From 676bd6d222509591614db840c2d36e94b2fdc3a2 Mon Sep 17 00:00:00 2001 From: PixelTux Date: Thu, 19 Feb 2026 15:52:46 +0100 Subject: [PATCH 01/40] extra_hosts mapping to have enables container-to-host connectivity --- docker-compose.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 32e8ee339..c268b01cd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,6 +10,9 @@ services: container_name: picoclaw-agent profiles: - agent + # Uncomment to access host network; leave commented unless needed. + #extra_hosts: + # - "host.docker.internal:host-gateway" volumes: - ./config/config.json:/home/picoclaw/.picoclaw/config.json:ro - picoclaw-workspace:/home/picoclaw/.picoclaw/workspace @@ -29,6 +32,9 @@ services: restart: unless-stopped profiles: - gateway + # Uncomment to access host network; leave commented unless needed. + #extra_hosts: + # - "host.docker.internal:host-gateway" volumes: # Configuration file - ./config/config.json:/home/picoclaw/.picoclaw/config.json:ro From c2ace2561cfae81839e977f90da7e29017d7b8e7 Mon Sep 17 00:00:00 2001 From: Artem Yadelskyi Date: Fri, 20 Feb 2026 22:09:36 +0200 Subject: [PATCH 02/40] feat(ci): Remove fmt from build step --- .github/workflows/build.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 499613625..9b89b69ae 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,7 @@ name: build on: push: - branches: ["main"] + branches: [ "main" ] jobs: build: @@ -16,10 +16,5 @@ jobs: with: go-version-file: go.mod - - name: fmt - run: | - make fmt - git diff --exit-code || (echo "::error::Code is not formatted. Run 'make fmt' and commit the changes." && exit 1) - - name: Build run: make build-all From 02b4d9fbe2dea85fb032ceba7d4c64f1499ba95a Mon Sep 17 00:00:00 2001 From: Artem Yadelskyi Date: Fri, 20 Feb 2026 22:35:16 +0200 Subject: [PATCH 03/40] feat(linter): Fix govet linter --- .github/workflows/pr.yml | 19 ------------------- .golangci.yaml | 1 - cmd/picoclaw/cmd_auth.go | 6 +++--- cmd/picoclaw/cmd_gateway.go | 3 ++- cmd/picoclaw/cmd_skills.go | 4 ++-- pkg/channels/telegram.go | 4 ++-- pkg/channels/wecom.go | 2 +- pkg/channels/wecom_app.go | 2 +- pkg/channels/wecom_app_test.go | 13 ------------- pkg/channels/wecom_test.go | 4 +--- pkg/migrate/migrate.go | 2 +- pkg/migrate/migrate_test.go | 10 +++++----- pkg/providers/codex_cli_credentials.go | 2 +- pkg/tools/edit.go | 2 +- pkg/tools/filesystem.go | 8 +++++--- pkg/tools/i2c_linux.go | 2 +- pkg/voice/transcriber.go | 6 +++--- 17 files changed, 29 insertions(+), 61 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 27782ced2..be1c10c52 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -24,25 +24,6 @@ jobs: with: version: v2.10.1 - # TODO: Remove once linter is properly configured - vet: - name: Vet - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Setup Go - uses: actions/setup-go@v6 - with: - go-version-file: go.mod - - - name: Run go generate - run: go generate ./... - - - name: Run go vet - run: go vet ./... - test: name: Tests runs-on: ubuntu-latest diff --git a/.golangci.yaml b/.golangci.yaml index 6dafb6b56..d45d69e67 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -47,7 +47,6 @@ linters: - godox - goprintffuncname - gosec - - govet - ineffassign - lll - maintidx diff --git a/cmd/picoclaw/cmd_auth.go b/cmd/picoclaw/cmd_auth.go index 5bed7f116..729c56177 100644 --- a/cmd/picoclaw/cmd_auth.go +++ b/cmd/picoclaw/cmd_auth.go @@ -114,7 +114,7 @@ func authLoginOpenAI(useDeviceCode bool) { os.Exit(1) } - if err := auth.SetCredential("openai", cred); err != nil { + if err = auth.SetCredential("openai", cred); err != nil { fmt.Printf("Failed to save credentials: %v\n", err) os.Exit(1) } @@ -188,7 +188,7 @@ func authLoginGoogleAntigravity() { fmt.Printf("Project: %s\n", projectID) } - if err := auth.SetCredential("google-antigravity", cred); err != nil { + if err = auth.SetCredential("google-antigravity", cred); err != nil { fmt.Printf("Failed to save credentials: %v\n", err) os.Exit(1) } @@ -265,7 +265,7 @@ func authLoginPasteToken(provider string) { os.Exit(1) } - if err := auth.SetCredential(provider, cred); err != nil { + if err = auth.SetCredential(provider, cred); err != nil { fmt.Printf("Failed to save credentials: %v\n", err) os.Exit(1) } diff --git a/cmd/picoclaw/cmd_gateway.go b/cmd/picoclaw/cmd_gateway.go index 00ec0f96d..9a3b6aa19 100644 --- a/cmd/picoclaw/cmd_gateway.go +++ b/cmd/picoclaw/cmd_gateway.go @@ -98,7 +98,8 @@ func gatewayCmd() { channel, chatID = "cli", "direct" } // Use ProcessHeartbeat - no session history, each heartbeat is independent - response, err := agentLoop.ProcessHeartbeat(context.Background(), prompt, channel, chatID) + var response string + response, err = agentLoop.ProcessHeartbeat(context.Background(), prompt, channel, chatID) if err != nil { return tools.ErrorResult(fmt.Sprintf("Heartbeat error: %v", err)) } diff --git a/cmd/picoclaw/cmd_skills.go b/cmd/picoclaw/cmd_skills.go index 2dd46756a..0814494b3 100644 --- a/cmd/picoclaw/cmd_skills.go +++ b/cmd/picoclaw/cmd_skills.go @@ -118,7 +118,7 @@ func skillsInstallFromRegistry(cfg *config.Config, registryName, slug string) { workspace := cfg.WorkspacePath() targetDir := filepath.Join(workspace, "skills", slug) - if _, err := os.Stat(targetDir); err == nil { + if _, err = os.Stat(targetDir); err == nil { fmt.Printf("\u2717 Skill '%s' already installed at %s\n", slug, targetDir) os.Exit(1) } @@ -126,7 +126,7 @@ func skillsInstallFromRegistry(cfg *config.Config, registryName, slug string) { ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() - if err := os.MkdirAll(filepath.Join(workspace, "skills"), 0o755); err != nil { + if err = os.MkdirAll(filepath.Join(workspace, "skills"), 0o755); err != nil { fmt.Printf("\u2717 Failed to create skills directory: %v\n", err) os.Exit(1) } diff --git a/pkg/channels/telegram.go b/pkg/channels/telegram.go index 2a971e147..a0a1c8d0a 100644 --- a/pkg/channels/telegram.go +++ b/pkg/channels/telegram.go @@ -267,10 +267,10 @@ func (c *TelegramChannel) handleMessage(ctx context.Context, message *telego.Mes transcribedText := "" if c.transcriber != nil && c.transcriber.IsAvailable() { - ctx, cancel := context.WithTimeout(ctx, 30*time.Second) + transcriberCtx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() - result, err := c.transcriber.Transcribe(ctx, voicePath) + result, err := c.transcriber.Transcribe(transcriberCtx, voicePath) if err != nil { logger.ErrorCF("telegram", "Voice transcription failed", map[string]any{ "error": err.Error(), diff --git a/pkg/channels/wecom.go b/pkg/channels/wecom.go index 07bd8488c..f8daf89de 100644 --- a/pkg/channels/wecom.go +++ b/pkg/channels/wecom.go @@ -272,7 +272,7 @@ func (c *WeComBotChannel) handleMessageCallback(ctx context.Context, w http.Resp AgentID string `xml:"AgentID"` } - if err := xml.Unmarshal(body, &encryptedMsg); err != nil { + if err = xml.Unmarshal(body, &encryptedMsg); err != nil { logger.ErrorCF("wecom", "Failed to parse XML", map[string]any{ "error": err.Error(), }) diff --git a/pkg/channels/wecom_app.go b/pkg/channels/wecom_app.go index 878504106..715c48707 100644 --- a/pkg/channels/wecom_app.go +++ b/pkg/channels/wecom_app.go @@ -348,7 +348,7 @@ func (c *WeComAppChannel) handleMessageCallback(ctx context.Context, w http.Resp AgentID string `xml:"AgentID"` } - if err := xml.Unmarshal(body, &encryptedMsg); err != nil { + if err = xml.Unmarshal(body, &encryptedMsg); err != nil { logger.ErrorCF("wecom_app", "Failed to parse XML", map[string]any{ "error": err.Error(), }) diff --git a/pkg/channels/wecom_app_test.go b/pkg/channels/wecom_app_test.go index 6778520f3..abf15c52b 100644 --- a/pkg/channels/wecom_app_test.go +++ b/pkg/channels/wecom_app_test.go @@ -852,19 +852,6 @@ func TestWeComAppMessageStructures(t *testing.T) { } }) - t.Run("WeComImageMessage structure", func(t *testing.T) { - msg := WeComImageMessage{ - ToUser: "user123", - MsgType: "image", - AgentID: 1000002, - } - msg.Image.MediaID = "media_123456" - - if msg.Image.MediaID != "media_123456" { - t.Errorf("Image.MediaID = %q, want %q", msg.Image.MediaID, "media_123456") - } - }) - t.Run("WeComAccessTokenResponse structure", func(t *testing.T) { jsonData := `{ "errcode": 0, diff --git a/pkg/channels/wecom_test.go b/pkg/channels/wecom_test.go index 53cde2693..8afa7e8c3 100644 --- a/pkg/channels/wecom_test.go +++ b/pkg/channels/wecom_test.go @@ -198,10 +198,8 @@ func TestWeComBotVerifySignature(t *testing.T) { Token: "", WebhookURL: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=test", } - base := NewBaseChannel("wecom", cfgEmpty, msgBus, cfgEmpty.AllowFrom) chEmpty := &WeComBotChannel{ - BaseChannel: base, - config: cfgEmpty, + config: cfgEmpty, } if !WeComVerifySignature(chEmpty.config.Token, "any_sig", "any_ts", "any_nonce", "any_msg") { diff --git a/pkg/migrate/migrate.go b/pkg/migrate/migrate.go index ab2635890..cfa82b7d7 100644 --- a/pkg/migrate/migrate.go +++ b/pkg/migrate/migrate.go @@ -67,7 +67,7 @@ func Run(opts Options) (*Result, error) { return nil, err } - if _, err := os.Stat(openclawHome); os.IsNotExist(err) { + if _, err = os.Stat(openclawHome); os.IsNotExist(err) { return nil, fmt.Errorf("OpenClaw installation not found at %s", openclawHome) } diff --git a/pkg/migrate/migrate_test.go b/pkg/migrate/migrate_test.go index ccc00f72c..b6b3d70aa 100644 --- a/pkg/migrate/migrate_test.go +++ b/pkg/migrate/migrate_test.go @@ -58,10 +58,10 @@ func TestConvertKeysToSnake(t *testing.T) { t.Fatal("expected map[string]interface{}") } - if _, ok := m["api_key"]; !ok { + if _, ok = m["api_key"]; !ok { t.Error("expected key 'api_key' after conversion") } - if _, ok := m["api_base"]; !ok { + if _, ok = m["api_base"]; !ok { t.Error("expected key 'api_base' after conversion") } @@ -69,10 +69,10 @@ func TestConvertKeysToSnake(t *testing.T) { if !ok { t.Fatal("expected nested map") } - if _, ok := nested["max_tokens"]; !ok { + if _, ok = nested["max_tokens"]; !ok { t.Error("expected key 'max_tokens' in nested map") } - if _, ok := nested["allow_from"]; !ok { + if _, ok = nested["allow_from"]; !ok { t.Error("expected key 'allow_from' in nested map") } @@ -108,7 +108,7 @@ func TestLoadOpenClawConfig(t *testing.T) { if err != nil { t.Fatal(err) } - if err := os.WriteFile(configPath, data, 0o644); err != nil { + if err = os.WriteFile(configPath, data, 0o644); err != nil { t.Fatal(err) } diff --git a/pkg/providers/codex_cli_credentials.go b/pkg/providers/codex_cli_credentials.go index 46ba24b12..40f3ee2a1 100644 --- a/pkg/providers/codex_cli_credentials.go +++ b/pkg/providers/codex_cli_credentials.go @@ -31,7 +31,7 @@ func ReadCodexCliCredentials() (accessToken, accountID string, expiresAt time.Ti } var auth CodexCliAuth - if err := json.Unmarshal(data, &auth); err != nil { + if err = json.Unmarshal(data, &auth); err != nil { return "", "", time.Time{}, fmt.Errorf("parsing %s: %w", authPath, err) } diff --git a/pkg/tools/edit.go b/pkg/tools/edit.go index 39d2642d4..c28ca6ca2 100644 --- a/pkg/tools/edit.go +++ b/pkg/tools/edit.go @@ -72,7 +72,7 @@ func (t *EditFileTool) Execute(ctx context.Context, args map[string]any) *ToolRe return ErrorResult(err.Error()) } - if _, err := os.Stat(resolvedPath); os.IsNotExist(err) { + if _, err = os.Stat(resolvedPath); os.IsNotExist(err) { return ErrorResult(fmt.Sprintf("file not found: %s", path)) } diff --git a/pkg/tools/filesystem.go b/pkg/tools/filesystem.go index dd996bc0d..1bf50906e 100644 --- a/pkg/tools/filesystem.go +++ b/pkg/tools/filesystem.go @@ -34,17 +34,19 @@ func validatePath(path, workspace string, restrict bool) (string, error) { return "", fmt.Errorf("access denied: path is outside the workspace") } + var resolved string workspaceReal := absWorkspace - if resolved, err := filepath.EvalSymlinks(absWorkspace); err == nil { + if resolved, err = filepath.EvalSymlinks(absWorkspace); err == nil { workspaceReal = resolved } - if resolved, err := filepath.EvalSymlinks(absPath); err == nil { + if resolved, err = filepath.EvalSymlinks(absPath); err == nil { if !isWithinWorkspace(resolved, workspaceReal) { return "", fmt.Errorf("access denied: symlink resolves outside workspace") } } else if os.IsNotExist(err) { - if parentResolved, err := resolveExistingAncestor(filepath.Dir(absPath)); err == nil { + var parentResolved string + if parentResolved, err = resolveExistingAncestor(filepath.Dir(absPath)); err == nil { if !isWithinWorkspace(parentResolved, workspaceReal) { return "", fmt.Errorf("access denied: symlink resolves outside workspace") } diff --git a/pkg/tools/i2c_linux.go b/pkg/tools/i2c_linux.go index 2a0626340..4eaaf8f09 100644 --- a/pkg/tools/i2c_linux.go +++ b/pkg/tools/i2c_linux.go @@ -182,7 +182,7 @@ func (t *I2CTool) readDevice(args map[string]any) *ToolResult { if reg < 0 || reg > 255 { return ErrorResult("register must be between 0x00 and 0xFF") } - _, err := syscall.Write(fd, []byte{byte(reg)}) + _, err = syscall.Write(fd, []byte{byte(reg)}) if err != nil { return ErrorResult(fmt.Sprintf("failed to write register 0x%02x: %v", reg, err)) } diff --git a/pkg/voice/transcriber.go b/pkg/voice/transcriber.go index ad8767d40..f973e77fe 100644 --- a/pkg/voice/transcriber.go +++ b/pkg/voice/transcriber.go @@ -79,17 +79,17 @@ func (t *GroqTranscriber) Transcribe(ctx context.Context, audioFilePath string) logger.DebugCF("voice", "File copied to request", map[string]any{"bytes_copied": copied}) - if err := writer.WriteField("model", "whisper-large-v3"); err != nil { + if err = writer.WriteField("model", "whisper-large-v3"); err != nil { logger.ErrorCF("voice", "Failed to write model field", map[string]any{"error": err}) return nil, fmt.Errorf("failed to write model field: %w", err) } - if err := writer.WriteField("response_format", "json"); err != nil { + if err = writer.WriteField("response_format", "json"); err != nil { logger.ErrorCF("voice", "Failed to write response_format field", map[string]any{"error": err}) return nil, fmt.Errorf("failed to write response_format field: %w", err) } - if err := writer.Close(); err != nil { + if err = writer.Close(); err != nil { logger.ErrorCF("voice", "Failed to close multipart writer", map[string]any{"error": err}) return nil, fmt.Errorf("failed to close multipart writer: %w", err) } From 244eb0b47d0f694df4bdc96c316b23698eab7407 Mon Sep 17 00:00:00 2001 From: Goksu Ceylan <79890826+GoCeylan@users.noreply.github.com> Date: Fri, 20 Feb 2026 19:15:46 -0500 Subject: [PATCH 04/40] fix (security): ExecTool `working_dir` sandbox escape (#478) * fix (security) Shell working_dir bypass * Feedback from @mengzhuo & Discord - reuse internal security package to validate path - add tests for workspace escape --- pkg/tools/shell.go | 10 ++++++- pkg/tools/shell_test.go | 60 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/pkg/tools/shell.go b/pkg/tools/shell.go index d2adb6468..a1ee0b6e1 100644 --- a/pkg/tools/shell.go +++ b/pkg/tools/shell.go @@ -144,7 +144,15 @@ func (t *ExecTool) Execute(ctx context.Context, args map[string]any) *ToolResult cwd := t.workingDir if wd, ok := args["working_dir"].(string); ok && wd != "" { - cwd = wd + if t.restrictToWorkspace && t.workingDir != "" { + resolvedWD, err := validatePath(wd, t.workingDir, true) + if err != nil { + return ErrorResult("Command blocked by safety guard (" + err.Error() + ")") + } + cwd = resolvedWD + } else { + cwd = wd + } } if cwd == "" { diff --git a/pkg/tools/shell_test.go b/pkg/tools/shell_test.go index f85b5a008..60f2b7b91 100644 --- a/pkg/tools/shell_test.go +++ b/pkg/tools/shell_test.go @@ -186,6 +186,66 @@ func TestShellTool_OutputTruncation(t *testing.T) { } } +// TestShellTool_WorkingDir_OutsideWorkspace verifies that working_dir cannot escape the workspace directly +func TestShellTool_WorkingDir_OutsideWorkspace(t *testing.T) { + root := t.TempDir() + workspace := filepath.Join(root, "workspace") + outsideDir := filepath.Join(root, "outside") + if err := os.MkdirAll(workspace, 0755); err != nil { + t.Fatalf("failed to create workspace: %v", err) + } + if err := os.MkdirAll(outsideDir, 0755); err != nil { + t.Fatalf("failed to create outside dir: %v", err) + } + + tool := NewExecTool(workspace, true) + result := tool.Execute(context.Background(), map[string]interface{}{ + "command": "pwd", + "working_dir": outsideDir, + }) + + if !result.IsError { + t.Fatalf("expected working_dir outside workspace to be blocked, got output: %s", result.ForLLM) + } + if !strings.Contains(result.ForLLM, "blocked") { + t.Errorf("expected 'blocked' in error, got: %s", result.ForLLM) + } +} + +// TestShellTool_WorkingDir_SymlinkEscape verifies that a symlink inside the workspace +// pointing outside cannot be used as working_dir to escape the sandbox. +func TestShellTool_WorkingDir_SymlinkEscape(t *testing.T) { + root := t.TempDir() + workspace := filepath.Join(root, "workspace") + secretDir := filepath.Join(root, "secret") + if err := os.MkdirAll(workspace, 0755); err != nil { + t.Fatalf("failed to create workspace: %v", err) + } + if err := os.MkdirAll(secretDir, 0755); err != nil { + t.Fatalf("failed to create secret dir: %v", err) + } + os.WriteFile(filepath.Join(secretDir, "secret.txt"), []byte("top secret"), 0644) + + // symlink lives inside the workspace but resolves to secretDir outside it + link := filepath.Join(workspace, "escape") + if err := os.Symlink(secretDir, link); err != nil { + t.Skipf("symlinks not supported in this environment: %v", err) + } + + tool := NewExecTool(workspace, true) + result := tool.Execute(context.Background(), map[string]interface{}{ + "command": "cat secret.txt", + "working_dir": link, + }) + + if !result.IsError { + t.Fatalf("expected symlink working_dir escape to be blocked, got output: %s", result.ForLLM) + } + if !strings.Contains(result.ForLLM, "blocked") { + t.Errorf("expected 'blocked' in error, got: %s", result.ForLLM) + } +} + // TestShellTool_RestrictToWorkspace verifies workspace restriction func TestShellTool_RestrictToWorkspace(t *testing.T) { tmpDir := t.TempDir() From 80c8b5753338dc75286d93d8d62fa01654b1a2f0 Mon Sep 17 00:00:00 2001 From: Luke Milby Date: Fri, 20 Feb 2026 19:21:38 -0500 Subject: [PATCH 05/40] Fix Memory Write (#557) * fix issue where memory will only trigger when asked to remember something * updated prompt for memory usage --- pkg/agent/context.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/agent/context.go b/pkg/agent/context.go index e989ffaaf..a9db5afdd 100644 --- a/pkg/agent/context.go +++ b/pkg/agent/context.go @@ -80,7 +80,7 @@ Your workspace is at: %s 2. **Be helpful and accurate** - When using tools, briefly explain what you're doing. -3. **Memory** - When remembering something, write to %s/memory/MEMORY.md`, +3. **Memory** - When interacting with me if something seems memorable, update %s/memory/MEMORY.md`, now, runtime, workspacePath, workspacePath, workspacePath, workspacePath, toolsSection, workspacePath) } From 3df7f705408d5767e43a22975fd2d093f33b7705 Mon Sep 17 00:00:00 2001 From: Hoshina Date: Sat, 21 Feb 2026 16:05:39 +0800 Subject: [PATCH 06/40] fix: golangci-lint fmt --- pkg/tools/shell_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/tools/shell_test.go b/pkg/tools/shell_test.go index 60f2b7b91..d0a300c6c 100644 --- a/pkg/tools/shell_test.go +++ b/pkg/tools/shell_test.go @@ -191,10 +191,10 @@ func TestShellTool_WorkingDir_OutsideWorkspace(t *testing.T) { root := t.TempDir() workspace := filepath.Join(root, "workspace") outsideDir := filepath.Join(root, "outside") - if err := os.MkdirAll(workspace, 0755); err != nil { + if err := os.MkdirAll(workspace, 0o755); err != nil { t.Fatalf("failed to create workspace: %v", err) } - if err := os.MkdirAll(outsideDir, 0755); err != nil { + if err := os.MkdirAll(outsideDir, 0o755); err != nil { t.Fatalf("failed to create outside dir: %v", err) } @@ -218,13 +218,13 @@ func TestShellTool_WorkingDir_SymlinkEscape(t *testing.T) { root := t.TempDir() workspace := filepath.Join(root, "workspace") secretDir := filepath.Join(root, "secret") - if err := os.MkdirAll(workspace, 0755); err != nil { + if err := os.MkdirAll(workspace, 0o755); err != nil { t.Fatalf("failed to create workspace: %v", err) } - if err := os.MkdirAll(secretDir, 0755); err != nil { + if err := os.MkdirAll(secretDir, 0o755); err != nil { t.Fatalf("failed to create secret dir: %v", err) } - os.WriteFile(filepath.Join(secretDir, "secret.txt"), []byte("top secret"), 0644) + os.WriteFile(filepath.Join(secretDir, "secret.txt"), []byte("top secret"), 0o644) // symlink lives inside the workspace but resolves to secretDir outside it link := filepath.Join(workspace, "escape") From 00666022949fb993f9b07ae8c2bb844fde977b23 Mon Sep 17 00:00:00 2001 From: Hoshina Date: Sat, 21 Feb 2026 16:20:15 +0800 Subject: [PATCH 07/40] fix: golangci-lint run --fix --- pkg/tools/shell_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/tools/shell_test.go b/pkg/tools/shell_test.go index d0a300c6c..6d35815e8 100644 --- a/pkg/tools/shell_test.go +++ b/pkg/tools/shell_test.go @@ -199,7 +199,7 @@ func TestShellTool_WorkingDir_OutsideWorkspace(t *testing.T) { } tool := NewExecTool(workspace, true) - result := tool.Execute(context.Background(), map[string]interface{}{ + result := tool.Execute(context.Background(), map[string]any{ "command": "pwd", "working_dir": outsideDir, }) @@ -233,7 +233,7 @@ func TestShellTool_WorkingDir_SymlinkEscape(t *testing.T) { } tool := NewExecTool(workspace, true) - result := tool.Execute(context.Background(), map[string]interface{}{ + result := tool.Execute(context.Background(), map[string]any{ "command": "cat secret.txt", "working_dir": link, }) From 023b245a285780edfcfbe90ae81b4c9cd7e7913d Mon Sep 17 00:00:00 2001 From: Hoshina Date: Sat, 21 Feb 2026 15:33:35 +0800 Subject: [PATCH 08/40] docs: add Chinese channel documentation --- README.zh.md | 458 ++++++--------------- docs/channels/dingtalk/README.zh.md | 33 ++ docs/channels/discord/README.zh.md | 35 ++ docs/channels/feishu/README.zh.md | 37 ++ docs/channels/line/README.zh.md | 41 ++ docs/channels/maixcam/README.zh.md | 31 ++ docs/channels/onebot/README.zh.md | 31 ++ docs/channels/qq/README.zh.md | 32 ++ docs/channels/slack/README.zh.md | 33 ++ docs/channels/telegram/README.zh.md | 33 ++ docs/channels/wecom/wecom_app/README.zh.md | 47 +++ docs/channels/wecom/wecom_bot/README.zh.md | 41 ++ 12 files changed, 510 insertions(+), 342 deletions(-) create mode 100644 docs/channels/dingtalk/README.zh.md create mode 100644 docs/channels/discord/README.zh.md create mode 100644 docs/channels/feishu/README.zh.md create mode 100644 docs/channels/line/README.zh.md create mode 100644 docs/channels/maixcam/README.zh.md create mode 100644 docs/channels/onebot/README.zh.md create mode 100644 docs/channels/qq/README.zh.md create mode 100644 docs/channels/slack/README.zh.md create mode 100644 docs/channels/telegram/README.zh.md create mode 100644 docs/channels/wecom/wecom_app/README.zh.md create mode 100644 docs/channels/wecom/wecom_bot/README.zh.md diff --git a/README.zh.md b/README.zh.md index ab896b6c0..4d739c5eb 100644 --- a/README.zh.md +++ b/README.zh.md @@ -14,7 +14,8 @@ Twitter

- **中文** | [日本語](README.ja.md) | [Português](README.pt-br.md) | [Tiếng Việt](README.vi.md) | [Français](README.fr.md) | [English](README.md) +**中文** | [日本語](README.ja.md) | [Português](README.pt-br.md) | [Tiếng Việt](README.vi.md) | [Français](README.fr.md) | [English](README.md) + --- @@ -42,14 +43,15 @@ > [!CAUTION] > **🚨 SECURITY & OFFICIAL CHANNELS / 安全声明** -> * **无加密货币 (NO CRYPTO):** PicoClaw **没有** 发行任何官方代币、Token 或虚拟货币。所有在 `pump.fun` 或其他交易平台上的相关声称均为 **诈骗**。 -> * **官方域名:** 唯一的官方网站是 **[picoclaw.io](https://picoclaw.io)**,公司官网是 **[sipeed.com](https://sipeed.com)**。 -> * **警惕:** 许多 `.ai/.org/.com/.net/...` 后缀的域名被第三方抢注,请勿轻信。 -> * **注意:** picoclaw正在初期的快速功能开发阶段,可能有尚未修复的网络安全问题,在1.0正式版发布前,请不要将其部署到生产环境中 -> * **注意:** picoclaw最近合并了大量PRs,近期版本可能内存占用较大(10~20MB),我们将在功能较为收敛后进行资源占用优化. - +> +> - **无加密货币 (NO CRYPTO):** PicoClaw **没有** 发行任何官方代币、Token 或虚拟货币。所有在 `pump.fun` 或其他交易平台上的相关声称均为 **诈骗**。 +> - **官方域名:** 唯一的官方网站是 **[picoclaw.io](https://picoclaw.io)**,公司官网是 **[sipeed.com](https://sipeed.com)**。 +> - **警惕:** 许多 `.ai/.org/.com/.net/...` 后缀的域名被第三方抢注,请勿轻信。 +> - **注意:** picoclaw正在初期的快速功能开发阶段,可能有尚未修复的网络安全问题,在1.0正式版发布前,请不要将其部署到生产环境中 +> - **注意:** picoclaw最近合并了大量PRs,近期版本可能内存占用较大(10~20MB),我们将在功能较为收敛后进行资源占用优化. ## 📢 新闻 (News) + 2026-02-16 🎉 PicoClaw 在一周内突破了12K star! 感谢大家的关注!PicoClaw 的成长速度超乎我们预期. 由于PR数量的快速膨胀,我们亟需社区开发者参与维护. 我们需要的志愿者角色和roadmap已经发布到了[这里](docs/picoclaw_community_roadmap_260216.md), 期待你的参与! 2026-02-13 🎉 **PicoClaw 在 4 天内突破 5000 Stars!** 感谢社区的支持!由于正值中国春节假期,PR 和 Issue 涌入较多,我们正在利用这段时间敲定 **项目路线图 (Roadmap)** 并组建 **开发者群组**,以便加速 PicoClaw 的开发。 @@ -69,12 +71,12 @@ 🤖 **AI 自举**: 纯 Go 语言原生实现 — 95% 的核心代码由 Agent 生成,并经由“人机回环 (Human-in-the-loop)”微调。 -| | OpenClaw | NanoBot | **PicoClaw** | -| --- | --- | --- | --- | -| **语言** | TypeScript | Python | **Go** | -| **RAM** | >1GB | >100MB | **< 10MB** | -| **启动时间**
(0.8GHz core) | >500s | >30s | **<1s** | -| **成本** | Mac Mini $599 | 大多数 Linux 开发板 ~$50 | **任意 Linux 开发板**
**低至 $10** | +| | OpenClaw | NanoBot | **PicoClaw** | +| ------------------------------ | ------------- | ------------------------ | -------------------------------------- | +| **语言** | TypeScript | Python | **Go** | +| **RAM** | >1GB | >100MB | **< 10MB** | +| **启动时间**
(0.8GHz core) | >500s | >30s | **<1s** | +| **成本** | Mac Mini $599 | 大多数 Linux 开发板 ~$50 | **任意 Linux 开发板**
**低至 $10** | PicoClaw @@ -101,9 +103,12 @@ ### 📱 在手机上轻松运行 + picoclaw 可以将你10年前的老旧手机废物利用,变身成为你的AI助理!快速指南: + 1. 先去应用商店下载安装Termux 2. 打开后执行指令 + ```bash # 注意: 下面的v0.1.1 可以换为你实际看到的最新版本 wget https://github.com/sipeed/picoclaw/releases/download/v0.1.1/picoclaw-linux-arm64 @@ -111,19 +116,17 @@ chmod +x picoclaw-linux-arm64 pkg install proot termux-chroot ./picoclaw-linux-arm64 onboard ``` -然后跟随下面的“快速开始”章节继续配置picoclaw即可使用! + +然后跟随下面的“快速开始”章节继续配置picoclaw即可使用! PicoClaw - - - ### 🐜 创新的低占用部署 PicoClaw 几乎可以部署在任何 Linux 设备上! -* $9.9 [LicheeRV-Nano](https://www.aliexpress.com/item/1005006519668532.html) E(网口) 或 W(WiFi6) 版本,用于极简家庭助手。 -* $30~50 [NanoKVM](https://www.aliexpress.com/item/1005007369816019.html),或 $100 [NanoKVM-Pro](https://www.aliexpress.com/item/1005010048471263.html),用于自动化服务器运维。 -* $50 [MaixCAM](https://www.aliexpress.com/item/1005008053333693.html) 或 $100 [MaixCAM2](https://www.kickstarter.com/projects/zepan/maixcam2-build-your-next-gen-4k-ai-camera),用于智能监控。 +- $9.9 [LicheeRV-Nano](https://www.aliexpress.com/item/1005006519668532.html) E(网口) 或 W(WiFi6) 版本,用于极简家庭助手。 +- $30~50 [NanoKVM](https://www.aliexpress.com/item/1005007369816019.html),或 $100 [NanoKVM-Pro](https://www.aliexpress.com/item/1005010048471263.html),用于自动化服务器运维。 +- $50 [MaixCAM](https://www.aliexpress.com/item/1005008053333693.html) 或 $100 [MaixCAM2](https://www.kickstarter.com/projects/zepan/maixcam2-build-your-next-gen-4k-ai-camera),用于智能监控。 [https://private-user-images.githubusercontent.com/83055338/547056448-e7b031ff-d6f5-4468-bcca-5726b6fecb5c.mp4](https://private-user-images.githubusercontent.com/83055338/547056448-e7b031ff-d6f5-4468-bcca-5726b6fecb5c.mp4) @@ -253,15 +256,14 @@ picoclaw onboard } } } - ``` > **新功能**: `model_list` 配置格式支持零代码添加 provider。详见[模型配置](#模型配置-model_list)章节。 **3. 获取 API Key** -* **LLM 提供商**: [OpenRouter](https://openrouter.ai/keys) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) · [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com/api-keys) -* **网络搜索** (可选): [Brave Search](https://brave.com/search/api) - 提供免费层级 (2000 请求/月) +- **LLM 提供商**: [OpenRouter](https://openrouter.ai/keys) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) · [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com/api-keys) +- **网络搜索** (可选): [Brave Search](https://brave.com/search/api) - 提供免费层级 (2000 请求/月) > **注意**: 完整的配置模板请参考 `config.example.json`。 @@ -278,260 +280,28 @@ picoclaw agent -m "2+2 等于几?" ## 💬 聊天应用集成 (Chat Apps) -通过 Telegram, Discord, 钉钉或企业微信与您的 PicoClaw 对话。 - -| 渠道 | 设置难度 | -| --- | --- | -| **Telegram** | 简单 (仅需 token) | -| **Discord** | 简单 (bot token + intents) | -| **QQ** | 简单 (AppID + AppSecret) | -| **钉钉 (DingTalk)** | 中等 (应用凭证) | -| **企业微信 (WeCom)** | 中等 (企业ID + Webhook配置) | - -
-Telegram (推荐) - -**1. 创建机器人** - -* 打开 Telegram,搜索 `@BotFather` -* 发送 `/newbot`,按照提示操作 -* 复制 token - -**2. 配置** - -```json -{ - "channels": { - "telegram": { - "enabled": true, - "token": "YOUR_BOT_TOKEN", - "allow_from": ["YOUR_USER_ID"] - } - } -} - -``` - -> 从 Telegram 上的 `@userinfobot` 获取您的用户 ID。 - -**3. 运行** - -```bash -picoclaw gateway - -``` - -
- -
-Discord - -**1. 创建机器人** - -* 前往 [https://discord.com/developers/applications](https://discord.com/developers/applications) -* Create an application → Bot → Add Bot -* 复制 bot token - -**2. 开启 Intents** - -* 在 Bot 设置中,开启 **MESSAGE CONTENT INTENT** -* (可选) 如果计划基于成员数据使用白名单,开启 **SERVER MEMBERS INTENT** - -**3. 获取您的 User ID** - -* Discord 设置 → Advanced → 开启 **Developer Mode** -* 右键点击您的头像 → **Copy User ID** - -**4. 配置** - -```json -{ - "channels": { - "discord": { - "enabled": true, - "token": "YOUR_BOT_TOKEN", - "allow_from": ["YOUR_USER_ID"], - "mention_only": false - } - } -} - -``` - -**5. 邀请机器人** - -* OAuth2 → URL Generator -* Scopes: `bot` -* Bot Permissions: `Send Messages`, `Read Message History` -* 打开生成的邀请 URL,将机器人添加到您的服务器 - -**6. 运行** - -```bash -picoclaw gateway - -``` - -
- -
-QQ - -**1. 创建机器人** - -* 前往 [QQ 开放平台](https://q.qq.com/#) -* 创建应用 → 获取 **AppID** 和 **AppSecret** - -**2. 配置** - -```json -{ - "channels": { - "qq": { - "enabled": true, - "app_id": "YOUR_APP_ID", - "app_secret": "YOUR_APP_SECRET", - "allow_from": [] - } - } -} - -``` - -> 将 `allow_from` 设为空以允许所有用户,或指定 QQ 号以限制访问。 - -**3. 运行** - -```bash -picoclaw gateway - -``` - -
- -
-钉钉 (DingTalk) - -**1. 创建机器人** - -* 前往 [开放平台](https://open.dingtalk.com/) -* 创建内部应用 -* 复制 Client ID 和 Client Secret - -**2. 配置** - -```json -{ - "channels": { - "dingtalk": { - "enabled": true, - "client_id": "YOUR_CLIENT_ID", - "client_secret": "YOUR_CLIENT_SECRET", - "allow_from": [] - } - } -} - -``` - -> 将 `allow_from` 设为空以允许所有用户,或指定 ID 以限制访问。 - -**3. 运行** - -```bash -picoclaw gateway - -``` - -
- -
-企业微信 (WeCom) - -PicoClaw 支持两种企业微信集成方式: - -**选项1: 智能机器人 (WeCom Bot)** - 设置更简单,支持群聊 -**选项2: 自建应用 (WeCom App)** - 功能更丰富,支持主动推送消息 - -详见 [企业微信自建应用配置指南](docs/wecom-app-configuration.md)。 - -**快速设置 - 智能机器人:** - -**1. 创建机器人** - -* 前往企业微信管理后台 → 群聊 → 添加群机器人 -* 复制 Webhook URL (格式: `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx`) - -**2. 配置** - -```json -{ - "channels": { - "wecom": { - "enabled": true, - "token": "YOUR_TOKEN", - "encoding_aes_key": "YOUR_ENCODING_AES_KEY", - "webhook_url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY", - "webhook_host": "0.0.0.0", - "webhook_port": 18793, - "webhook_path": "/webhook/wecom", - "allow_from": [] - } - } -} -``` - -**快速设置 - 自建应用:** - -**1. 创建应用** - -* 前往企业微信管理后台 → 应用管理 → 创建应用 -* 复制 **AgentId** 和 **Secret** -* 前往"我的企业"页面,复制 **CorpID** - -**2. 配置接收消息** - -* 在应用详情页,点击"接收消息" → "设置API" -* 设置 URL 为 `http://your-server:18792/webhook/wecom-app` -* 生成 **Token** 和 **EncodingAESKey** - -**3. 配置** - -```json -{ - "channels": { - "wecom_app": { - "enabled": true, - "corp_id": "wwxxxxxxxxxxxxxxxx", - "corp_secret": "YOUR_CORP_SECRET", - "agent_id": 1000002, - "token": "YOUR_TOKEN", - "encoding_aes_key": "YOUR_ENCODING_AES_KEY", - "webhook_host": "0.0.0.0", - "webhook_port": 18792, - "webhook_path": "/webhook/wecom-app", - "allow_from": [] - } - } -} -``` - -**4. 运行** - -```bash -picoclaw gateway - -``` - -> **注意**: 自建应用需要开放 18792 端口用于接收 Webhook 回调。生产环境建议使用反向代理配置 HTTPS。 - -
+PicoClaw 支持多种聊天平台,使您的 Agent 能够连接到任何地方。 + +### 核心渠道 + +| 渠道 | 设置难度 | 特性说明 | 文档链接 | +| -------------------- | ----------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------- | +| **Telegram** | ⭐ 简单 | 推荐,支持语音转文字,长轮询无需公网 | [查看文档](docs/channels/telegram/README.zh.md) | +| **Discord** | ⭐ 简单 | Socket Mode,支持群组/私信,Bot 生态成熟 | [查看文档](docs/channels/discord/README.zh.md) | +| **Slack** | ⭐ 简单 | **Socket Mode** (无需公网 IP),企业级支持 | [查看文档](docs/channels/slack/README.zh.md) | +| **QQ** | ⭐⭐ 中等 | 官方机器人 API,适合国内社群 | [查看文档](docs/channels/qq/README.zh.md) | +| **钉钉 (DingTalk)** | ⭐⭐ 中等 | Stream 模式无需公网,企业办公首选 | [查看文档](docs/channels/dingtalk/README.zh.md) | +| **企业微信 (WeCom)** | ⭐⭐⭐ 较难 | 支持群机器人(Webhook)和自建应用(API) | [Bot 文档](docs/channels/wecom/wecom_bot/README.zh.md) / [App 文档](docs/channels/wecom/wecom_app/README.zh.md) | +| **飞书 (Feishu)** | ⭐⭐⭐ 较难 | 企业级协作,功能丰富 | [查看文档](docs/channels/feishu/README.zh.md) | +| **Line** | ⭐⭐⭐ 较难 | 需要 HTTPS Webhook | [查看文档](docs/channels/line/README.zh.md) | +| **OneBot** | ⭐⭐ 中等 | 兼容 NapCat/Go-CQHTTP,社区生态丰富 | [查看文档](docs/channels/onebot/README.zh.md) | +| **MaixCam** | ⭐ 简单 | 专为 AI 摄像头设计的硬件集成通道 | [查看文档](docs/channels/maixcam/README.zh.md) | ## ClawdChat 加入 Agent 社交网络 只需通过 CLI 或任何集成的聊天应用发送一条消息,即可将 PicoClaw 连接到 Agent 社交网络。 -**阅读 `https://clawdchat.ai/skill.md` 并按照说明加入 [ClawdChat.ai](https://clawdchat.ai) +\*\*阅读 `https://clawdchat.ai/skill.md` 并按照说明加入 [ClawdChat.ai](https://clawdchat.ai) ## ⚙️ 配置详解 @@ -567,7 +337,6 @@ PicoClaw 可以自动执行周期性任务。在工作区创建 `HEARTBEAT.md` - Check my email for important messages - Review my calendar for upcoming events - Check the weather forecast - ``` Agent 将每隔 30 分钟(可配置)读取此文件,并使用可用工具执行任务。 @@ -580,22 +349,23 @@ Agent 将每隔 30 分钟(可配置)读取此文件,并使用可用工具 # Periodic Tasks ## Quick Tasks (respond directly) + - Report current time ## Long Tasks (use spawn for async) + - Search the web for AI news and summarize - Check email and report important messages - ``` **关键行为:** -| 特性 | 描述 | -| --- | --- | -| **spawn** | 创建异步子 Agent,不阻塞主心跳进程 | -| **独立上下文** | 子 Agent 拥有独立上下文,无会话历史 | +| 特性 | 描述 | +| ---------------- | ---------------------------------------- | +| **spawn** | 创建异步子 Agent,不阻塞主心跳进程 | +| **独立上下文** | 子 Agent 拥有独立上下文,无会话历史 | | **message tool** | 子 Agent 通过 message 工具直接与用户通信 | -| **非阻塞** | spawn 后,心跳继续处理下一个任务 | +| **非阻塞** | spawn 后,心跳继续处理下一个任务 | #### 子 Agent 通信原理 @@ -625,35 +395,34 @@ Agent 读取 HEARTBEAT.md "interval": 30 } } - ``` -| 选项 | 默认值 | 描述 | -| --- | --- | --- | -| `enabled` | `true` | 启用/禁用心跳 | -| `interval` | `30` | 检查间隔,单位分钟 (最小: 5) | +| 选项 | 默认值 | 描述 | +| ---------- | ------ | ---------------------------- | +| `enabled` | `true` | 启用/禁用心跳 | +| `interval` | `30` | 检查间隔,单位分钟 (最小: 5) | **环境变量:** -* `PICOCLAW_HEARTBEAT_ENABLED=false` 禁用 -* `PICOCLAW_HEARTBEAT_INTERVAL=60` 更改间隔 +- `PICOCLAW_HEARTBEAT_ENABLED=false` 禁用 +- `PICOCLAW_HEARTBEAT_INTERVAL=60` 更改间隔 ### 提供商 (Providers) > [!NOTE] > Groq 通过 Whisper 提供免费的语音转录。如果配置了 Groq,Telegram 语音消息将被自动转录为文字。 -| 提供商 | 用途 | 获取 API Key | -| --- | --- | --- | -| `gemini` | LLM (Gemini 直连) | [aistudio.google.com](https://aistudio.google.com) | -| `zhipu` | LLM (智谱直连) | [bigmodel.cn](bigmodel.cn) | -| `openrouter(待测试)` | LLM (推荐,可访问所有模型) | [openrouter.ai](https://openrouter.ai) | -| `anthropic(待测试)` | LLM (Claude 直连) | [console.anthropic.com](https://console.anthropic.com) | -| `openai(待测试)` | LLM (GPT 直连) | [platform.openai.com](https://platform.openai.com) | -| `deepseek(待测试)` | LLM (DeepSeek 直连) | [platform.deepseek.com](https://platform.deepseek.com) | -| `qwen` | LLM (通义千问) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) | -| `groq` | LLM + **语音转录** (Whisper) | [console.groq.com](https://console.groq.com) | -| `cerebras` | LLM (Cerebras 直连) | [cerebras.ai](https://cerebras.ai) | +| 提供商 | 用途 | 获取 API Key | +| -------------------- | ---------------------------- | -------------------------------------------------------------------- | +| `gemini` | LLM (Gemini 直连) | [aistudio.google.com](https://aistudio.google.com) | +| `zhipu` | LLM (智谱直连) | [bigmodel.cn](bigmodel.cn) | +| `openrouter(待测试)` | LLM (推荐,可访问所有模型) | [openrouter.ai](https://openrouter.ai) | +| `anthropic(待测试)` | LLM (Claude 直连) | [console.anthropic.com](https://console.anthropic.com) | +| `openai(待测试)` | LLM (GPT 直连) | [platform.openai.com](https://platform.openai.com) | +| `deepseek(待测试)` | LLM (DeepSeek 直连) | [platform.deepseek.com](https://platform.deepseek.com) | +| `qwen` | LLM (通义千问) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) | +| `groq` | LLM + **语音转录** (Whisper) | [console.groq.com](https://console.groq.com) | +| `cerebras` | LLM (Cerebras 直连) | [cerebras.ai](https://cerebras.ai) | ### 模型配置 (model_list) @@ -668,25 +437,25 @@ Agent 读取 HEARTBEAT.md #### 📋 所有支持的厂商 -| 厂商 | `model` 前缀 | 默认 API Base | 协议 | 获取 API Key | -|------|-------------|---------------|------|--------------| -| **OpenAI** | `openai/` | `https://api.openai.com/v1` | OpenAI | [获取密钥](https://platform.openai.com) | -| **Anthropic** | `anthropic/` | `https://api.anthropic.com/v1` | Anthropic | [获取密钥](https://console.anthropic.com) | -| **智谱 AI (GLM)** | `zhipu/` | `https://open.bigmodel.cn/api/paas/v4` | OpenAI | [获取密钥](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) | -| **DeepSeek** | `deepseek/` | `https://api.deepseek.com/v1` | OpenAI | [获取密钥](https://platform.deepseek.com) | -| **Google Gemini** | `gemini/` | `https://generativelanguage.googleapis.com/v1beta` | OpenAI | [获取密钥](https://aistudio.google.com/api-keys) | -| **Groq** | `groq/` | `https://api.groq.com/openai/v1` | OpenAI | [获取密钥](https://console.groq.com) | -| **Moonshot** | `moonshot/` | `https://api.moonshot.cn/v1` | OpenAI | [获取密钥](https://platform.moonshot.cn) | -| **通义千问 (Qwen)** | `qwen/` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI | [获取密钥](https://dashscope.console.aliyun.com) | -| **NVIDIA** | `nvidia/` | `https://integrate.api.nvidia.com/v1` | OpenAI | [获取密钥](https://build.nvidia.com) | -| **Ollama** | `ollama/` | `http://localhost:11434/v1` | OpenAI | 本地(无需密钥) | -| **OpenRouter** | `openrouter/` | `https://openrouter.ai/api/v1` | OpenAI | [获取密钥](https://openrouter.ai/keys) | -| **VLLM** | `vllm/` | `http://localhost:8000/v1` | OpenAI | 本地 | -| **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [获取密钥](https://cerebras.ai) | -| **火山引擎** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [获取密钥](https://console.volcengine.com) | -| **神算云** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - | -| **Antigravity** | `antigravity/` | Google Cloud | 自定义 | 仅 OAuth | -| **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - | +| 厂商 | `model` 前缀 | 默认 API Base | 协议 | 获取 API Key | +| ------------------- | ----------------- | --------------------------------------------------- | --------- | ----------------------------------------------------------------- | +| **OpenAI** | `openai/` | `https://api.openai.com/v1` | OpenAI | [获取密钥](https://platform.openai.com) | +| **Anthropic** | `anthropic/` | `https://api.anthropic.com/v1` | Anthropic | [获取密钥](https://console.anthropic.com) | +| **智谱 AI (GLM)** | `zhipu/` | `https://open.bigmodel.cn/api/paas/v4` | OpenAI | [获取密钥](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) | +| **DeepSeek** | `deepseek/` | `https://api.deepseek.com/v1` | OpenAI | [获取密钥](https://platform.deepseek.com) | +| **Google Gemini** | `gemini/` | `https://generativelanguage.googleapis.com/v1beta` | OpenAI | [获取密钥](https://aistudio.google.com/api-keys) | +| **Groq** | `groq/` | `https://api.groq.com/openai/v1` | OpenAI | [获取密钥](https://console.groq.com) | +| **Moonshot** | `moonshot/` | `https://api.moonshot.cn/v1` | OpenAI | [获取密钥](https://platform.moonshot.cn) | +| **通义千问 (Qwen)** | `qwen/` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI | [获取密钥](https://dashscope.console.aliyun.com) | +| **NVIDIA** | `nvidia/` | `https://integrate.api.nvidia.com/v1` | OpenAI | [获取密钥](https://build.nvidia.com) | +| **Ollama** | `ollama/` | `http://localhost:11434/v1` | OpenAI | 本地(无需密钥) | +| **OpenRouter** | `openrouter/` | `https://openrouter.ai/api/v1` | OpenAI | [获取密钥](https://openrouter.ai/keys) | +| **VLLM** | `vllm/` | `http://localhost:8000/v1` | OpenAI | 本地 | +| **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [获取密钥](https://cerebras.ai) | +| **火山引擎** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [获取密钥](https://console.volcengine.com) | +| **神算云** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - | +| **Antigravity** | `antigravity/` | Google Cloud | 自定义 | 仅 OAuth | +| **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - | #### 基础配置示例 @@ -720,6 +489,7 @@ Agent 读取 HEARTBEAT.md #### 各厂商配置示例 **OpenAI** + ```json { "model_name": "gpt-5.2", @@ -729,6 +499,7 @@ Agent 读取 HEARTBEAT.md ``` **智谱 AI (GLM)** + ```json { "model_name": "glm-4.7", @@ -738,6 +509,7 @@ Agent 读取 HEARTBEAT.md ``` **DeepSeek** + ```json { "model_name": "deepseek-chat", @@ -747,6 +519,7 @@ Agent 读取 HEARTBEAT.md ``` **Anthropic (使用 OAuth)** + ```json { "model_name": "claude-sonnet-4.6", @@ -754,9 +527,11 @@ Agent 读取 HEARTBEAT.md "auth_method": "oauth" } ``` + > 运行 `picoclaw auth login --provider anthropic` 来设置 OAuth 凭证。 **Ollama (本地)** + ```json { "model_name": "llama3", @@ -765,6 +540,7 @@ Agent 读取 HEARTBEAT.md ``` **自定义代理/API** + ```json { "model_name": "my-custom-model", @@ -802,6 +578,7 @@ Agent 读取 HEARTBEAT.md 旧的 `providers` 配置格式**已弃用**,但为向后兼容仍支持。 **旧配置(已弃用):** + ```json { "providers": { @@ -820,6 +597,7 @@ Agent 读取 HEARTBEAT.md ``` **新配置(推荐):** + ```json { "model_list": [ @@ -844,7 +622,7 @@ Agent 读取 HEARTBEAT.md **1. 获取 API key 和 base URL** -* 获取 [API key](https://bigmodel.cn/usercenter/proj-mgmt/apikeys) +- 获取 [API key](https://bigmodel.cn/usercenter/proj-mgmt/apikeys) **2. 配置** @@ -866,7 +644,6 @@ Agent 读取 HEARTBEAT.md } } } - ``` **3. 运行** @@ -946,30 +723,29 @@ picoclaw agent -m "你好" "interval": 30 } } - ``` ## CLI 命令行参考 -| 命令 | 描述 | -| --- | --- | -| `picoclaw onboard` | 初始化配置和工作区 | -| `picoclaw agent -m "..."` | 与 Agent 对话 | -| `picoclaw agent` | 交互式聊天模式 | -| `picoclaw gateway` | 启动网关 (Gateway) | -| `picoclaw status` | 显示状态 | -| `picoclaw cron list` | 列出所有定时任务 | -| `picoclaw cron add ...` | 添加定时任务 | +| 命令 | 描述 | +| ------------------------- | ------------------ | +| `picoclaw onboard` | 初始化配置和工作区 | +| `picoclaw agent -m "..."` | 与 Agent 对话 | +| `picoclaw agent` | 交互式聊天模式 | +| `picoclaw gateway` | 启动网关 (Gateway) | +| `picoclaw status` | 显示状态 | +| `picoclaw cron list` | 列出所有定时任务 | +| `picoclaw cron add ...` | 添加定时任务 | ### 定时任务 / 提醒 (Scheduled Tasks) PicoClaw 通过 `cron` 工具支持定时提醒和重复任务: -* **一次性提醒**: "Remind me in 10 minutes" (10分钟后提醒我) → 10分钟后触发一次 -* **重复任务**: "Remind me every 2 hours" (每2小时提醒我) → 每2小时触发 -* **Cron 表达式**: "Remind me at 9am daily" (每天上午9点提醒我) → 使用 cron 表达式 +- **一次性提醒**: "Remind me in 10 minutes" (10分钟后提醒我) → 10分钟后触发一次 +- **重复任务**: "Remind me every 2 hours" (每2小时提醒我) → 每2小时触发 +- **Cron 表达式**: "Remind me at 9am daily" (每天上午9点提醒我) → 使用 cron 表达式 任务存储在 `~/.picoclaw/workspace/cron/` 中并自动处理。 @@ -983,7 +759,7 @@ PicoClaw 通过 `cron` 工具支持定时提醒和重复任务: 用户群组: -Discord: [https://discord.gg/V4sAZ9XWpN](https://discord.gg/V4sAZ9XWpN) +Discord: [https://discord.gg/V4sAZ9XWpN](https://discord.gg/V4sAZ9XWpN) PicoClaw @@ -997,6 +773,7 @@ Discord: [https://discord.gg/V4sAZ9XWpN](https://discord.gg/V4sAZ9XWpN) 1. 在 [https://brave.com/search/api](https://brave.com/search/api) 获取免费 API Key (每月 2000 次免费查询) 2. 添加到 `~/.picoclaw/config.json`: + ```json { "tools": { @@ -1013,11 +790,8 @@ Discord: [https://discord.gg/V4sAZ9XWpN](https://discord.gg/V4sAZ9XWpN) } } } - ``` - - ### 遇到内容过滤错误 (Content Filtering Errors) 某些提供商(如智谱)有严格的内容过滤。尝试改写您的问题或使用其他模型。 @@ -1030,10 +804,10 @@ Discord: [https://discord.gg/V4sAZ9XWpN](https://discord.gg/V4sAZ9XWpN) ## 📝 API Key 对比 -| 服务 | 免费层级 | 适用场景 | -| --- | --- | --- | -| **OpenRouter** | 200K tokens/月 | 多模型聚合 (Claude, GPT-4 等) | -| **智谱 (Zhipu)** | 200K tokens/月 | 最适合中国用户 | -| **Brave Search** | 2000 次查询/月 | 网络搜索功能 | -| **Groq** | 提供免费层级 | 极速推理 (Llama, Mixtral) | -| **Cerebras** | 提供免费层级 | 极速推理 (Llama, Qwen 等) | \ No newline at end of file +| 服务 | 免费层级 | 适用场景 | +| ---------------- | -------------- | ----------------------------- | +| **OpenRouter** | 200K tokens/月 | 多模型聚合 (Claude, GPT-4 等) | +| **智谱 (Zhipu)** | 200K tokens/月 | 最适合中国用户 | +| **Brave Search** | 2000 次查询/月 | 网络搜索功能 | +| **Groq** | 提供免费层级 | 极速推理 (Llama, Mixtral) | +| **Cerebras** | 提供免费层级 | 极速推理 (Llama, Qwen 等) | diff --git a/docs/channels/dingtalk/README.zh.md b/docs/channels/dingtalk/README.zh.md new file mode 100644 index 000000000..1e445d0b0 --- /dev/null +++ b/docs/channels/dingtalk/README.zh.md @@ -0,0 +1,33 @@ +# 钉钉 + +钉钉是阿里巴巴的企业通讯平台,在中国职场中广受欢迎。它采用流式 SDK 来维持持久连接。 + +## 配置 + +```json +{ + "channels": { + "dingtalk": { + "enabled": true, + "client_id": "YOUR_CLIENT_ID", + "client_secret": "YOUR_CLIENT_SECRET", + "allow_from": [] + } + } +} +``` + +| 字段 | 类型 | 必填 | 描述 | +| ------------- | ------ | ---- | -------------------------------- | +| enabled | bool | 是 | 是否启用钉钉频道 | +| client_id | string | 是 | 钉钉应用的 Client ID | +| client_secret | string | 是 | 钉钉应用的 Client Secret | +| allow_from | array | 否 | 用户ID白名单,空表示允许所有用户 | + +## 设置流程 + +1. 前往 [钉钉开放平台](https://open.dingtalk.com/) +2. 创建一个企业内部应用 +3. 从应用设置中获取 Client ID 和 Client Secret +4. 配置OAuth和事件订阅(如需要) +5. 将 Client ID 和 Client Secret 填入配置文件中 diff --git a/docs/channels/discord/README.zh.md b/docs/channels/discord/README.zh.md new file mode 100644 index 000000000..5b597eced --- /dev/null +++ b/docs/channels/discord/README.zh.md @@ -0,0 +1,35 @@ +# Discord + +Discord 是一个专为社区设计的免费语音、视频和文本聊天应用。PicoClaw 通过 Discord Bot API 连接到 Discord 服务器,支持接收和发送消息。 + +## 配置 + +```json +{ + "channels": { + "discord": { + "enabled": true, + "token": "YOUR_BOT_TOKEN", + "allow_from": ["YOUR_USER_ID"], + "mention_only": false + } + } +} +``` + +| 字段 | 类型 | 必填 | 描述 | +| ------------ | ------ | ---- | -------------------------------- | +| enabled | bool | 是 | 是否启用 Discord 频道 | +| token | string | 是 | Discord 机器人 Token | +| allow_from | array | 否 | 用户ID白名单,空表示允许所有用户 | +| mention_only | bool | 否 | 是否仅响应提及机器人的消息 | + +## 设置流程 + +1. 前往 [Discord 开发者门户](https://discord.com/developers/applications) 创建一个新的应用 +2. 启用 Intents: + - Message Content Intent + - Server Members Intent +3. 获取 Bot Token +4. 将 Bot Token 填入配置文件中 +5. 邀请机器人加入服务器并授予必要权限(例如发送消息、读取消息历史等) diff --git a/docs/channels/feishu/README.zh.md b/docs/channels/feishu/README.zh.md new file mode 100644 index 000000000..310827723 --- /dev/null +++ b/docs/channels/feishu/README.zh.md @@ -0,0 +1,37 @@ +# 飞书 + +飞书(国际版名称:Lark)是字节跳动旗下的企业协作平台。它通过事件驱动的 Webhook 同时支持中国和全球市场。 + +## 配置 + +```json +{ + "channels": { + "feishu": { + "enabled": true, + "app_id": "cli_xxx", + "app_secret": "xxx", + "encrypt_key": "", + "verification_token": "", + "allow_from": [] + } + } +} +``` + +| 字段 | 类型 | 必填 | 描述 | +| ------------------ | ------ | ---- | -------------------------------- | +| enabled | bool | 是 | 是否启用飞书频道 | +| app_id | string | 是 | 飞书应用的 App ID(以cli\_开头) | +| app_secret | string | 是 | 飞书应用的 App Secret | +| encrypt_key | string | 否 | 事件回调加密密钥 | +| verification_token | string | 否 | 用于Webhook事件验证的Token | +| allow_from | array | 否 | 用户ID白名单,空表示允许所有用户 | + +## 设置流程 + +1. 前往 [飞书开放平台](https://open.feishu.cn/)创建应用程序 +2. 获取 App ID 和 App Secret +3. 配置事件订阅和Webhook URL +4. 设置加密(可选,生产环境建议启用) +5. 将 App ID、App Secret、Encrypt Key 和 Verification Token(如果启用加密) 填入配置文件中 diff --git a/docs/channels/line/README.zh.md b/docs/channels/line/README.zh.md new file mode 100644 index 000000000..fd3aa80da --- /dev/null +++ b/docs/channels/line/README.zh.md @@ -0,0 +1,41 @@ +# Line + +PicoClaw 通过 LINE Messaging API 配合 Webhook 回调功能实现对 LINE 的支持。 + +## 配置 + +```json +{ + "channels": { + "line": { + "enabled": true, + "channel_secret": "YOUR_CHANNEL_SECRET", + "channel_access_token": "YOUR_CHANNEL_ACCESS_TOKEN", + "webhook_host": "0.0.0.0", + "webhook_port": 18791, + "webhook_path": "/webhook/line", + "allow_from": [] + } + } +} +``` + +| 字段 | 类型 | 必填 | 描述 | +| -------------------- | ------ | ---- | ------------------------------------------ | +| enabled | bool | 是 | 是否启用 LINE Channel | +| channel_secret | string | 是 | LINE Messaging API 的 Channel Secret | +| channel_access_token | string | 是 | LINE Messaging API 的 Channel Access Token | +| webhook_host | string | 是 | Webhook 监听的主机地址 (通常为 0.0.0.0) | +| webhook_port | int | 是 | Webhook 监听的端口 (默认为 18791) | +| webhook_path | string | 是 | Webhook 的路径 (默认为 /webhook/line) | +| allow_from | array | 否 | 用户ID白名单,空表示允许所有用户 | + +## 设置流程 + +1. 前往 [LINE Developers Console](https://developers.line.biz/console/) 创建一个服务提供商和一个 Messaging API Channel +2. 获取 Channel Secret 和 Channel Access Token +3. 配置Webhook: + - Line要求Webhook必须使用HTTPS协议,因此需要部署一个支持HTTPS的服务器,或者使用反向代理工具如ngrok将本地服务器暴露到公网 + - 将 Webhook URL 设置为 `https://your-domain.com/webhook/line` + - 启用 Webhook 并验证 URL +4. 将 Channel Secret 和 Channel Access Token 填入配置文件中 diff --git a/docs/channels/maixcam/README.zh.md b/docs/channels/maixcam/README.zh.md new file mode 100644 index 000000000..8d53d4bef --- /dev/null +++ b/docs/channels/maixcam/README.zh.md @@ -0,0 +1,31 @@ +# MaixCam + +MaixCam 是专用于连接矽速科技 MaixCAM 与 MaixCAM2 AI 摄像设备的通道。它采用 TCP 套接字实现双向通信,支持边缘 AI 部署场景。 + +## 配置 + +```json +{ + "channels": { + "maixcam": { + "enabled": true, + "server_address": "0.0.0.0:8899", + "allow_from": [] + } + } +} +``` + +| 字段 | 类型 | 必填 | 描述 | +| -------------- | ------ | ---- | -------------------------------- | +| enabled | bool | 是 | 是否启用 MaixCam 频道 | +| server_address | string | 是 | TCP 服务器监听地址和端口 | +| allow_from | array | 否 | 设备ID白名单,空表示允许所有设备 | + +## 使用场景 + +MaixCam 通道使 PicoClaw 能够作为边缘设备的 AI 后端运行: + +- **智能监控** :MaixCAM 发送图像帧,PicoClaw 通过视觉模型进行分析 +- **物联网控制** :设备发送传感器数据,PicoClaw 协调响应 +- **离线AI** :在本地网络部署 PicoClaw 实现低延迟推理 diff --git a/docs/channels/onebot/README.zh.md b/docs/channels/onebot/README.zh.md new file mode 100644 index 000000000..6195f1c98 --- /dev/null +++ b/docs/channels/onebot/README.zh.md @@ -0,0 +1,31 @@ +# OneBot + +OneBot 是一个面向 QQ 机器人的开放协议标准,为多种 QQ 机器人实现(例如 go-cqhttp、Mirai)提供了统一的接口。它使用 WebSocket 进行通信。 + +## 配置 + +```json +{ + "channels": { + "onebot": { + "enabled": true, + "ws_url": "ws://localhost:8080", + "access_token": "", + "allow_from": [] + } + } +} +``` + +| 字段 | 类型 | 必填 | 描述 | +| ------------ | ------ | ---- | -------------------------------- | +| enabled | bool | 是 | 是否启用 OneBot 频道 | +| ws_url | string | 是 | OneBot 服务器的 WebSocket URL | +| access_token | string | 否 | 连接 OneBot 服务器的访问令牌 | +| allow_from | array | 否 | 用户ID白名单,空表示允许所有用户 | + +## 设置流程 + +1. 部署一个 OneBot 兼容的实现(例如napcat) +2. 配置 OneBot 实现以启用 WebSocket 服务并设置访问令牌(如果需要) +3. 将 WebSocket URL 和访问令牌填入配置文件中 diff --git a/docs/channels/qq/README.zh.md b/docs/channels/qq/README.zh.md new file mode 100644 index 000000000..bd774960f --- /dev/null +++ b/docs/channels/qq/README.zh.md @@ -0,0 +1,32 @@ +# QQ + +PicoClaw 通过 QQ 开放平台的官方机器人 API 提供对 QQ 的支持。 + +## 配置 + +```json +{ + "channels": { + "qq": { + "enabled": true, + "app_id": "YOUR_APP_ID", + "app_secret": "YOUR_APP_SECRET", + "allow_from": [] + } + } +} +``` + +| 字段 | 类型 | 必填 | 描述 | +| ---------- | ------ | ---- | -------------------------------- | +| enabled | bool | 是 | 是否启用 QQ Channel | +| app_id | string | 是 | QQ 机器人应用的 App ID | +| app_secret | string | 是 | QQ 机器人应用的 App Secret | +| allow_from | array | 否 | 用户ID白名单,空表示允许所有用户 | + +## 设置流程 + +1. 前往 [QQ 开放平台](https://q.qq.com/) 创建一个机器人 +2. 通过仪表盘获取 App ID 和 App Secret +3. 开启机器人沙箱模式, 将用户和群添加到沙箱中 +4. 将 App ID 和 App Secret 填入配置文件中 diff --git a/docs/channels/slack/README.zh.md b/docs/channels/slack/README.zh.md new file mode 100644 index 000000000..58ebcb566 --- /dev/null +++ b/docs/channels/slack/README.zh.md @@ -0,0 +1,33 @@ +# Slack + +Slack 是全球领先的企业级即时通讯平台。PicoClaw 采用 Slack 的 Socket Mode 实现实时双向通信,无需配置公开的 Webhook 端点。 + +## 配置 + +```json +{ + "channels": { + "slack": { + "enabled": true, + "bot_token": "xoxb-...", + "app_token": "xapp-...", + "allow_from": [] + } + } +} +``` + +| 字段 | 类型 | 必填 | 描述 | +| ---------- | ------ | ---- | -------------------------------------------------------- | +| enabled | bool | 是 | 是否启用 Slack 频道 | +| bot_token | string | 是 | Slack 机器人的 Bot User OAuth Token (以 xoxb- 开头) | +| app_token | string | 是 | Slack 应用的 Socket Mode App Level Token (以 xapp- 开头) | +| allow_from | array | 否 | 用户ID白名单,空表示允许所有用户 | + +## 设置流程 + +1. 前往 [Slack API](https://api.slack.com/) 创建一个新的 Slack 应用 +2. 启用 Socket Mode 并获取 App Level Token +3. 添加 Bot Token Scopes(例如`chat:write`、`im:history`等) +4. 安装应用到工作区并获取 Bot User OAuth Token +5. 将 Bot Token 和 App Token 填入配置文件中 diff --git a/docs/channels/telegram/README.zh.md b/docs/channels/telegram/README.zh.md new file mode 100644 index 000000000..d453c68fa --- /dev/null +++ b/docs/channels/telegram/README.zh.md @@ -0,0 +1,33 @@ +# Telegram + +Telegram Channel 通过 Telegram 机器人 API 使用长轮询实现基于机器人的通信。它支持文本消息、媒体附件(照片、语音、音频、文档)、通过 Groq Whisper 进行语音转录以及内置命令处理器。 + +## 配置 + +```json +{ + "channels": { + "telegram": { + "enabled": true, + "token": "123456789:ABCdefGHIjklMNOpqrsTUVwxyz", + "allow_from": ["123456789"], + "proxy": "" + } + } +} +``` + +| 字段 | 类型 | 必填 | 描述 | +| ---------- | ------ | ---- | --------------------------------------------------------- | +| enabled | bool | 是 | 是否启用 Telegram 频道 | +| token | string | 是 | Telegram 机器人 API Token | +| allow_from | array | 否 | 用户ID白名单,空表示允许所有用户 | +| proxy | string | 否 | 连接 Telegram API 的代理 URL (例如 http://127.0.0.1:7890) | + +## 设置流程 + +1. 在 Telegram 中搜索 `@BotFather` +2. 发送 `/newbot` 命令并按照提示创建新机器人 +3. 获取 HTTP API Token +4. 将 Token 填入配置文件中 +5. (可选) 配置 `allow_from` 以限制允许互动的用户 ID (可通过 `@userinfobot` 获取 ID) diff --git a/docs/channels/wecom/wecom_app/README.zh.md b/docs/channels/wecom/wecom_app/README.zh.md new file mode 100644 index 000000000..1e6a0e2b3 --- /dev/null +++ b/docs/channels/wecom/wecom_app/README.zh.md @@ -0,0 +1,47 @@ +# 企业微信自建应用 + +企业微信自建应用是指企业在企业微信中创建的应用,主要用于企业内部使用。通过企业微信自建应用,企业可以实现与员工的高效沟通和协作,提高工作效率。 + +## 配置 + +```json +{ + "channels": { + "wecom_app": { + "enabled": true, + "corp_id": "wwxxxxxxxxxxxxxxxx", + "corp_secret": "YOUR_CORP_SECRET", + "agent_id": 1000002, + "token": "YOUR_TOKEN", + "encoding_aes_key": "YOUR_ENCODING_AES_KEY", + "webhook_host": "0.0.0.0", + "webhook_port": 18792, + "webhook_path": "/webhook/wecom-app", + "allow_from": [], + "reply_timeout": 5 + } + } +} +``` + +| 字段 | 类型 | 必填 | 描述 | +| ---------------- | ------ | ---- | ---------------------------------------- | +| corp_id | string | 是 | 企业 ID | +| corp_secret | string | 是 | 应用程序密钥 | +| agent_id | int | 是 | 应用程序代理 ID | +| token | string | 是 | 回调验证令牌 | +| encoding_aes_key | string | 是 | 43 字符 AES 密钥 | +| webhook_host | string | 否 | HTTP 服务器绑定地址 | +| webhook_port | int | 否 | HTTP 服务器端口(默认:18792) | +| webhook_path | string | 否 | Webhook 路径(默认:/webhook/wecom-app) | +| allow_from | array | 否 | 用户 ID 白名单 | +| reply_timeout | int | 否 | 回复超时时间(秒) | + +## 设置流程 + +1. 登录 [企业微信管理后台](https://work.weixin.qq.com/) +2. 进入“应用管理” -> “创建应用” +3. 获取企业 ID (CorpID) 和应用 Secret +4. 在应用设置中配置“接收消息”,获取 Token 和 EncodingAESKey +5. 设置回调 URL 为 `http://:/webhook/wecom-app` +6. 将 CorpID, Secret, AgentID 等信息填入配置文件 diff --git a/docs/channels/wecom/wecom_bot/README.zh.md b/docs/channels/wecom/wecom_bot/README.zh.md new file mode 100644 index 000000000..c4bb1c87e --- /dev/null +++ b/docs/channels/wecom/wecom_bot/README.zh.md @@ -0,0 +1,41 @@ +# 企业微信机器人 + +企业微信机器人是企业微信提供的一种快速接入方式,可以通过 Webhook URL 接收消息。 + +## 配置 + +```json +{ + "channels": { + "wecom": { + "enabled": true, + "token": "YOUR_TOKEN", + "encoding_aes_key": "YOUR_ENCODING_AES_KEY", + "webhook_url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY", + "webhook_host": "0.0.0.0", + "webhook_port": 18793, + "webhook_path": "/webhook/wecom", + "allow_from": [], + "reply_timeout": 5 + } + } +} +``` + +| 字段 | 类型 | 必填 | 描述 | +| ---------------- | ------ | ---- | -------------------------------------------- | +| token | string | 是 | 签名验证代币 | +| encoding_aes_key | string | 是 | 用于解密的 43 字符 AES 密钥 | +| webhook_url | string | 是 | 用于发送回复的企业微信群聊机器人 Webhook URL | +| webhook_host | string | 否 | HTTP 服务器绑定地址(默认:0.0.0.0) | +| webhook_port | int | 否 | HTTP 服务器端口(默认:18793) | +| webhook_path | string | 否 | Webhook 端点路径(默认:/webhook/wecom) | +| allow_from | array | 否 | 用户 ID 白名单(空值 = 允许所有用户) | +| reply_timeout | int | 否 | 回复超时时间(单位:秒,默认值:5) | + +## 设置流程 + +1. 在企业微信群中添加机器人 +2. 获取 Webhook URL +3. (如需接收消息) 在机器人配置页面设置接收消息的 API 地址(回调地址)以及 Token 和 EncodingAESKey +4. 将相关信息填入配置文件 From aea4f25c8387aee5e16b03a126beebbd712ff26d Mon Sep 17 00:00:00 2001 From: zepan Date: Sat, 21 Feb 2026 22:45:47 +0800 Subject: [PATCH 09/40] 1. update wechat qrcode. 2. add CONTRIBUTING.md --- CONTRIBUTING.md | 302 ++++++++++++++++++++++++++++++++++++++++++++ CONTRIBUTING.zh.md | 303 +++++++++++++++++++++++++++++++++++++++++++++ assets/wechat.png | Bin 144319 -> 144045 bytes 3 files changed, 605 insertions(+) create mode 100644 CONTRIBUTING.md create mode 100644 CONTRIBUTING.zh.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..88227f493 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,302 @@ +# Contributing to PicoClaw + +Thank you for your interest in contributing to PicoClaw! This project is a community-driven effort to build the lightweight and versatile personal AI assistant. We welcome contributions of all kinds: bug fixes, features, documentation, translations, and testing. + +PicoClaw itself was substantially developed with AI assistance — we embrace this approach and have built our contribution process around it. + +## Table of Contents + +- [Code of Conduct](#code-of-conduct) +- [Ways to Contribute](#ways-to-contribute) +- [Getting Started](#getting-started) +- [Development Setup](#development-setup) +- [Making Changes](#making-changes) +- [AI-Assisted Contributions](#ai-assisted-contributions) +- [Pull Request Process](#pull-request-process) +- [Branch Strategy](#branch-strategy) +- [Code Review](#code-review) +- [Communication](#communication) + +--- + +## Code of Conduct + +We are committed to maintaining a welcoming and respectful community. Be kind, constructive, and assume good faith. Harassment or discrimination of any kind will not be tolerated. + +--- + +## Ways to Contribute + +- **Bug reports** — Open an issue using the bug report template. +- **Feature requests** — Open an issue using the feature request template; discuss before implementing. +- **Code** — Fix bugs or implement features. See the workflow below. +- **Documentation** — Improve READMEs, docs, inline comments, or translations. +- **Testing** — Run PicoClaw on new hardware, channels, or LLM providers and report your results. + +For substantial new features, please open an issue first to discuss the design before writing code. This prevents wasted effort and ensures alignment with the project's direction. + +--- + +## Getting Started + +1. **Fork** the repository on GitHub. +2. **Clone** your fork locally: + ```bash + git clone https://github.com//picoclaw.git + cd picoclaw + ``` +3. Add the upstream remote: + ```bash + git remote add upstream https://github.com/sipeed/picoclaw.git + ``` + +--- + +## Development Setup + +### Prerequisites + +- Go 1.25 or later +- `make` + +### Build + +```bash +make build # Build binary (runs go generate first) +make generate # Run go generate only +make check # Full pre-commit check: deps + fmt + vet + test +``` + +### Running Tests + +```bash +make test # Run all tests +go test -run TestName -v ./pkg/session/ # Run a single test +go test -bench=. -benchmem -run='^$' ./... # Run benchmarks +``` + +### Code Style + +```bash +make fmt # Format code +make vet # Static analysis +make lint # Full linter run +``` + +All CI checks must pass before a PR can be merged. Run `make check` locally before pushing to catch issues early. + +--- + +## Making Changes + +### Branching + +Always branch off `main` and target `main` in your PR. Never push directly to `main` or any `release/*` branch: + +```bash +git checkout main +git pull upstream main +git checkout -b your-feature-branch +``` + +Use descriptive branch names, e.g. `fix/telegram-timeout`, `feat/ollama-provider`, `docs/contributing-guide`. + +### Commits + +- Write clear, concise commit messages in English. +- Use the imperative mood: "Add retry logic" not "Added retry logic". +- Reference the related issue when relevant: `Fix session leak (#123)`. +- Keep commits focused. One logical change per commit is preferred. +- For minor cleanups or typo fixes, squash them into a single commit before opening a PR. +- Refer to https://www.conventionalcommits.org/zh-hans/v1.0.0/ + +### Keeping Up to Date + +Rebase your branch onto upstream `main` before opening a PR: + +```bash +git fetch upstream +git rebase upstream/main +``` + +--- + +## AI-Assisted Contributions + +PicoClaw was built with substantial AI assistance, and we fully embrace AI-assisted development. However, contributors must understand their responsibilities when using AI tools. + +### Disclosure Is Required + +Every PR must disclose AI involvement using the PR template's **🤖 AI Code Generation** section. There are three levels: + +| Level | Description | +|---|---| +| 🤖 Fully AI-generated | AI wrote the code; contributor reviewed and validated it | +| 🛠️ Mostly AI-generated | AI produced the draft; contributor made significant modifications | +| 👨‍💻 Mostly Human-written | Contributor led; AI provided suggestions or none at all | + +Honest disclosure is expected. There is no stigma attached to any level — what matters is the quality of the contribution. + +### You Are Responsible for What You Submit + +Using AI to generate code does not reduce your responsibility as the contributor. Before opening a PR with AI-generated code, you must: + +- **Read and understand** every line of the generated code. +- **Test it** in a real environment (see the Test Environment section of the PR template). +- **Check for security issues** — AI models can generate subtly insecure code (e.g., path traversal, injection, credential exposure). Review carefully. +- **Verify correctness** — AI-generated logic can be plausible-sounding but wrong. Validate the behavior, not just the syntax. + +PRs where it is clear the contributor has not read or tested the AI-generated code will be closed without review. + +### AI-Generated Code Quality Standards + +AI-generated contributions are held to the **same quality bar** as human-written code: + +- It must pass all CI checks (`make check`). +- It must be idiomatic Go and consistent with the existing codebase style. +- It must not introduce unnecessary abstractions, dead code, or over-engineering. +- It must include or update tests where appropriate. + +### Security Review + +AI-generated code requires extra security scrutiny. Pay special attention to: + +- File path handling and sandbox escapes (see commit `244eb0b` for a real example) +- External input validation in channel handlers and tool implementations +- Credential or secret handling +- Command execution (`exec.Command`, shell invocations) + +If you are unsure whether a piece of AI-generated code is safe, say so in the PR — reviewers will help. + +--- + +## Pull Request Process + +### Before Opening a PR + +- [ ] Run `make check` and ensure it passes locally. +- [ ] Fill in the PR template completely, including the AI disclosure section. +- [ ] Link any related issue(s) in the PR description. +- [ ] Keep the PR focused. Avoid bundling unrelated changes together. + +### PR Template Sections + +The PR template asks for: + +- **Description** — What does this change do and why? +- **Type of Change** — Bug fix, feature, docs, or refactor. +- **AI Code Generation** — Disclosure of AI involvement (required). +- **Related Issue** — Link to the issue this addresses. +- **Technical Context** — Reference URLs and reasoning (skip for pure docs PRs). +- **Test Environment** — Hardware, OS, model/provider, and channels used for testing. +- **Evidence** — Optional logs or screenshots demonstrating the change works. +- **Checklist** — Self-review confirmation. + +### PR Size + +Prefer small, reviewable PRs. A PR that changes 200 lines across 5 files is much easier to review than one that changes 2000 lines across 30 files. If your feature is large, consider splitting it into a series of smaller, logically complete PRs. + +--- + +## Branch Strategy + +### Long-Lived Branches + +- **`main`** — the active development branch. All feature PRs target `main`. The branch is protected: direct pushes are not permitted, and at least one maintainer approval is required before merging. +- **`release/x.y`** — stable release branches, cut from `main` when a version is ready to ship. These branches are more strictly protected than `main`. + +### Requirements to Merge into `main` + +A PR can only be merged when all of the following are satisfied: + +1. **CI passes** — All GitHub Actions workflows (lint, test, build) must be green. +2. **Reviewer approval** — At least one maintainer has approved the PR. +3. **No unresolved review comments** — All review threads must be resolved. +4. **PR template is complete** — Including AI disclosure and test environment. + +### Who Can Merge + +Only maintainers can merge PRs. Contributors cannot merge their own PRs, even if they have write access. + +### Merge Strategy + +We use **squash merge** for most PRs to keep the `main` history clean and readable. Each merged PR becomes a single commit referencing the PR number, e.g.: + +``` +feat: Add Ollama provider support (#491) +``` + +If a PR consists of multiple independent, well-separated commits that tell a clear story, a regular merge may be used at the maintainer's discretion. + +### Release Branches + +When a version is ready, maintainers cut a `release/x.y` branch from `main`. After that point: + +- **New features are not backported.** The release branch receives no new functionality after it is cut. +- **Security fixes and critical bug fixes are cherry-picked.** If a fix in `main` qualifies (security vulnerability, data loss, crash), maintainers will cherry-pick the relevant commit(s) onto the affected `release/x.y` branch and issue a patch release. + +If you believe a fix in `main` should be backported to a release branch, note it in the PR description or open a separate issue. The decision rests with the maintainers. + +Release branches have stricter protections than `main` and are never directly pushed to under any circumstances. + +--- + +## Code Review + +### For Contributors + +- Respond to review comments within a reasonable time. If you need more time, say so. +- When you update a PR in response to feedback, briefly note what changed (e.g., "Updated to use `sync.RWMutex` as suggested"). +- If you disagree with feedback, engage respectfully. Explain your reasoning; reviewers can be wrong too. +- Do not force-push after a review has started — it makes it harder for reviewers to see what changed. Use additional commits instead; the maintainer will squash on merge. + +### For Reviewers + +Review for: + +1. **Correctness** — Does the code do what it claims? Are there edge cases? +2. **Security** — Especially for AI-generated code, tool implementations, and channel handlers. +3. **Architecture** — Is the approach consistent with the existing design? +4. **Simplicity** — Is there a simpler solution? Does this add unnecessary complexity? +5. **Tests** — Are the changes covered by tests? Are existing tests still meaningful? + +Be constructive and specific. "This could have a race condition if two goroutines call this concurrently — consider using a mutex here" is better than "this looks wrong". + + +### Reviewer List +Once your PR is submitted, you can reach out to the assigned reviewers listed in the following table. + +|Function| Reviewer| +|--- |--- | +|Provider|@yinwm | +|Channel |@yinwm | +|Agent |@lxowalle| +|Tools |@lxowalle| +|SKill || +|MCP || +|Optimization|@lxowalle| +|Security|| +|AI CI |@imguoguo| +|UX || +|Document|| + +--- + +## Communication + +- **GitHub Issues** — Bug reports, feature requests, design discussions. +- **GitHub Discussions** — General questions, ideas, community conversation. +- **Pull Request comments** — Code-specific feedback. +- **Wechat&Discord** — We will invite you when you have at least one merged PR + +When in doubt, open an issue before writing code. It costs little and prevents wasted effort. + +--- + +## A Note on the Project's AI-Driven Origin + +PicoClaw's architecture was substantially designed and implemented with AI assistance, guided by human oversight. If you find something that looks odd or over-engineered, it may be an artifact of that process — opening an issue to discuss it is always welcome. + +We believe AI-assisted development done responsibly produces great results. We also believe humans must remain accountable for what they ship. These two beliefs are not in conflict. + +Thank you for contributing! diff --git a/CONTRIBUTING.zh.md b/CONTRIBUTING.zh.md new file mode 100644 index 000000000..01a1abfd5 --- /dev/null +++ b/CONTRIBUTING.zh.md @@ -0,0 +1,303 @@ +# 参与贡献 PicoClaw + +感谢你对 PicoClaw 的关注!本项目是一个社区驱动的开源项目,目标是构建 轻量灵活,人人可用 的个人AI助手。我们欢迎一切形式的贡献:Bug 修复、新功能、文档、翻译和测试。 + +PicoClaw 本身在很大程度上是借助 AI 辅助开发的——我们拥抱这种方式,并围绕它构建了贡献流程。 + +## 目录 + +- [行为准则](#行为准则) +- [贡献方式](#贡献方式) +- [快速开始](#快速开始) +- [开发环境配置](#开发环境配置) +- [提交修改](#提交修改) +- [AI 辅助贡献](#ai-辅助贡献) +- [Pull Request 流程](#pull-request-流程) +- [分支策略](#分支策略) +- [代码审查](#代码审查) +- [沟通渠道](#沟通渠道) + +--- + +## 行为准则 + +我们致力于维护一个友好、互相尊重的社区环境。请保持善意、建设性的态度,并善意地理解他人。任何形式的骚扰或歧视均不被接受。 + +--- + +## 贡献方式 + +- **Bug 反馈** — 使用 Bug 报告模板提交 Issue。 +- **功能建议** — 使用功能请求模板提交 Issue,建议在开始实现前先进行讨论。 +- **代码贡献** — 修复 Bug 或实现新功能,参见下方工作流程。 +- **文档改进** — 完善 README、文档、代码注释或翻译。 +- **测试与验证** — 在新硬件、新渠道或新 LLM 提供商上运行 PicoClaw 并反馈结果。 + +对于较大的新功能,请先提交 Issue 讨论设计方案,再动手写代码。这能避免无效投入,也确保与项目方向保持一致。 + +--- + +## 快速开始 + +1. 在 GitHub 上 **Fork** 本仓库。 +2. 将你的 Fork **克隆**到本地: + ```bash + git clone https://github.com/<你的用户名>/picoclaw.git + cd picoclaw + ``` +3. 添加上游远程仓库: + ```bash + git remote add upstream https://github.com/sipeed/picoclaw.git + ``` + +--- + +## 开发环境配置 + +### 前置依赖 + +- Go 1.25 或更高版本 +- `make` + +### 构建 + +```bash +make build # 构建二进制文件(会先执行 go generate) +make generate # 仅执行 go generate +make check # 完整的提交前检查:deps + fmt + vet + test +``` + +### 运行测试 + +```bash +make test # 运行所有测试 +go test -run TestName -v ./pkg/session/ # 运行单个测试 +go test -bench=. -benchmem -run='^$' ./... # 运行基准测试 +``` + +### 代码风格 + +```bash +make fmt # 格式化代码 +make vet # 静态分析 +make lint # 完整的 lint 检查 +``` + +所有 CI 检查通过后 PR 才能被合并。推送代码前请先在本地运行 `make check`,提前发现问题。 + +--- + +## 提交修改 + +### 分支管理 + +始终从 `main` 分支切出,并在 PR 中以 `main` 为目标分支。不要直接向 `main` 或任何 `release/*` 分支推送代码: + +```bash +git checkout main +git pull upstream main +git checkout -b 你的功能分支名 +``` + +请使用描述性的分支名,例如:`fix/telegram-timeout`、`feat/ollama-provider`、`docs/contributing-guide`。 + +### Commit 规范 + +- 使用英文撰写清晰、简洁的 commit 信息。 +- 使用祈使句:写 "Add retry logic",而不是 "Added retry logic"。 +- 有关联 Issue 时请引用:`Fix session leak (#123)`。 +- 保持 commit 专注,每个 commit 只做一件事。 +- 对于小的清理或拼写修正,提 PR 前请将其合并为一个 commit。 +- 按照 https://www.conventionalcommits.org/zh-hans/v1.0.0/ 规范来撰写 + +### 保持与上游同步 + +提 PR 前,请将你的分支变基到上游 `main`: + +```bash +git fetch upstream +git rebase upstream/main +``` + +--- + +## AI 辅助贡献 + +PicoClaw 在很大程度上借助 AI 辅助开发,我们完全拥抱这种开发方式。但贡献者必须清楚地了解自己在使用 AI 工具时所承担的责任。 + +### 必须披露 AI 使用情况 + +每个 PR 都必须通过 PR 模板中的 **🤖 AI 代码生成** 部分披露 AI 参与情况,共分三个级别: + +| 级别 | 说明 | +|---|---| +| 🤖 完全由 AI 生成 | AI 编写代码,贡献者负责审查和验证 | +| 🛠️ 主要由 AI 生成 | AI 起草,贡献者做了较大修改 | +| 👨‍💻 主要由人工编写 | 贡献者主导,AI 仅提供辅助或未使用 AI | + +我们期望你诚实填写。三种级别均可接受,没有任何歧视——重要的是贡献的质量。 + +### 你对提交的代码负全责 + +使用 AI 生成代码并不能减轻你作为贡献者的责任。在提交含有 AI 生成代码的 PR 之前,你必须: + +- **逐行阅读并理解**生成的代码。 +- **在真实环境中测试**(参见 PR 模板中的测试环境部分)。 +- **检查安全问题** — AI 模型可能生成存在安全隐患的代码(如路径穿越、注入攻击、凭据泄露等),请仔细审查。 +- **验证正确性** — AI 生成的逻辑可能听起来合理但实际上是错误的,请验证行为,而不仅仅是语法。 + +如果明显可以看出贡献者没有阅读或测试 AI 生成的代码,该 PR 将被直接关闭,不予审查。 + +### AI 生成代码的质量标准 + +AI 生成的代码与人工编写的代码遵循**相同的质量要求**: + +- 必须通过所有 CI 检查(`make check`)。 +- 必须符合 Go 惯用写法,并与现有代码库的风格保持一致。 +- 不得引入不必要的抽象、死代码或过度设计。 +- 须在适当的地方包含或更新测试。 + +### 安全审查 + +AI 生成的代码需要格外仔细的安全审查。请特别关注以下方面: + +- 文件路径处理与沙箱逃逸(项目历史中的 commit `244eb0b` 就是真实案例) +- channel 处理器和 tool 实现中的外部输入校验 +- 凭据或密钥的处理 +- 命令执行(`exec.Command`、shell 调用等) + +如果你不确定某段 AI 生成代码是否安全,请在 PR 中说明——审查者会帮助判断。 + +--- + +## Pull Request 流程 + +### 提 PR 前的检查 + +- [ ] 在本地运行 `make check` 并确认通过。 +- [ ] 完整填写 PR 模板,包括 AI 披露部分。 +- [ ] 在 PR 描述中关联相关 Issue。 +- [ ] 保持 PR 专注,避免将不相关的修改混在一起。 + +### PR 模板各部分说明 + +PR 模板要求填写: + +- **描述** — 这个改动做了什么,为什么要做? +- **变更类型** — Bug 修复、新功能、文档或重构。 +- **AI 代码生成** — AI 参与情况披露(必填)。 +- **关联 Issue** — 此 PR 解决的 Issue 链接。 +- **技术背景** — 参考链接和设计理由(纯文档类 PR 可跳过)。 +- **测试环境** — 用于测试的硬件、操作系统、模型/提供商和渠道。 +- **验证证据** — 可选的日志或截图,用于证明改动有效。 +- **检查清单** — 自我审查确认。 + +### PR 规模 + +请尽量提交小而易于审查的 PR。一个涉及 5 个文件共 200 行改动的 PR,远比涉及 30 个文件共 2000 行改动的 PR 容易审查。如果你的功能较大,可以考虑将其拆分为一系列逻辑完整的小 PR。 + +--- + +## 分支策略 + +### 长期分支 + +- **`main`** — 活跃开发分支。所有功能 PR 均以 `main` 为目标。该分支受保护:禁止直接推送,合并前必须获得至少一名维护者的批准。 +- **`release/x.y`** — 稳定发布分支,在某个版本准备发布时从 `main` 切出。这些分支的保护级别高于 `main`。 + +### 合并到 `main` 的前提条件 + +PR 必须同时满足以下所有条件,才能被合并: + +1. **CI 全部通过** — 所有 GitHub Actions 工作流(lint、test、build)均为绿色。 +2. **获得审查者批准** — 至少一名维护者已批准该 PR。 +3. **无未解决的审查意见** — 所有审查讨论线程均已关闭。 +4. **PR 模板填写完整** — 包括 AI 披露和测试环境信息。 + +### 谁可以合并 + +只有维护者才能合并 PR。贡献者不能合并自己的 PR,即使拥有写权限也不行。 + +### 合并策略 + +为保持 `main` 历史清晰可读,我们对大多数 PR 使用 **Squash Merge**。每个合并的 PR 变为一个包含 PR 编号的单独 commit,例如: + +``` +feat: Add Ollama provider support (#491) +``` + +如果一个 PR 包含多个独立、结构清晰、能讲述完整故事的 commit,维护者可视情况使用普通 merge。 + +### Release 分支 + +当某个版本准备就绪时,维护者会从 `main` 切出 `release/x.y` 分支。此后: + +- **新功能不会被回溯(backport)。** Release 分支切出后,不再接收任何新功能。 +- **安全修复和关键 Bug 修复会被 cherry-pick 进来。** 若 `main` 上的某个修复属于安全漏洞、数据丢失或崩溃类问题,维护者会将相关 commit cherry-pick 到受影响的 `release/x.y` 分支,并发布补丁版本。 + +如果你认为 `main` 上的某个修复应该被回溯到某个 release 分支,请在 PR 描述中注明,或单独开一个 Issue 说明。最终决定由维护者做出。 + +Release 分支的保护级别高于 `main`,在任何情况下均不允许直接推送。 + +--- + +## 代码审查 + +### 对贡献者的建议 + +- 在合理时间内回复审查意见。如果需要更多时间,请告知。 +- 更新 PR 以响应反馈时,简要说明改动内容(例如:"按建议改用了 `sync.RWMutex`")。 +- 如果你不同意某条反馈,请礼貌地阐述你的理由——审查者也可能有判断失误的时候。 +- 审查开始后请不要 force push——这会让审查者难以追踪变化。请使用额外的 commit,维护者在合并时会进行 squash。 + +### 对审查者的建议 + +审查重点: + +1. **正确性** — 代码是否实现了其声称的功能?是否存在边界情况? +2. **安全性** — 对 AI 生成代码、tool 实现和 channel 处理器尤其需要关注。 +3. **架构** — 实现方式是否与现有设计一致? +4. **简洁性** — 是否有更简单的方案?是否引入了不必要的复杂度? +5. **测试** — 改动是否有测试覆盖?现有测试是否仍然有意义? + +请给出建设性且具体的反馈。"如果两个 goroutine 同时调用这个函数可能会有竞态条件,建议在这里加一个 mutex" 远比 "这里看起来有问题" 更有帮助。 + +### 审查者列表 +提交对应PR后,可以参考下表联系对应的审查人员沟通 + +|Function| Reviewer| +|--- |--- | +|Provider|@yinwm | +|Channel |@yinwm | +|Agent |@lxowalle| +|Tools |@lxowalle| +|SKill || +|MCP || +|Optimization|@lxowalle| +|Security|| +|AI CI |@imguoguo| +|UX || +|Document|| + + + +--- + +## 沟通渠道 + +- **GitHub Issues** — Bug 报告、功能建议、设计讨论。 +- **GitHub Discussions** — 一般性问题、想法交流、社区讨论。 +- **Pull Request 评论** — 与具体代码相关的反馈。 +- **Wechat&Discord** — 当你有至少一个已合并的PR后,我们会邀请你加入开发者交流群 + +有疑问时,请先开 Issue 讨论,再动手写代码。这几乎没有成本,却能避免大量无效投入。 + +--- + +## 关于本项目的 AI 驱动起源 + +PicoClaw 的架构在人工监督下,经由 AI 辅助完成了大量设计和实现工作。如果你发现某处看起来奇怪或过度设计,这可能是该过程留下的痕迹——欢迎提 Issue 讨论。 + +我们相信,负责任地使用 AI 辅助开发能产生优秀的成果。我们同样相信,人类必须对自己提交的内容负责。这两点并不矛盾。 + +感谢你的贡献! diff --git a/assets/wechat.png b/assets/wechat.png index 8fc41ea7d53cfc9e0ccb7b6fe5a4fd6d079cee7c..a34217c335542a13aace2103bd15ccebf94acde2 100644 GIT binary patch literal 144045 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 - [中文](README.zh.md) | [日本語](README.ja.md) | [Português](README.pt-br.md) | [Tiếng Việt](README.vi.md) | [Français](README.fr.md) | **English** +[中文](README.zh.md) | [日本語](README.ja.md) | [Português](README.pt-br.md) | [Tiếng Việt](README.vi.md) | [Français](README.fr.md) | **English** + --- @@ -42,16 +43,17 @@ > **🚨 SECURITY & OFFICIAL CHANNELS / 安全声明** > > * **NO CRYPTO:** PicoClaw has **NO** official token/coin. All claims on `pump.fun` or other trading platforms are **SCAMS**. +> > * **OFFICIAL DOMAIN:** The **ONLY** official website is **[picoclaw.io](https://picoclaw.io)**, and company website is **[sipeed.com](https://sipeed.com)** > * **Warning:** Many `.ai/.org/.com/.net/...` domains are registered by third parties. > * **Warning:** picoclaw is in early development now and may have unresolved network security issues. Do not deploy to production environments before the v1.0 release. > * **Note:** picoclaw has recently merged a lot of PRs, which may result in a larger memory footprint (10–20MB) in the latest versions. We plan to prioritize resource optimization as soon as the current feature set reaches a stable state. - ## 📢 News + 2026-02-16 🎉 PicoClaw hit 12K stars in one week! Thank you all for your support! PicoClaw is growing faster than we ever imagined. Given the high volume of PRs, we urgently need community maintainers. Our volunteer roles and roadmap are officially posted [here](docs/picoclaw_community_roadmap_260216.md) —we can’t wait to have you on board! -2026-02-13 🎉 PicoClaw hit 5000 stars in 4days! Thank you for the community! There are so many PRs&issues come in (during Chinese New Year holidays), we are finalizing the Project Roadmap and setting up the Developer Group to accelerate PicoClaw's development. +2026-02-13 🎉 PicoClaw hit 5000 stars in 4days! Thank you for the community! There are so many PRs & issues coming in (during Chinese New Year holidays), we are finalizing the Project Roadmap and setting up the Developer Group to accelerate PicoClaw's development. 🚀 Call to Action: Please submit your feature requests in GitHub Discussions. We will review and prioritize them during our upcoming weekly meeting. 2026-02-09 🎉 PicoClaw Launched! Built in 1 day to bring AI Agents to $10 hardware with <10MB RAM. 🦐 PicoClaw,Let's Go! @@ -100,9 +102,12 @@ ### 📱 Run on old Android Phones + Give your decade-old phone a second life! Turn it into a smart AI Assistant with PicoClaw. Quick Start: + 1. **Install Termux** (Available on F-Droid or Google Play). 2. **Execute cmds** + ```bash # Note: Replace v0.1.1 with the latest version from the Releases page wget https://github.com/sipeed/picoclaw/releases/download/v0.1.1/picoclaw-linux-arm64 @@ -110,6 +115,7 @@ chmod +x picoclaw-linux-arm64 pkg install proot termux-chroot ./picoclaw-linux-arm64 onboard ``` + And then follow the instructions in the "Quick Start" section to complete the configuration! PicoClaw @@ -323,7 +329,6 @@ picoclaw gateway * (Optional) Enable **SERVER MEMBERS INTENT** if you plan to use allow lists based on member data **3. Get your User ID** - * Discord Settings → Advanced → enable **Developer Mode** * Right-click your avatar → **Copy User ID** @@ -425,7 +430,6 @@ picoclaw gateway ```bash picoclaw gateway ``` -
@@ -521,7 +525,6 @@ See [WeCom App Configuration Guide](docs/wecom-app-configuration.md) for detaile * Go to WeCom Admin Console → App Management → Create App * Copy **AgentId** and **Secret** * Go to "My Company" page, copy **CorpID** - **2. Configure receive message** * In App details, click "Receive Message" → "Set API" @@ -605,23 +608,23 @@ PicoClaw runs in a sandboxed environment by default. The agent can only access f } ``` -| Option | Default | Description | -|--------|---------|-------------| -| `workspace` | `~/.picoclaw/workspace` | Working directory for the agent | -| `restrict_to_workspace` | `true` | Restrict file/command access to workspace | +| Option | Default | Description | +| ----------------------- | ----------------------- | ----------------------------------------- | +| `workspace` | `~/.picoclaw/workspace` | Working directory for the agent | +| `restrict_to_workspace` | `true` | Restrict file/command access to workspace | #### Protected Tools When `restrict_to_workspace: true`, the following tools are sandboxed: -| Tool | Function | Restriction | -|------|----------|-------------| -| `read_file` | Read files | Only files within workspace | -| `write_file` | Write files | Only files within workspace | -| `list_dir` | List directories | Only directories within workspace | -| `edit_file` | Edit files | Only files within workspace | -| `append_file` | Append to files | Only files within workspace | -| `exec` | Execute commands | Command paths must be within workspace | +| Tool | Function | Restriction | +| ------------- | ---------------- | -------------------------------------- | +| `read_file` | Read files | Only files within workspace | +| `write_file` | Write files | Only files within workspace | +| `list_dir` | List directories | Only directories within workspace | +| `edit_file` | Edit files | Only files within workspace | +| `append_file` | Append to files | Only files within workspace | +| `exec` | Execute commands | Command paths must be within workspace | #### Additional Exec Protection @@ -674,11 +677,11 @@ export PICOCLAW_AGENTS_DEFAULTS_RESTRICT_TO_WORKSPACE=false The `restrict_to_workspace` setting applies consistently across all execution paths: -| Execution Path | Security Boundary | -|----------------|-------------------| -| Main Agent | `restrict_to_workspace` ✅ | +| Execution Path | Security Boundary | +| ---------------- | ---------------------------- | +| Main Agent | `restrict_to_workspace` ✅ | | Subagent / Spawn | Inherits same restriction ✅ | -| Heartbeat tasks | Inherits same restriction ✅ | +| Heartbeat tasks | Inherits same restriction ✅ | All paths share the same workspace restriction — there's no way to bypass the security boundary through subagents or scheduled tasks. @@ -704,21 +707,23 @@ For long-running tasks (web search, API calls), use the `spawn` tool to create a # Periodic Tasks ## Quick Tasks (respond directly) + - Report current time ## Long Tasks (use spawn for async) + - Search the web for AI news and summarize - Check email and report important messages ``` **Key behaviors:** -| Feature | Description | -|---------|-------------| -| **spawn** | Creates async subagent, doesn't block heartbeat | -| **Independent context** | Subagent has its own context, no session history | -| **message tool** | Subagent communicates with user directly via message tool | -| **Non-blocking** | After spawning, heartbeat continues to next task | +| Feature | Description | +| ----------------------- | --------------------------------------------------------- | +| **spawn** | Creates async subagent, doesn't block heartbeat | +| **Independent context** | Subagent has its own context, no session history | +| **message tool** | Subagent communicates with user directly via message tool | +| **Non-blocking** | After spawning, heartbeat continues to next task | #### How Subagent Communication Works @@ -749,10 +754,10 @@ The subagent has access to tools (message, web_search, etc.) and can communicate } ``` -| Option | Default | Description | -|--------|---------|-------------| -| `enabled` | `true` | Enable/disable heartbeat | -| `interval` | `30` | Check interval in minutes (min: 5) | +| Option | Default | Description | +| ---------- | ------- | ---------------------------------- | +| `enabled` | `true` | Enable/disable heartbeat | +| `interval` | `30` | Check interval in minutes (min: 5) | **Environment variables:** @@ -764,17 +769,17 @@ The subagent has access to tools (message, web_search, etc.) and can communicate > [!NOTE] > Groq provides free voice transcription via Whisper. If configured, Telegram voice messages will be automatically transcribed. -| Provider | Purpose | Get API Key | -| -------------------------- | --------------------------------------- | ------------------------------------------------------ | -| `gemini` | LLM (Gemini direct) | [aistudio.google.com](https://aistudio.google.com) | -| `zhipu` | LLM (Zhipu direct) | [bigmodel.cn](bigmodel.cn) | -| `openrouter(To be tested)` | LLM (recommended, access to all models) | [openrouter.ai](https://openrouter.ai) | -| `anthropic(To be tested)` | LLM (Claude direct) | [console.anthropic.com](https://console.anthropic.com) | -| `openai(To be tested)` | LLM (GPT direct) | [platform.openai.com](https://platform.openai.com) | -| `deepseek(To be tested)` | LLM (DeepSeek direct) | [platform.deepseek.com](https://platform.deepseek.com) | +| Provider | Purpose | Get API Key | +| -------------------------- | --------------------------------------- | -------------------------------------------------------------------- | +| `gemini` | LLM (Gemini direct) | [aistudio.google.com](https://aistudio.google.com) | +| `zhipu` | LLM (Zhipu direct) | [bigmodel.cn](https://bigmodel.cn) | +| `openrouter(To be tested)` | LLM (recommended, access to all models) | [openrouter.ai](https://openrouter.ai) | +| `anthropic(To be tested)` | LLM (Claude direct) | [console.anthropic.com](https://console.anthropic.com) | +| `openai(To be tested)` | LLM (GPT direct) | [platform.openai.com](https://platform.openai.com) | +| `deepseek(To be tested)` | LLM (DeepSeek direct) | [platform.deepseek.com](https://platform.deepseek.com) | | `qwen` | LLM (Qwen direct) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) | -| `groq` | LLM + **Voice transcription** (Whisper) | [console.groq.com](https://console.groq.com) | -| `cerebras` | LLM (Cerebras direct) | [cerebras.ai](https://cerebras.ai) | +| `groq` | LLM + **Voice transcription** (Whisper) | [console.groq.com](https://console.groq.com) | +| `cerebras` | LLM (Cerebras direct) | [cerebras.ai](https://cerebras.ai) | ### Model Configuration (model_list) @@ -789,25 +794,25 @@ This design also enables **multi-agent support** with flexible provider selectio #### 📋 All Supported Vendors -| Vendor | `model` Prefix | Default API Base | Protocol | API Key | -|--------|----------------|------------------|----------|---------| -| **OpenAI** | `openai/` | `https://api.openai.com/v1` | OpenAI | [Get Key](https://platform.openai.com) | -| **Anthropic** | `anthropic/` | `https://api.anthropic.com/v1` | Anthropic | [Get Key](https://console.anthropic.com) | -| **智谱 AI (GLM)** | `zhipu/` | `https://open.bigmodel.cn/api/paas/v4` | OpenAI | [Get Key](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) | -| **DeepSeek** | `deepseek/` | `https://api.deepseek.com/v1` | OpenAI | [Get Key](https://platform.deepseek.com) | -| **Google Gemini** | `gemini/` | `https://generativelanguage.googleapis.com/v1beta` | OpenAI | [Get Key](https://aistudio.google.com/api-keys) | -| **Groq** | `groq/` | `https://api.groq.com/openai/v1` | OpenAI | [Get Key](https://console.groq.com) | -| **Moonshot** | `moonshot/` | `https://api.moonshot.cn/v1` | OpenAI | [Get Key](https://platform.moonshot.cn) | -| **通义千问 (Qwen)** | `qwen/` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI | [Get Key](https://dashscope.console.aliyun.com) | -| **NVIDIA** | `nvidia/` | `https://integrate.api.nvidia.com/v1` | OpenAI | [Get Key](https://build.nvidia.com) | -| **Ollama** | `ollama/` | `http://localhost:11434/v1` | OpenAI | Local (no key needed) | -| **OpenRouter** | `openrouter/` | `https://openrouter.ai/api/v1` | OpenAI | [Get Key](https://openrouter.ai/keys) | -| **VLLM** | `vllm/` | `http://localhost:8000/v1` | OpenAI | Local | -| **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [Get Key](https://cerebras.ai) | -| **火山引擎** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [Get Key](https://console.volcengine.com) | -| **神算云** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - | -| **Antigravity** | `antigravity/` | Google Cloud | Custom | OAuth only | -| **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - | +| Vendor | `model` Prefix | Default API Base | Protocol | API Key | +| ------------------- | ----------------- | --------------------------------------------------- | --------- | ---------------------------------------------------------------- | +| **OpenAI** | `openai/` | `https://api.openai.com/v1` | OpenAI | [Get Key](https://platform.openai.com) | +| **Anthropic** | `anthropic/` | `https://api.anthropic.com/v1` | Anthropic | [Get Key](https://console.anthropic.com) | +| **智谱 AI (GLM)** | `zhipu/` | `https://open.bigmodel.cn/api/paas/v4` | OpenAI | [Get Key](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) | +| **DeepSeek** | `deepseek/` | `https://api.deepseek.com/v1` | OpenAI | [Get Key](https://platform.deepseek.com) | +| **Google Gemini** | `gemini/` | `https://generativelanguage.googleapis.com/v1beta` | OpenAI | [Get Key](https://aistudio.google.com/api-keys) | +| **Groq** | `groq/` | `https://api.groq.com/openai/v1` | OpenAI | [Get Key](https://console.groq.com) | +| **Moonshot** | `moonshot/` | `https://api.moonshot.cn/v1` | OpenAI | [Get Key](https://platform.moonshot.cn) | +| **通义千问 (Qwen)** | `qwen/` | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI | [Get Key](https://dashscope.console.aliyun.com) | +| **NVIDIA** | `nvidia/` | `https://integrate.api.nvidia.com/v1` | OpenAI | [Get Key](https://build.nvidia.com) | +| **Ollama** | `ollama/` | `http://localhost:11434/v1` | OpenAI | Local (no key needed) | +| **OpenRouter** | `openrouter/` | `https://openrouter.ai/api/v1` | OpenAI | [Get Key](https://openrouter.ai/keys) | +| **VLLM** | `vllm/` | `http://localhost:8000/v1` | OpenAI | Local | +| **Cerebras** | `cerebras/` | `https://api.cerebras.ai/v1` | OpenAI | [Get Key](https://cerebras.ai) | +| **火山引擎** | `volcengine/` | `https://ark.cn-beijing.volces.com/api/v3` | OpenAI | [Get Key](https://console.volcengine.com) | +| **神算云** | `shengsuanyun/` | `https://router.shengsuanyun.com/api/v1` | OpenAI | - | +| **Antigravity** | `antigravity/` | Google Cloud | Custom | OAuth only | +| **GitHub Copilot** | `github-copilot/` | `localhost:4321` | gRPC | - | #### Basic Configuration @@ -841,6 +846,7 @@ This design also enables **multi-agent support** with flexible provider selectio #### Vendor-Specific Examples **OpenAI** + ```json { "model_name": "gpt-5.2", @@ -850,6 +856,7 @@ This design also enables **multi-agent support** with flexible provider selectio ``` **智谱 AI (GLM)** + ```json { "model_name": "glm-4.7", @@ -859,6 +866,7 @@ This design also enables **multi-agent support** with flexible provider selectio ``` **DeepSeek** + ```json { "model_name": "deepseek-chat", @@ -868,6 +876,7 @@ This design also enables **multi-agent support** with flexible provider selectio ``` **Anthropic (with API key)** + ```json { "model_name": "claude-sonnet-4.6", @@ -875,9 +884,11 @@ This design also enables **multi-agent support** with flexible provider selectio "api_key": "sk-ant-your-key" } ``` + > Run `picoclaw auth login --provider anthropic` to paste your API token. **Ollama (local)** + ```json { "model_name": "llama3", @@ -886,6 +897,7 @@ This design also enables **multi-agent support** with flexible provider selectio ``` **Custom Proxy/API** + ```json { "model_name": "my-custom-model", @@ -923,6 +935,7 @@ Configure multiple endpoints for the same model name—PicoClaw will automatical The old `providers` configuration is **deprecated** but still supported for backward compatibility. **Old Config (deprecated):** + ```json { "providers": { @@ -941,6 +954,7 @@ The old `providers` configuration is **deprecated** but still supported for back ``` **New Config (recommended):** + ```json { "model_list": [ @@ -1105,13 +1119,13 @@ Jobs are stored in `~/.picoclaw/workspace/cron/` and processed automatically. PRs welcome! The codebase is intentionally small and readable. 🤗 -Roadmap coming soon... +See our full [Community Roadmap](https://github.com/sipeed/picoclaw/blob/main/ROADMAP.md). -Developer group building, Entry Requirement: At least 1 Merged PR. +Developer group building, join after your first merged PR! User Groups: -discord: +discord: PicoClaw From cb0c8703fb9d5ce373bc0c4f770177ba66508b25 Mon Sep 17 00:00:00 2001 From: King Tai <109292982+CrisisAlpha@users.noreply.github.com> Date: Sun, 22 Feb 2026 18:40:59 +0800 Subject: [PATCH 17/40] test(tools,utils): add ToolRegistry unit tests and fix Truncate panic on negative maxLen (#517) Add comprehensive unit tests for the ToolRegistry covering registration, lookup, execution, context injection, async callbacks, schema generation, provider definition conversion, and concurrent access. Fix a defensive edge case in Truncate where a negative maxLen would cause a slice bounds panic, and add table-driven tests covering boundary conditions, zero/negative lengths, and Unicode handling. Co-authored-by: Cursor --- pkg/tools/registry_test.go | 350 +++++++++++++++++++++++++++++++++++++ pkg/utils/string.go | 3 + pkg/utils/string_test.go | 106 +++++++++++ 3 files changed, 459 insertions(+) create mode 100644 pkg/tools/registry_test.go create mode 100644 pkg/utils/string_test.go diff --git a/pkg/tools/registry_test.go b/pkg/tools/registry_test.go new file mode 100644 index 000000000..33978e543 --- /dev/null +++ b/pkg/tools/registry_test.go @@ -0,0 +1,350 @@ +package tools + +import ( + "context" + "strings" + "sync" + "testing" + + "github.com/sipeed/picoclaw/pkg/providers" +) + +// --- mock types --- + +type mockRegistryTool struct { + name string + desc string + params map[string]interface{} + result *ToolResult +} + +func (m *mockRegistryTool) Name() string { return m.name } +func (m *mockRegistryTool) Description() string { return m.desc } +func (m *mockRegistryTool) Parameters() map[string]interface{} { return m.params } +func (m *mockRegistryTool) Execute(_ context.Context, _ map[string]interface{}) *ToolResult { + return m.result +} + +type mockCtxTool struct { + mockRegistryTool + channel string + chatID string +} + +func (m *mockCtxTool) SetContext(channel, chatID string) { + m.channel = channel + m.chatID = chatID +} + +type mockAsyncRegistryTool struct { + mockRegistryTool + cb AsyncCallback +} + +func (m *mockAsyncRegistryTool) SetCallback(cb AsyncCallback) { + m.cb = cb +} + +// --- helpers --- + +func newMockTool(name, desc string) *mockRegistryTool { + return &mockRegistryTool{ + name: name, + desc: desc, + params: map[string]interface{}{"type": "object"}, + result: SilentResult("ok"), + } +} + +// --- tests --- + +func TestNewToolRegistry(t *testing.T) { + r := NewToolRegistry() + if r.Count() != 0 { + t.Errorf("expected empty registry, got count %d", r.Count()) + } + if len(r.List()) != 0 { + t.Errorf("expected empty list, got %v", r.List()) + } +} + +func TestToolRegistry_RegisterAndGet(t *testing.T) { + r := NewToolRegistry() + tool := newMockTool("echo", "echoes input") + r.Register(tool) + + got, ok := r.Get("echo") + if !ok { + t.Fatal("expected to find registered tool") + } + if got.Name() != "echo" { + t.Errorf("expected name 'echo', got %q", got.Name()) + } +} + +func TestToolRegistry_Get_NotFound(t *testing.T) { + r := NewToolRegistry() + _, ok := r.Get("nonexistent") + if ok { + t.Error("expected ok=false for unregistered tool") + } +} + +func TestToolRegistry_RegisterOverwrite(t *testing.T) { + r := NewToolRegistry() + r.Register(newMockTool("dup", "first")) + r.Register(newMockTool("dup", "second")) + + if r.Count() != 1 { + t.Errorf("expected count 1 after overwrite, got %d", r.Count()) + } + tool, _ := r.Get("dup") + if tool.Description() != "second" { + t.Errorf("expected overwritten description 'second', got %q", tool.Description()) + } +} + +func TestToolRegistry_Execute_Success(t *testing.T) { + r := NewToolRegistry() + r.Register(&mockRegistryTool{ + name: "greet", + desc: "says hello", + params: map[string]interface{}{}, + result: SilentResult("hello"), + }) + + result := r.Execute(context.Background(), "greet", nil) + if result.IsError { + t.Errorf("expected success, got error: %s", result.ForLLM) + } + if result.ForLLM != "hello" { + t.Errorf("expected ForLLM 'hello', got %q", result.ForLLM) + } +} + +func TestToolRegistry_Execute_NotFound(t *testing.T) { + r := NewToolRegistry() + result := r.Execute(context.Background(), "missing", nil) + if !result.IsError { + t.Error("expected error for missing tool") + } + if !strings.Contains(result.ForLLM, "not found") { + t.Errorf("expected 'not found' in error, got %q", result.ForLLM) + } + if result.Err == nil { + t.Error("expected Err to be set via WithError") + } +} + +func TestToolRegistry_ExecuteWithContext_ContextualTool(t *testing.T) { + r := NewToolRegistry() + ct := &mockCtxTool{ + mockRegistryTool: *newMockTool("ctx_tool", "needs context"), + } + r.Register(ct) + + r.ExecuteWithContext(context.Background(), "ctx_tool", nil, "telegram", "chat-42", nil) + + if ct.channel != "telegram" { + t.Errorf("expected channel 'telegram', got %q", ct.channel) + } + if ct.chatID != "chat-42" { + t.Errorf("expected chatID 'chat-42', got %q", ct.chatID) + } +} + +func TestToolRegistry_ExecuteWithContext_SkipsEmptyContext(t *testing.T) { + r := NewToolRegistry() + ct := &mockCtxTool{ + mockRegistryTool: *newMockTool("ctx_tool", "needs context"), + } + r.Register(ct) + + r.ExecuteWithContext(context.Background(), "ctx_tool", nil, "", "", nil) + + if ct.channel != "" || ct.chatID != "" { + t.Error("SetContext should not be called with empty channel/chatID") + } +} + +func TestToolRegistry_ExecuteWithContext_AsyncCallback(t *testing.T) { + r := NewToolRegistry() + at := &mockAsyncRegistryTool{ + mockRegistryTool: *newMockTool("async_tool", "async work"), + } + at.result = AsyncResult("started") + r.Register(at) + + called := false + cb := func(_ context.Context, _ *ToolResult) { called = true } + + result := r.ExecuteWithContext(context.Background(), "async_tool", nil, "", "", cb) + if at.cb == nil { + t.Error("expected SetCallback to have been called") + } + if !result.Async { + t.Error("expected async result") + } + + at.cb(context.Background(), SilentResult("done")) + if !called { + t.Error("expected callback to be invoked") + } +} + +func TestToolRegistry_GetDefinitions(t *testing.T) { + r := NewToolRegistry() + r.Register(newMockTool("alpha", "tool A")) + + defs := r.GetDefinitions() + if len(defs) != 1 { + t.Fatalf("expected 1 definition, got %d", len(defs)) + } + if defs[0]["type"] != "function" { + t.Errorf("expected type 'function', got %v", defs[0]["type"]) + } + fn, ok := defs[0]["function"].(map[string]interface{}) + if !ok { + t.Fatal("expected 'function' key to be a map") + } + if fn["name"] != "alpha" { + t.Errorf("expected name 'alpha', got %v", fn["name"]) + } + if fn["description"] != "tool A" { + t.Errorf("expected description 'tool A', got %v", fn["description"]) + } +} + +func TestToolRegistry_ToProviderDefs(t *testing.T) { + r := NewToolRegistry() + params := map[string]interface{}{"type": "object", "properties": map[string]interface{}{}} + r.Register(&mockRegistryTool{ + name: "beta", + desc: "tool B", + params: params, + result: SilentResult("ok"), + }) + + defs := r.ToProviderDefs() + if len(defs) != 1 { + t.Fatalf("expected 1 provider def, got %d", len(defs)) + } + + want := providers.ToolDefinition{ + Type: "function", + Function: providers.ToolFunctionDefinition{ + Name: "beta", + Description: "tool B", + Parameters: params, + }, + } + got := defs[0] + if got.Type != want.Type { + t.Errorf("Type: want %q, got %q", want.Type, got.Type) + } + if got.Function.Name != want.Function.Name { + t.Errorf("Name: want %q, got %q", want.Function.Name, got.Function.Name) + } + if got.Function.Description != want.Function.Description { + t.Errorf("Description: want %q, got %q", want.Function.Description, got.Function.Description) + } +} + +func TestToolRegistry_List(t *testing.T) { + r := NewToolRegistry() + r.Register(newMockTool("x", "")) + r.Register(newMockTool("y", "")) + + names := r.List() + if len(names) != 2 { + t.Fatalf("expected 2 names, got %d", len(names)) + } + + nameSet := map[string]bool{} + for _, n := range names { + nameSet[n] = true + } + if !nameSet["x"] || !nameSet["y"] { + t.Errorf("expected names {x, y}, got %v", names) + } +} + +func TestToolRegistry_Count(t *testing.T) { + r := NewToolRegistry() + if r.Count() != 0 { + t.Errorf("expected 0, got %d", r.Count()) + } + + r.Register(newMockTool("a", "")) + r.Register(newMockTool("b", "")) + if r.Count() != 2 { + t.Errorf("expected 2, got %d", r.Count()) + } + + r.Register(newMockTool("a", "replaced")) + if r.Count() != 2 { + t.Errorf("expected 2 after overwrite, got %d", r.Count()) + } +} + +func TestToolRegistry_GetSummaries(t *testing.T) { + r := NewToolRegistry() + r.Register(newMockTool("read_file", "Reads a file")) + + summaries := r.GetSummaries() + if len(summaries) != 1 { + t.Fatalf("expected 1 summary, got %d", len(summaries)) + } + if !strings.Contains(summaries[0], "`read_file`") { + t.Errorf("expected backtick-quoted name in summary, got %q", summaries[0]) + } + if !strings.Contains(summaries[0], "Reads a file") { + t.Errorf("expected description in summary, got %q", summaries[0]) + } +} + +func TestToolToSchema(t *testing.T) { + tool := newMockTool("demo", "demo tool") + schema := ToolToSchema(tool) + + if schema["type"] != "function" { + t.Errorf("expected type 'function', got %v", schema["type"]) + } + fn, ok := schema["function"].(map[string]interface{}) + if !ok { + t.Fatal("expected 'function' to be a map") + } + if fn["name"] != "demo" { + t.Errorf("expected name 'demo', got %v", fn["name"]) + } + if fn["description"] != "demo tool" { + t.Errorf("expected description 'demo tool', got %v", fn["description"]) + } + if fn["parameters"] == nil { + t.Error("expected parameters to be set") + } +} + +func TestToolRegistry_ConcurrentAccess(t *testing.T) { + r := NewToolRegistry() + var wg sync.WaitGroup + + for i := 0; i < 50; i++ { + wg.Add(1) + go func(n int) { + defer wg.Done() + name := string(rune('A' + n%26)) + r.Register(newMockTool(name, "concurrent")) + r.Get(name) + r.Count() + r.List() + r.GetDefinitions() + }(i) + } + + wg.Wait() + + if r.Count() == 0 { + t.Error("expected tools to be registered after concurrent access") + } +} diff --git a/pkg/utils/string.go b/pkg/utils/string.go index 7a6aa37cc..62d9beee0 100644 --- a/pkg/utils/string.go +++ b/pkg/utils/string.go @@ -4,6 +4,9 @@ package utils // Handles multi-byte Unicode characters properly. // If the string is truncated, "..." is appended to indicate truncation. func Truncate(s string, maxLen int) string { + if maxLen <= 0 { + return "" + } runes := []rune(s) if len(runes) <= maxLen { return s diff --git a/pkg/utils/string_test.go b/pkg/utils/string_test.go new file mode 100644 index 000000000..a44ead228 --- /dev/null +++ b/pkg/utils/string_test.go @@ -0,0 +1,106 @@ +package utils + +import "testing" + +func TestTruncate(t *testing.T) { + tests := []struct { + name string + input string + maxLen int + want string + }{ + { + name: "short string unchanged", + input: "hi", + maxLen: 10, + want: "hi", + }, + { + name: "exact length unchanged", + input: "hello", + maxLen: 5, + want: "hello", + }, + { + name: "long string truncated with ellipsis", + input: "hello world", + maxLen: 8, + want: "hello...", + }, + { + name: "maxLen equals 4 leaves 1 char plus ellipsis", + input: "abcdef", + maxLen: 4, + want: "a...", + }, + { + name: "maxLen 3 returns first 3 chars without ellipsis", + input: "abcdef", + maxLen: 3, + want: "abc", + }, + { + name: "maxLen 2 returns first 2 chars", + input: "abcdef", + maxLen: 2, + want: "ab", + }, + { + name: "maxLen 1 returns first char", + input: "abcdef", + maxLen: 1, + want: "a", + }, + { + name: "maxLen 0 returns empty", + input: "hello", + maxLen: 0, + want: "", + }, + { + name: "negative maxLen returns empty", + input: "hello", + maxLen: -1, + want: "", + }, + { + name: "empty string unchanged", + input: "", + maxLen: 5, + want: "", + }, + { + name: "empty string with zero maxLen", + input: "", + maxLen: 0, + want: "", + }, + { + name: "unicode truncated correctly", + input: "\U0001f600\U0001f601\U0001f602\U0001f603\U0001f604", + maxLen: 4, + want: "\U0001f600...", + }, + { + name: "unicode short enough", + input: "\u00e9\u00e8", + maxLen: 5, + want: "\u00e9\u00e8", + }, + { + name: "mixed ascii and unicode", + input: "Go\U0001f680\U0001f525\U0001f4a5\U0001f30d", + maxLen: 5, + want: "Go...", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := Truncate(tt.input, tt.maxLen) + if got != tt.want { + t.Errorf("Truncate(%q, %d) = %q, want %q", tt.input, tt.maxLen, got, tt.want) + } + }) + } +} From a849e02917e6c3c6a52a0e2c27e19552cc91f88d Mon Sep 17 00:00:00 2001 From: Lixeer <1612655510@qq.com> Date: Sun, 22 Feb 2026 22:30:53 +0800 Subject: [PATCH 18/40] fix: better session management for `github_copilot_provider` --- cmd/picoclaw/cmd_gateway.go | 3 + pkg/providers/github_copilot_provider.go | 74 ++++++++++++++++-------- pkg/providers/types.go | 5 ++ 3 files changed, 59 insertions(+), 23 deletions(-) diff --git a/cmd/picoclaw/cmd_gateway.go b/cmd/picoclaw/cmd_gateway.go index 28ef76ad3..30d61aec3 100644 --- a/cmd/picoclaw/cmd_gateway.go +++ b/cmd/picoclaw/cmd_gateway.go @@ -212,6 +212,9 @@ func gatewayCmd() { fmt.Println("\nShutting down...") cancel() + if cp, ok := provider.(providers.SessionProvider); ok { + cp.Close() + } healthServer.Stop(context.Background()) deviceService.Stop() heartbeatService.Stop() diff --git a/pkg/providers/github_copilot_provider.go b/pkg/providers/github_copilot_provider.go index 6124881f7..8131b76fc 100644 --- a/pkg/providers/github_copilot_provider.go +++ b/pkg/providers/github_copilot_provider.go @@ -4,60 +4,75 @@ import ( "context" "encoding/json" "fmt" + "sync" copilot "github.com/github/copilot-sdk/go" ) type GitHubCopilotProvider struct { uri string - connectMode string // `stdio` or `grpc`` + connectMode string // "stdio" or "grpc" + client *copilot.Client session *copilot.Session + + mu sync.Mutex } func NewGitHubCopilotProvider(uri string, connectMode string, model string) (*GitHubCopilotProvider, error) { - var session *copilot.Session if connectMode == "" { connectMode = "grpc" } - switch connectMode { + switch connectMode { case "stdio": - // todo + // TODO: + return nil, fmt.Errorf("stdio mode not implemented") case "grpc": client := copilot.NewClient(&copilot.ClientOptions{ CLIUrl: uri, }) if err := client.Start(context.Background()); err != nil { - return nil, fmt.Errorf( - "Can't connect to Github Copilot, https://github.com/github/copilot-sdk/blob/main/docs/getting-started.md#connecting-to-an-external-cli-server for details", - ) + return nil, fmt.Errorf("can't connect to Github Copilot: %w; `https://github.com/github/copilot-sdk/blob/main/docs/getting-started.md#connecting-to-an-external-cli-server` for details", err) } - defer client.Stop() - session, _ = client.CreateSession(context.Background(), &copilot.SessionConfig{ + + session, err := client.CreateSession(context.Background(), &copilot.SessionConfig{ Model: model, Hooks: &copilot.SessionHooks{}, }) + if err != nil { + client.Stop() + return nil, fmt.Errorf("create session failed: %w", err) + } + + return &GitHubCopilotProvider{ + uri: uri, + connectMode: connectMode, + client: client, + session: session, + }, nil + default: + return nil, fmt.Errorf("unknown connect mode: %s", connectMode) } - - return &GitHubCopilotProvider{ - uri: uri, - connectMode: connectMode, - session: session, - }, nil } -// Chat sends a chat request to GitHub Copilot -func (p *GitHubCopilotProvider) Chat( - ctx context.Context, messages []Message, tools []ToolDefinition, model string, options map[string]any, -) (*LLMResponse, error) { +func (p *GitHubCopilotProvider) Close() { + p.mu.Lock() + defer p.mu.Unlock() + if p.client != nil { + p.client.Stop() + p.client = nil + p.session = nil + } +} + +func (p *GitHubCopilotProvider) Chat(ctx context.Context, messages []Message, tools []ToolDefinition, model string, options map[string]interface{}) (*LLMResponse, error) { type tempMessage struct { Role string `json:"role"` Content string `json:"content"` } out := make([]tempMessage, 0, len(messages)) - for _, msg := range messages { out = append(out, tempMessage{ Role: msg.Role, @@ -65,18 +80,31 @@ func (p *GitHubCopilotProvider) Chat( }) } - fullcontent, _ := json.Marshal(out) + fullcontent, err := json.Marshal(out) + if err != nil { + return nil, fmt.Errorf("marshal messages: %w", err) + } + p.mu.Lock() + defer p.mu.Unlock() - content, _ := p.session.Send(ctx, copilot.MessageOptions{ + resp, err := p.session.SendAndWait(ctx, copilot.MessageOptions{ Prompt: string(fullcontent), }) + if err != nil { + return nil, err + } + + var content string + if resp != nil && resp.Data.Content != nil { + content = *resp.Data.Content + } return &LLMResponse{ FinishReason: "stop", Content: content, }, nil } - func (p *GitHubCopilotProvider) GetDefaultModel() string { + return "gpt-4.1" } diff --git a/pkg/providers/types.go b/pkg/providers/types.go index f711e7803..40ff6f7c8 100644 --- a/pkg/providers/types.go +++ b/pkg/providers/types.go @@ -30,6 +30,11 @@ type LLMProvider interface { GetDefaultModel() string } +type SessionProvider interface { + LLMProvider + Close() +} + // FailoverReason classifies why an LLM request failed for fallback decisions. type FailoverReason string From 3d605a4f537507713706aa626b74ad8506e6e12a Mon Sep 17 00:00:00 2001 From: Lixeer <1612655510@qq.com> Date: Sun, 22 Feb 2026 23:02:29 +0800 Subject: [PATCH 19/40] fix: run fmt and lint --- pkg/providers/github_copilot_provider.go | 15 ++++++++++++--- pkg/tools/registry_test.go | 20 ++++++++++---------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/pkg/providers/github_copilot_provider.go b/pkg/providers/github_copilot_provider.go index 8131b76fc..c69658b44 100644 --- a/pkg/providers/github_copilot_provider.go +++ b/pkg/providers/github_copilot_provider.go @@ -33,7 +33,10 @@ func NewGitHubCopilotProvider(uri string, connectMode string, model string) (*Gi CLIUrl: uri, }) if err := client.Start(context.Background()); err != nil { - return nil, fmt.Errorf("can't connect to Github Copilot: %w; `https://github.com/github/copilot-sdk/blob/main/docs/getting-started.md#connecting-to-an-external-cli-server` for details", err) + return nil, fmt.Errorf( + "can't connect to Github Copilot: %w; `https://github.com/github/copilot-sdk/blob/main/docs/getting-started.md#connecting-to-an-external-cli-server` for details", + err, + ) } session, err := client.CreateSession(context.Background(), &copilot.SessionConfig{ @@ -67,7 +70,13 @@ func (p *GitHubCopilotProvider) Close() { } } -func (p *GitHubCopilotProvider) Chat(ctx context.Context, messages []Message, tools []ToolDefinition, model string, options map[string]interface{}) (*LLMResponse, error) { +func (p *GitHubCopilotProvider) Chat( + ctx context.Context, + messages []Message, + tools []ToolDefinition, + model string, + options map[string]any, +) (*LLMResponse, error) { type tempMessage struct { Role string `json:"role"` Content string `json:"content"` @@ -104,7 +113,7 @@ func (p *GitHubCopilotProvider) Chat(ctx context.Context, messages []Message, to Content: content, }, nil } -func (p *GitHubCopilotProvider) GetDefaultModel() string { +func (p *GitHubCopilotProvider) GetDefaultModel() string { return "gpt-4.1" } diff --git a/pkg/tools/registry_test.go b/pkg/tools/registry_test.go index 33978e543..8ae13b20c 100644 --- a/pkg/tools/registry_test.go +++ b/pkg/tools/registry_test.go @@ -14,14 +14,14 @@ import ( type mockRegistryTool struct { name string desc string - params map[string]interface{} + params map[string]any result *ToolResult } -func (m *mockRegistryTool) Name() string { return m.name } -func (m *mockRegistryTool) Description() string { return m.desc } -func (m *mockRegistryTool) Parameters() map[string]interface{} { return m.params } -func (m *mockRegistryTool) Execute(_ context.Context, _ map[string]interface{}) *ToolResult { +func (m *mockRegistryTool) Name() string { return m.name } +func (m *mockRegistryTool) Description() string { return m.desc } +func (m *mockRegistryTool) Parameters() map[string]any { return m.params } +func (m *mockRegistryTool) Execute(_ context.Context, _ map[string]any) *ToolResult { return m.result } @@ -51,7 +51,7 @@ func newMockTool(name, desc string) *mockRegistryTool { return &mockRegistryTool{ name: name, desc: desc, - params: map[string]interface{}{"type": "object"}, + params: map[string]any{"type": "object"}, result: SilentResult("ok"), } } @@ -109,7 +109,7 @@ func TestToolRegistry_Execute_Success(t *testing.T) { r.Register(&mockRegistryTool{ name: "greet", desc: "says hello", - params: map[string]interface{}{}, + params: map[string]any{}, result: SilentResult("hello"), }) @@ -203,7 +203,7 @@ func TestToolRegistry_GetDefinitions(t *testing.T) { if defs[0]["type"] != "function" { t.Errorf("expected type 'function', got %v", defs[0]["type"]) } - fn, ok := defs[0]["function"].(map[string]interface{}) + fn, ok := defs[0]["function"].(map[string]any) if !ok { t.Fatal("expected 'function' key to be a map") } @@ -217,7 +217,7 @@ func TestToolRegistry_GetDefinitions(t *testing.T) { func TestToolRegistry_ToProviderDefs(t *testing.T) { r := NewToolRegistry() - params := map[string]interface{}{"type": "object", "properties": map[string]interface{}{}} + params := map[string]any{"type": "object", "properties": map[string]any{}} r.Register(&mockRegistryTool{ name: "beta", desc: "tool B", @@ -310,7 +310,7 @@ func TestToolToSchema(t *testing.T) { if schema["type"] != "function" { t.Errorf("expected type 'function', got %v", schema["type"]) } - fn, ok := schema["function"].(map[string]interface{}) + fn, ok := schema["function"].(map[string]any) if !ok { t.Fatal("expected 'function' to be a map") } From c6865fe852f4e163767b78b6df72a06b5fdc6204 Mon Sep 17 00:00:00 2001 From: Vidish <57653368+ulolol@users.noreply.github.com> Date: Sun, 22 Feb 2026 22:00:14 +0530 Subject: [PATCH 20/40] feat: integrate Tavily search (#340) * feat: integrate Tavily search * fix: set include_raw_content to false in Tavily search as wealready get relevant data inside content * refactor: update Go type declarations to `any`, apply formatting fixes. --- README.ja.md | 29 ++++++++++-- README.md | 9 +++- README.zh.md | 27 ++++++----- pkg/config/config.go | 8 ++++ pkg/tools/registry_test.go | 20 ++++---- pkg/tools/web.go | 97 +++++++++++++++++++++++++++++++++++++- pkg/tools/web_test.go | 72 ++++++++++++++++++++++++++++ 7 files changed, 232 insertions(+), 30 deletions(-) diff --git a/README.ja.md b/README.ja.md index bb0bdfb28..3506c77c2 100644 --- a/README.ja.md +++ b/README.ja.md @@ -162,7 +162,7 @@ docker compose --profile gateway up -d > [!TIP] > `~/.picoclaw/config.json` に API キーを設定してください。 > API キーの取得先: [OpenRouter](https://openrouter.ai/keys) (LLM) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) (LLM) -> Web 検索は **任意** です - 無料の [Brave Search API](https://brave.com/search/api) (月 2000 クエリ無料) +> Web 検索は **任意** です - 無料の [Tavily API](https://tavily.com) (月 1000 クエリ無料) または [Brave Search API](https://brave.com/search/api) (月 2000 クエリ無料) **1. 初期化** @@ -193,14 +193,34 @@ picoclaw onboard "token": "YOUR_TELEGRAM_BOT_TOKEN", "allow_from": [] } + }, + "tools": { + "web": { + "search": { + "api_key": "YOUR_BRAVE_API_KEY", + "max_results": 5 + }, + "tavily": { + "enabled": false, + "api_key": "YOUR_TAVILY_API_KEY", + "max_results": 5 + } + }, + "cron": { + "exec_timeout_minutes": 5 + } + }, + "heartbeat": { + "enabled": true, + "interval": 30 } } ``` **3. API キーの取得** -- **LLM プロバイダー**: [OpenRouter](https://openrouter.ai/keys) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) · [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com/api-keys) · [Qwen](https://dashscope.console.aliyun.com) -- **Web 検索**(任意): [Brave Search](https://brave.com/search/api) - 無料枠あり(月 2000 リクエスト) +- **LLM プロバイダー**: [OpenRouter](https://openrouter.ai/keys) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) · [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com/api-keys) +- **Web 検索**(任意): [Tavily](https://tavily.com) - AI エージェント向けに最適化 (月 1000 リクエスト) · [Brave Search](https://brave.com/search/api) - 無料枠あり(月 2000 リクエスト) > **注意**: 完全な設定テンプレートは `config.example.json` を参照してください。 @@ -985,7 +1005,7 @@ Discord: https://discord.gg/V4sAZ9XWpN 検索 API キーをまだ設定していない場合、これは正常です。PicoClaw は手動検索用の便利なリンクを提供します。 Web 検索を有効にするには: -1. [https://brave.com/search/api](https://brave.com/search/api) で無料の API キーを取得(月 2000 クエリ無料) +1. [https://tavily.com](https://tavily.com) (月 1000 クエリ無料) または [https://brave.com/search/api](https://brave.com/search/api) で無料の API キーを取得(月 2000 クエリ無料) 2. `~/.picoclaw/config.json` に追加: ```json { @@ -1023,5 +1043,6 @@ Web 検索を有効にするには: | **Zhipu** | 月 200K トークン | 中国ユーザー向け最適 | | **Qwen** | 無料枠あり | 通義千問 (Qwen) | | **Brave Search** | 月 2000 クエリ | Web 検索機能 | +| **Tavily** | 月 1000 クエリ | AI エージェント検索最適化 | | **Groq** | 無料枠あり | 高速推論(Llama, Mixtral) | | **Cerebras** | 無料枠あり | 高速推論(Llama, Qwen など) | diff --git a/README.md b/README.md index de6fd87ea..825f57340 100644 --- a/README.md +++ b/README.md @@ -200,7 +200,7 @@ docker compose --profile gateway up -d > [!TIP] > Set your API key in `~/.picoclaw/config.json`. > Get API keys: [OpenRouter](https://openrouter.ai/keys) (LLM) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) (LLM) -> Web search is **optional** - get free [Brave Search API](https://brave.com/search/api) (2000 free queries/month) or use built-in auto fallback. +> Web Search is **optional** - get free [Tavily API](https://tavily.com) (1000 free queries/month) or [Brave Search API](https://brave.com/search/api) (2000 free queries/month) or use built-in auto fallback. **1. Initialize** @@ -240,6 +240,11 @@ picoclaw onboard "api_key": "YOUR_BRAVE_API_KEY", "max_results": 5 }, + "tavily": { + "enabled": false, + "api_key": "YOUR_TAVILY_API_KEY", + "max_results": 5 + }, "duckduckgo": { "enabled": true, "max_results": 5 @@ -254,7 +259,7 @@ picoclaw onboard **3. Get API Keys** * **LLM Provider**: [OpenRouter](https://openrouter.ai/keys) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) · [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com/api-keys) -* **Web Search** (optional): [Brave Search](https://brave.com/search/api) - Free tier available (2000 requests/month) +* **Web Search** (optional): [Tavily](https://tavily.com) - Optimized for AI Agents (1000 requests/month) · [Brave Search](https://brave.com/search/api) - Free tier available (2000 requests/month) > **Note**: See `config.example.json` for a complete configuration template. diff --git a/README.zh.md b/README.zh.md index 4d739c5eb..fd188567d 100644 --- a/README.zh.md +++ b/README.zh.md @@ -205,7 +205,7 @@ docker compose --profile gateway up -d > [!TIP] > 在 `~/.picoclaw/config.json` 中设置您的 API Key。 > 获取 API Key: [OpenRouter](https://openrouter.ai/keys) (LLM) · [Zhipu (智谱)](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) (LLM) -> 网络搜索是 **可选的** - 获取免费的 [Brave Search API](https://brave.com/search/api) (每月 2000 次免费查询) +> 网络搜索是 **可选的** - 获取免费的 [Tavily API](https://tavily.com) (每月 1000 次免费查询) 或 [Brave Search API](https://brave.com/search/api) (每月 2000 次免费查询) **1. 初始化 (Initialize)** @@ -246,8 +246,9 @@ picoclaw onboard "api_key": "YOUR_BRAVE_API_KEY", "max_results": 5 }, - "duckduckgo": { - "enabled": true, + "tavily": { + "enabled": false, + "api_key": "YOUR_TAVILY_API_KEY", "max_results": 5 } }, @@ -262,8 +263,8 @@ picoclaw onboard **3. 获取 API Key** -- **LLM 提供商**: [OpenRouter](https://openrouter.ai/keys) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) · [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com/api-keys) -- **网络搜索** (可选): [Brave Search](https://brave.com/search/api) - 提供免费层级 (2000 请求/月) +* **LLM 提供商**: [OpenRouter](https://openrouter.ai/keys) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) · [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com/api-keys) +* **网络搜索** (可选): [Tavily](https://tavily.com) - 专为 AI Agent 优化 (1000 请求/月) · [Brave Search](https://brave.com/search/api) - 提供免费层级 (2000 请求/月) > **注意**: 完整的配置模板请参考 `config.example.json`。 @@ -771,7 +772,7 @@ Discord: [https://discord.gg/V4sAZ9XWpN](https://discord.gg/V4sAZ9XWpN) 启用网络搜索: -1. 在 [https://brave.com/search/api](https://brave.com/search/api) 获取免费 API Key (每月 2000 次免费查询) +1. 在 [https://tavily.com](https://tavily.com) (1000 次免费) 或 [https://brave.com/search/api](https://brave.com/search/api) 获取免费 API Key (2000 次免费) 2. 添加到 `~/.picoclaw/config.json`: ```json @@ -804,10 +805,10 @@ Discord: [https://discord.gg/V4sAZ9XWpN](https://discord.gg/V4sAZ9XWpN) ## 📝 API Key 对比 -| 服务 | 免费层级 | 适用场景 | -| ---------------- | -------------- | ----------------------------- | -| **OpenRouter** | 200K tokens/月 | 多模型聚合 (Claude, GPT-4 等) | -| **智谱 (Zhipu)** | 200K tokens/月 | 最适合中国用户 | -| **Brave Search** | 2000 次查询/月 | 网络搜索功能 | -| **Groq** | 提供免费层级 | 极速推理 (Llama, Mixtral) | -| **Cerebras** | 提供免费层级 | 极速推理 (Llama, Qwen 等) | +| 服务 | 免费层级 | 适用场景 | +| --- | --- | --- | +| **OpenRouter** | 200K tokens/月 | 多模型聚合 (Claude, GPT-4 等) | +| **智谱 (Zhipu)** | 200K tokens/月 | 最适合中国用户 | +| **Brave Search** | 2000 次查询/月 | 网络搜索功能 | +| **Tavily** | 1000 次查询/月 | AI Agent 搜索优化 | +| **Groq** | 提供免费层级 | 极速推理 (Llama, Mixtral) | diff --git a/pkg/config/config.go b/pkg/config/config.go index 20556011a..036021e49 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -418,6 +418,13 @@ type BraveConfig struct { MaxResults int `json:"max_results" env:"PICOCLAW_TOOLS_WEB_BRAVE_MAX_RESULTS"` } +type TavilyConfig struct { + Enabled bool `json:"enabled" env:"PICOCLAW_TOOLS_WEB_TAVILY_ENABLED"` + APIKey string `json:"api_key" env:"PICOCLAW_TOOLS_WEB_TAVILY_API_KEY"` + BaseURL string `json:"base_url" env:"PICOCLAW_TOOLS_WEB_TAVILY_BASE_URL"` + MaxResults int `json:"max_results" env:"PICOCLAW_TOOLS_WEB_TAVILY_MAX_RESULTS"` +} + type DuckDuckGoConfig struct { Enabled bool `json:"enabled" env:"PICOCLAW_TOOLS_WEB_DUCKDUCKGO_ENABLED"` MaxResults int `json:"max_results" env:"PICOCLAW_TOOLS_WEB_DUCKDUCKGO_MAX_RESULTS"` @@ -431,6 +438,7 @@ type PerplexityConfig struct { type WebToolsConfig struct { Brave BraveConfig `json:"brave"` + Tavily TavilyConfig `json:"tavily"` DuckDuckGo DuckDuckGoConfig `json:"duckduckgo"` Perplexity PerplexityConfig `json:"perplexity"` } diff --git a/pkg/tools/registry_test.go b/pkg/tools/registry_test.go index 33978e543..8ae13b20c 100644 --- a/pkg/tools/registry_test.go +++ b/pkg/tools/registry_test.go @@ -14,14 +14,14 @@ import ( type mockRegistryTool struct { name string desc string - params map[string]interface{} + params map[string]any result *ToolResult } -func (m *mockRegistryTool) Name() string { return m.name } -func (m *mockRegistryTool) Description() string { return m.desc } -func (m *mockRegistryTool) Parameters() map[string]interface{} { return m.params } -func (m *mockRegistryTool) Execute(_ context.Context, _ map[string]interface{}) *ToolResult { +func (m *mockRegistryTool) Name() string { return m.name } +func (m *mockRegistryTool) Description() string { return m.desc } +func (m *mockRegistryTool) Parameters() map[string]any { return m.params } +func (m *mockRegistryTool) Execute(_ context.Context, _ map[string]any) *ToolResult { return m.result } @@ -51,7 +51,7 @@ func newMockTool(name, desc string) *mockRegistryTool { return &mockRegistryTool{ name: name, desc: desc, - params: map[string]interface{}{"type": "object"}, + params: map[string]any{"type": "object"}, result: SilentResult("ok"), } } @@ -109,7 +109,7 @@ func TestToolRegistry_Execute_Success(t *testing.T) { r.Register(&mockRegistryTool{ name: "greet", desc: "says hello", - params: map[string]interface{}{}, + params: map[string]any{}, result: SilentResult("hello"), }) @@ -203,7 +203,7 @@ func TestToolRegistry_GetDefinitions(t *testing.T) { if defs[0]["type"] != "function" { t.Errorf("expected type 'function', got %v", defs[0]["type"]) } - fn, ok := defs[0]["function"].(map[string]interface{}) + fn, ok := defs[0]["function"].(map[string]any) if !ok { t.Fatal("expected 'function' key to be a map") } @@ -217,7 +217,7 @@ func TestToolRegistry_GetDefinitions(t *testing.T) { func TestToolRegistry_ToProviderDefs(t *testing.T) { r := NewToolRegistry() - params := map[string]interface{}{"type": "object", "properties": map[string]interface{}{}} + params := map[string]any{"type": "object", "properties": map[string]any{}} r.Register(&mockRegistryTool{ name: "beta", desc: "tool B", @@ -310,7 +310,7 @@ func TestToolToSchema(t *testing.T) { if schema["type"] != "function" { t.Errorf("expected type 'function', got %v", schema["type"]) } - fn, ok := schema["function"].(map[string]interface{}) + fn, ok := schema["function"].(map[string]any) if !ok { t.Fatal("expected 'function' to be a map") } diff --git a/pkg/tools/web.go b/pkg/tools/web.go index 301e00daf..059437889 100644 --- a/pkg/tools/web.go +++ b/pkg/tools/web.go @@ -1,6 +1,7 @@ package tools import ( + "bytes" "context" "encoding/json" "fmt" @@ -84,6 +85,88 @@ func (p *BraveSearchProvider) Search(ctx context.Context, query string, count in return strings.Join(lines, "\n"), nil } +type TavilySearchProvider struct { + apiKey string + baseURL string +} + +func (p *TavilySearchProvider) Search(ctx context.Context, query string, count int) (string, error) { + searchURL := p.baseURL + if searchURL == "" { + searchURL = "https://api.tavily.com/search" + } + + payload := map[string]any{ + "api_key": p.apiKey, + "query": query, + "search_depth": "advanced", + "include_answer": false, + "include_images": false, + "include_raw_content": "false", + "max_results": count, + } + + bodyBytes, err := json.Marshal(payload) + if err != nil { + return "", fmt.Errorf("failed to marshal payload: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, "POST", searchURL, bytes.NewBuffer(bodyBytes)) + if err != nil { + return "", fmt.Errorf("failed to create request: %w", err) + } + + req.Header.Set("Content-Type", "application/json") + req.Header.Set("User-Agent", userAgent) + + client := &http.Client{Timeout: 10 * time.Second} + resp, err := client.Do(req) + if err != nil { + return "", fmt.Errorf("request failed: %w", err) + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return "", fmt.Errorf("failed to read response: %w", err) + } + + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("tavily api error (status %d): %s", resp.StatusCode, string(body)) + } + + var searchResp struct { + Results []struct { + Title string `json:"title"` + URL string `json:"url"` + Content string `json:"content"` + } `json:"results"` + } + + if err := json.Unmarshal(body, &searchResp); err != nil { + return "", fmt.Errorf("failed to parse response: %w", err) + } + + results := searchResp.Results + if len(results) == 0 { + return fmt.Sprintf("No results for: %s", query), nil + } + + var lines []string + lines = append(lines, fmt.Sprintf("Results for: %s (via Tavily)", query)) + for i, item := range results { + if i >= count { + break + } + lines = append(lines, fmt.Sprintf("%d. %s\n %s", i+1, item.Title, item.URL)) + if item.Content != "" { + lines = append(lines, fmt.Sprintf(" %s", item.Content)) + } + } + + return strings.Join(lines, "\n"), nil +} + type DuckDuckGoSearchProvider struct{} func (p *DuckDuckGoSearchProvider) Search(ctx context.Context, query string, count int) (string, error) { @@ -256,6 +339,10 @@ type WebSearchToolOptions struct { BraveAPIKey string BraveMaxResults int BraveEnabled bool + TavilyAPIKey string + TavilyBaseURL string + TavilyMaxResults int + TavilyEnabled bool DuckDuckGoMaxResults int DuckDuckGoEnabled bool PerplexityAPIKey string @@ -267,7 +354,7 @@ func NewWebSearchTool(opts WebSearchToolOptions) *WebSearchTool { var provider SearchProvider maxResults := 5 - // Priority: Perplexity > Brave > DuckDuckGo + // Priority: Perplexity > Brave > Tavily > DuckDuckGo if opts.PerplexityEnabled && opts.PerplexityAPIKey != "" { provider = &PerplexitySearchProvider{apiKey: opts.PerplexityAPIKey} if opts.PerplexityMaxResults > 0 { @@ -278,6 +365,14 @@ func NewWebSearchTool(opts WebSearchToolOptions) *WebSearchTool { if opts.BraveMaxResults > 0 { maxResults = opts.BraveMaxResults } + } else if opts.TavilyEnabled && opts.TavilyAPIKey != "" { + provider = &TavilySearchProvider{ + apiKey: opts.TavilyAPIKey, + baseURL: opts.TavilyBaseURL, + } + if opts.TavilyMaxResults > 0 { + maxResults = opts.TavilyMaxResults + } } else if opts.DuckDuckGoEnabled { provider = &DuckDuckGoSearchProvider{} if opts.DuckDuckGoMaxResults > 0 { diff --git a/pkg/tools/web_test.go b/pkg/tools/web_test.go index d999d8958..75e0d8d16 100644 --- a/pkg/tools/web_test.go +++ b/pkg/tools/web_test.go @@ -333,3 +333,75 @@ func TestWebTool_WebFetch_MissingDomain(t *testing.T) { t.Errorf("Expected domain error message, got ForLLM: %s", result.ForLLM) } } + +// TestWebTool_TavilySearch_Success verifies successful Tavily search +func TestWebTool_TavilySearch_Success(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + t.Errorf("Expected POST request, got %s", r.Method) + } + if r.Header.Get("Content-Type") != "application/json" { + t.Errorf("Expected Content-Type application/json, got %s", r.Header.Get("Content-Type")) + } + + // Verify payload + var payload map[string]any + json.NewDecoder(r.Body).Decode(&payload) + if payload["api_key"] != "test-key" { + t.Errorf("Expected api_key test-key, got %v", payload["api_key"]) + } + if payload["query"] != "test query" { + t.Errorf("Expected query 'test query', got %v", payload["query"]) + } + + // Return mock response + response := map[string]any{ + "results": []map[string]any{ + { + "title": "Test Result 1", + "url": "https://example.com/1", + "content": "Content for result 1", + }, + { + "title": "Test Result 2", + "url": "https://example.com/2", + "content": "Content for result 2", + }, + }, + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + json.NewEncoder(w).Encode(response) + })) + defer server.Close() + + tool := NewWebSearchTool(WebSearchToolOptions{ + TavilyEnabled: true, + TavilyAPIKey: "test-key", + TavilyBaseURL: server.URL, + TavilyMaxResults: 5, + }) + + ctx := context.Background() + args := map[string]any{ + "query": "test query", + } + + result := tool.Execute(ctx, args) + + // Success should not be an error + if result.IsError { + t.Errorf("Expected success, got IsError=true: %s", result.ForLLM) + } + + // ForUser should contain result titles and URLs + if !strings.Contains(result.ForUser, "Test Result 1") || + !strings.Contains(result.ForUser, "https://example.com/1") { + t.Errorf("Expected results in output, got: %s", result.ForUser) + } + + // Should mention via Tavily + if !strings.Contains(result.ForUser, "via Tavily") { + t.Errorf("Expected 'via Tavily' in output, got: %s", result.ForUser) + } +} From 4a73415e0516e0f954267c2ee797896d2ec770bb Mon Sep 17 00:00:00 2001 From: Kai Xia Date: Mon, 23 Feb 2026 08:09:26 +1100 Subject: [PATCH 21/40] golangci-lint run --fix on master Signed-off-by: Kai Xia --- pkg/tools/registry_test.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pkg/tools/registry_test.go b/pkg/tools/registry_test.go index 33978e543..8ae13b20c 100644 --- a/pkg/tools/registry_test.go +++ b/pkg/tools/registry_test.go @@ -14,14 +14,14 @@ import ( type mockRegistryTool struct { name string desc string - params map[string]interface{} + params map[string]any result *ToolResult } -func (m *mockRegistryTool) Name() string { return m.name } -func (m *mockRegistryTool) Description() string { return m.desc } -func (m *mockRegistryTool) Parameters() map[string]interface{} { return m.params } -func (m *mockRegistryTool) Execute(_ context.Context, _ map[string]interface{}) *ToolResult { +func (m *mockRegistryTool) Name() string { return m.name } +func (m *mockRegistryTool) Description() string { return m.desc } +func (m *mockRegistryTool) Parameters() map[string]any { return m.params } +func (m *mockRegistryTool) Execute(_ context.Context, _ map[string]any) *ToolResult { return m.result } @@ -51,7 +51,7 @@ func newMockTool(name, desc string) *mockRegistryTool { return &mockRegistryTool{ name: name, desc: desc, - params: map[string]interface{}{"type": "object"}, + params: map[string]any{"type": "object"}, result: SilentResult("ok"), } } @@ -109,7 +109,7 @@ func TestToolRegistry_Execute_Success(t *testing.T) { r.Register(&mockRegistryTool{ name: "greet", desc: "says hello", - params: map[string]interface{}{}, + params: map[string]any{}, result: SilentResult("hello"), }) @@ -203,7 +203,7 @@ func TestToolRegistry_GetDefinitions(t *testing.T) { if defs[0]["type"] != "function" { t.Errorf("expected type 'function', got %v", defs[0]["type"]) } - fn, ok := defs[0]["function"].(map[string]interface{}) + fn, ok := defs[0]["function"].(map[string]any) if !ok { t.Fatal("expected 'function' key to be a map") } @@ -217,7 +217,7 @@ func TestToolRegistry_GetDefinitions(t *testing.T) { func TestToolRegistry_ToProviderDefs(t *testing.T) { r := NewToolRegistry() - params := map[string]interface{}{"type": "object", "properties": map[string]interface{}{}} + params := map[string]any{"type": "object", "properties": map[string]any{}} r.Register(&mockRegistryTool{ name: "beta", desc: "tool B", @@ -310,7 +310,7 @@ func TestToolToSchema(t *testing.T) { if schema["type"] != "function" { t.Errorf("expected type 'function', got %v", schema["type"]) } - fn, ok := schema["function"].(map[string]interface{}) + fn, ok := schema["function"].(map[string]any) if !ok { t.Fatal("expected 'function' to be a map") } From 8928f83c7ff254ec1c74bff1d03aca20220cb702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20Xia=28=E5=A4=8F=E6=81=BA=29?= Date: Mon, 23 Feb 2026 09:45:17 +1100 Subject: [PATCH 22/40] remove old roadmap (#632) --- README.fr.md | 2 +- README.md | 2 +- README.pt-br.md | 2 +- README.vi.md | 2 +- README.zh.md | 2 +- docs/picoclaw_community_roadmap_260216.md | 112 ---------------------- 6 files changed, 5 insertions(+), 117 deletions(-) delete mode 100644 docs/picoclaw_community_roadmap_260216.md diff --git a/README.fr.md b/README.fr.md index 7199f7098..a762870ff 100644 --- a/README.fr.md +++ b/README.fr.md @@ -50,7 +50,7 @@ ## 📢 Actualités -2026-02-16 🎉 PicoClaw a atteint 12K étoiles en une semaine ! Merci à tous pour votre soutien ! PicoClaw grandit plus vite que nous ne l'avions jamais imaginé. Vu le volume élevé de PR, nous avons un besoin urgent de mainteneurs communautaires. Nos rôles de bénévoles et notre feuille de route sont officiellement publiés [ici](docs/picoclaw_community_roadmap_260216.md) — nous avons hâte de vous accueillir ! +2026-02-16 🎉 PicoClaw a atteint 12K étoiles en une semaine ! Merci à tous pour votre soutien ! PicoClaw grandit plus vite que nous ne l'avions jamais imaginé. Vu le volume élevé de PR, nous avons un besoin urgent de mainteneurs communautaires. Nos rôles de bénévoles et notre feuille de route sont officiellement publiés [ici](docs/ROADMAP.md) — nous avons hâte de vous accueillir ! 2026-02-13 🎉 PicoClaw a atteint 5000 étoiles en 4 jours ! Merci à la communauté ! Nous finalisons la **Feuille de Route du Projet** et mettons en place le **Groupe de Développeurs** pour accélérer le développement de PicoClaw. 🚀 **Appel à l'action :** Soumettez vos demandes de fonctionnalités dans les GitHub Discussions. Nous les examinerons et les prioriserons lors de notre prochaine réunion hebdomadaire. diff --git a/README.md b/README.md index 825f57340..955255f2e 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ ## 📢 News -2026-02-16 🎉 PicoClaw hit 12K stars in one week! Thank you all for your support! PicoClaw is growing faster than we ever imagined. Given the high volume of PRs, we urgently need community maintainers. Our volunteer roles and roadmap are officially posted [here](docs/picoclaw_community_roadmap_260216.md) —we can’t wait to have you on board! +2026-02-16 🎉 PicoClaw hit 12K stars in one week! Thank you all for your support! PicoClaw is growing faster than we ever imagined. Given the high volume of PRs, we urgently need community maintainers. Our volunteer roles and roadmap are officially posted [here](docs/ROADMAP.md) —we can’t wait to have you on board! 2026-02-13 🎉 PicoClaw hit 5000 stars in 4days! Thank you for the community! There are so many PRs & issues coming in (during Chinese New Year holidays), we are finalizing the Project Roadmap and setting up the Developer Group to accelerate PicoClaw's development. 🚀 Call to Action: Please submit your feature requests in GitHub Discussions. We will review and prioritize them during our upcoming weekly meeting. diff --git a/README.pt-br.md b/README.pt-br.md index ec8fe8e1c..900ee7932 100644 --- a/README.pt-br.md +++ b/README.pt-br.md @@ -50,7 +50,7 @@ ## 📢 Novidades -2026-02-16 🎉 PicoClaw atingiu 12K stars em uma semana! Obrigado a todos pelo apoio! O PicoClaw está crescendo mais rápido do que jamais imaginamos. Dado o alto volume de PRs, precisamos urgentemente de maintainers da comunidade. Nossos papéis de voluntários e roadmap foram publicados oficialmente [aqui](docs/picoclaw_community_roadmap_260216.md) — estamos ansiosos para ter você a bordo! +2026-02-16 🎉 PicoClaw atingiu 12K stars em uma semana! Obrigado a todos pelo apoio! O PicoClaw está crescendo mais rápido do que jamais imaginamos. Dado o alto volume de PRs, precisamos urgentemente de maintainers da comunidade. Nossos papéis de voluntários e roadmap foram publicados oficialmente [aqui](docs/ROADMAP.md) — estamos ansiosos para ter você a bordo! 2026-02-13 🎉 PicoClaw atingiu 5000 stars em 4 dias! Obrigado à comunidade! Estamos finalizando o **Roadmap do Projeto** e configurando o **Grupo de Desenvolvedores** para acelerar o desenvolvimento do PicoClaw. diff --git a/README.vi.md b/README.vi.md index 161842933..29ff12bb0 100644 --- a/README.vi.md +++ b/README.vi.md @@ -50,7 +50,7 @@ ## 📢 Tin tức -2026-02-16 🎉 PicoClaw đạt 12K stars chỉ trong một tuần! Cảm ơn tất cả mọi người! PicoClaw đang phát triển nhanh hơn chúng tôi tưởng tượng. Do số lượng PR tăng cao, chúng tôi cấp thiết cần maintainer từ cộng đồng. Các vai trò tình nguyện viên và roadmap đã được công bố [tại đây](docs/picoclaw_community_roadmap_260216.md) — rất mong đón nhận sự tham gia của bạn! +2026-02-16 🎉 PicoClaw đạt 12K stars chỉ trong một tuần! Cảm ơn tất cả mọi người! PicoClaw đang phát triển nhanh hơn chúng tôi tưởng tượng. Do số lượng PR tăng cao, chúng tôi cấp thiết cần maintainer từ cộng đồng. Các vai trò tình nguyện viên và roadmap đã được công bố [tại đây](docs/ROADMAP.md) — rất mong đón nhận sự tham gia của bạn! 2026-02-13 🎉 PicoClaw đạt 5000 stars trong 4 ngày! Cảm ơn cộng đồng! Chúng tôi đang hoàn thiện **Lộ trình dự án (Roadmap)** và thiết lập **Nhóm phát triển** để đẩy nhanh tốc độ phát triển PicoClaw. 🚀 **Kêu gọi hành động:** Vui lòng gửi yêu cầu tính năng tại GitHub Discussions. Chúng tôi sẽ xem xét và ưu tiên trong cuộc họp hàng tuần. diff --git a/README.zh.md b/README.zh.md index fd188567d..17a736fec 100644 --- a/README.zh.md +++ b/README.zh.md @@ -52,7 +52,7 @@ ## 📢 新闻 (News) -2026-02-16 🎉 PicoClaw 在一周内突破了12K star! 感谢大家的关注!PicoClaw 的成长速度超乎我们预期. 由于PR数量的快速膨胀,我们亟需社区开发者参与维护. 我们需要的志愿者角色和roadmap已经发布到了[这里](docs/picoclaw_community_roadmap_260216.md), 期待你的参与! +2026-02-16 🎉 PicoClaw 在一周内突破了12K star! 感谢大家的关注!PicoClaw 的成长速度超乎我们预期. 由于PR数量的快速膨胀,我们亟需社区开发者参与维护. 我们需要的志愿者角色和roadmap已经发布到了[这里](docs/ROADMAP.md), 期待你的参与! 2026-02-13 🎉 **PicoClaw 在 4 天内突破 5000 Stars!** 感谢社区的支持!由于正值中国春节假期,PR 和 Issue 涌入较多,我们正在利用这段时间敲定 **项目路线图 (Roadmap)** 并组建 **开发者群组**,以便加速 PicoClaw 的开发。 🚀 **行动号召:** 请在 GitHub Discussions 中提交您的功能请求 (Feature Requests)。我们将在接下来的周会上进行审查和优先级排序。 diff --git a/docs/picoclaw_community_roadmap_260216.md b/docs/picoclaw_community_roadmap_260216.md deleted file mode 100644 index 95de768c6..000000000 --- a/docs/picoclaw_community_roadmap_260216.md +++ /dev/null @@ -1,112 +0,0 @@ -## 🚀 Join the PicoClaw Journey: Call for Community Volunteers & Roadmap Reveal - -**Hello, PicoClaw Community!** - -First, a massive thank you to everyone for your enthusiasm and PR contributions. It is because of you that PicoClaw continues to iterate and evolve so rapidly. Thanks to the simplicity and accessibility of the **Go language**, we’ve seen a non-stop stream of high-quality PRs! - -PicoClaw is growing much faster than we anticipated. As we are currently in the midst of the **Chinese New Year holiday**, we are looking to recruit community volunteers to help us maintain this incredible momentum. - -This document outlines the specific volunteer roles we need right now and provides a look at our upcoming **Roadmap**. - -### 🎁 Community Perks - -To show our appreciation, developers who officially join our community operations will receive: - -* **Exclusive AI Hardware:** Our upcoming, unreleased AI device. -* **Token Discounts:** Potential discounts on LLM tokens (currently in negotiations with major providers). - -### 🎥 Calling All Content Creators! - -Not a developer? You can still help! We welcome users to post **PicoClaw reviews or tutorials**. - -* **Twitter:** Use the tag **#picoclaw** and mention **@SipeedIO**. -* **Bilibili:** Mention **@Sipeed矽速科技** or send us a DM. -We will be rewarding high-quality content creators with the same perks as our community developers! - ---- - -## 🛠️ Urgent Volunteer Roles - -We are looking for experts in the following areas: - -1. **Issue/PR Reviewers** -* **The Mission:** With PRs and Issues exploding in volume, we need help with initial triage, evaluation, and merging. -* **Focus:** Preliminary merging and community health. Efficiency optimization and security audits will be handled by specialized roles. - - -2. **Resource Optimization Experts** -* **The Mission:** Rapid growth has introduced dependencies that are making PicoClaw a bit "heavy." We want to keep it lean. -* **Focus:** Analyzing resource growth between releases and trimming redundancy. -* **Priority:** **RAM usage optimization** > Binary size reduction. - - -3. **Security Audit & Bug Fixes** -* **The Mission:** Due to the "vibe coding" nature of our early stages, we need a thorough review of network security and AI permission management. -* **Focus:** Auditing the codebase for vulnerabilities and implementing robust fixes. - - -4. **Documentation & DX (Developer Experience)** -* **The Mission:** Our current README is a bit outdated. We need "step-by-step" guides that even beginners can follow. -* **Focus:** Creating clear, user-friendly documentation for both setup and development. - - -5. **AI-Powered CI/CD Optimization** -* **The Mission:** PicoClaw started as a "vibe coding" experiment; now we want to use AI to manage it. -* **Focus:** Automating builds with AI and exploring AI-driven issue resolution. - -**How to Apply:** > If you are interested in any of the roles above, please send an email to support@sipeed.com with the subject line: [Apply: PicoClaw Expert Volunteer] + Your Desired Role. -Please include a brief introduction and any relevant experience or portfolio links. We will review all applications and grant project permissions to selected contributors! - ---- - -## 📍 The Roadmap - -Interested in a specific feature? You can "claim" these tasks and start building: - -### -* **Provider:** - * **Provider Refactor:** Currently being handled by **@Daming** (ETA: 5 days) - * You can still submit code; Daming will merge it into the new implementation. -* **Channels:** - * Support for OneBot, additional platforms - * attachments (images, audio, video, files). -* **Skills:** - * Implementing `find_skill` to discover tools via [ClawhHub](https://clawhub.ai) and other platforms. -* **Operations:** * MCP Support. - * Android operations (e.g., botdrop). - * Browser automation via CDP or ActionBook. - - -* **Multi-Agent Ecosystem:** - * **Basic Model-Agent** - * **Model Routing:** Small models for easy tasks, large models for hard ones (to save tokens). - * **Swarm Mode.** - * **AIEOS Integration.** - - -* **Branding:** - * **Logo**: We need a cute logo! We’re leaning toward a **Mantis Shrimp**—small, but packs a legendary punch! - - -We have officially created these tasks as GitHub Issues, all marked with the roadmap tag. -This list will be updated continuously as we progress. -If you would like to claim a task, please feel free to start a conversation by commenting directly on the corresponding issue! - ---- - -## 🤝 How to Join - -**Everything is open to your creativity!** If you have a wild idea, just PR it. - -1. **The Fast Track:** Once you have at least **one merged PR**, you are eligible to join our **Developer Discord** to help plan the future of PicoClaw. -2. **The Application Track:** If you haven’t submitted a PR yet but want to dive in, email **support@sipeed.com** with the subject: -> `[Apply Join PicoClaw Dev Group] + Your GitHub Account` -> Include the role you're interested in and any evidence of your development experience. - - - -### Looking Ahead - -Powered by PicoClaw, we are crafting a Swarm AI Assistant to transform your environment into a seamless network of personal stewards. By automating the friction of daily life, we empower you to transcend the ordinary and freely explore your creative potential. - -**Finally, Happy Chinese New Year to everyone!** May PicoClaw gallop forward in this **Year of the Horse!** 🐎 From 4cc8b90da94d9695d3edad52281cefdc58db8e58 Mon Sep 17 00:00:00 2001 From: Vidish <57653368+ulolol@users.noreply.github.com> Date: Mon, 23 Feb 2026 09:42:34 +0530 Subject: [PATCH 23/40] Fix: missing Tavily config in loop.go, and the invalid config param in web_search (#660) --- pkg/agent/loop.go | 4 ++++ pkg/tools/web.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/agent/loop.go b/pkg/agent/loop.go index b36f4a0c4..bf229ad74 100644 --- a/pkg/agent/loop.go +++ b/pkg/agent/loop.go @@ -97,6 +97,10 @@ func registerSharedTools( BraveAPIKey: cfg.Tools.Web.Brave.APIKey, BraveMaxResults: cfg.Tools.Web.Brave.MaxResults, BraveEnabled: cfg.Tools.Web.Brave.Enabled, + TavilyAPIKey: cfg.Tools.Web.Tavily.APIKey, + TavilyBaseURL: cfg.Tools.Web.Tavily.BaseURL, + TavilyMaxResults: cfg.Tools.Web.Tavily.MaxResults, + TavilyEnabled: cfg.Tools.Web.Tavily.Enabled, DuckDuckGoMaxResults: cfg.Tools.Web.DuckDuckGo.MaxResults, DuckDuckGoEnabled: cfg.Tools.Web.DuckDuckGo.Enabled, PerplexityAPIKey: cfg.Tools.Web.Perplexity.APIKey, diff --git a/pkg/tools/web.go b/pkg/tools/web.go index 059437889..452e95e0f 100644 --- a/pkg/tools/web.go +++ b/pkg/tools/web.go @@ -102,7 +102,7 @@ func (p *TavilySearchProvider) Search(ctx context.Context, query string, count i "search_depth": "advanced", "include_answer": false, "include_images": false, - "include_raw_content": "false", + "include_raw_content": false, "max_results": count, } From 712f5a8300f0ce9d9d22352a1bc92bed3a0c8b88 Mon Sep 17 00:00:00 2001 From: yinwm Date: Mon, 23 Feb 2026 16:55:06 +0800 Subject: [PATCH 24/40] refactor(config): rename model field to model_name The configuration field for specifying the model has been renamed from "model" to "model_name" for better clarity and consistency with the model_list configuration. A GetModelName() accessor method has been added to maintain backward compatibility. Existing configurations using the old "model" field will continue to work correctly. This change affects: - Configuration structure (AgentDefaults struct) - All references across the codebase - Documentation in all language variants - Example configuration files --- README.fr.md | 2 +- README.ja.md | 2 +- README.md | 2 +- README.pt-br.md | 2 +- README.vi.md | 2 +- README.zh.md | 2 +- cmd/picoclaw/cmd_agent.go | 4 +- cmd/picoclaw/cmd_auth.go | 10 +-- cmd/picoclaw/cmd_gateway.go | 2 +- cmd/picoclaw/cmd_status.go | 2 +- config/config.example.json | 2 +- pkg/agent/instance.go | 2 +- pkg/channels/telegram_commands.go | 4 +- pkg/config/config.go | 12 ++- pkg/config/migration.go | 2 +- pkg/config/model_config_test.go | 132 ++++++++++++++++++++++++++++++ pkg/migrate/config.go | 5 +- pkg/providers/factory.go | 2 +- pkg/providers/legacy_provider.go | 2 +- 19 files changed, 169 insertions(+), 24 deletions(-) diff --git a/README.fr.md b/README.fr.md index 7199f7098..04f40e022 100644 --- a/README.fr.md +++ b/README.fr.md @@ -222,7 +222,7 @@ picoclaw onboard ], "agents": { "defaults": { - "model": "gpt4" + "model_name": "gpt4" } }, "channels": { diff --git a/README.ja.md b/README.ja.md index bb0bdfb28..b379bc2a7 100644 --- a/README.ja.md +++ b/README.ja.md @@ -184,7 +184,7 @@ picoclaw onboard ], "agents": { "defaults": { - "model": "gpt4" + "model_name": "gpt4" } }, "channels": { diff --git a/README.md b/README.md index 7bc7b1089..058e16a2b 100644 --- a/README.md +++ b/README.md @@ -209,7 +209,7 @@ picoclaw onboard "agents": { "defaults": { "workspace": "~/.picoclaw/workspace", - "model": "gpt4", + "model_name": "gpt4", "max_tokens": 8192, "temperature": 0.7, "max_tool_iterations": 20 diff --git a/README.pt-br.md b/README.pt-br.md index ec8fe8e1c..cfa5b801b 100644 --- a/README.pt-br.md +++ b/README.pt-br.md @@ -223,7 +223,7 @@ picoclaw onboard ], "agents": { "defaults": { - "model": "gpt4" + "model_name": "gpt4" } }, "tools": { diff --git a/README.vi.md b/README.vi.md index 161842933..1d0084aa3 100644 --- a/README.vi.md +++ b/README.vi.md @@ -203,7 +203,7 @@ picoclaw onboard ], "agents": { "defaults": { - "model": "gpt4" + "model_name": "gpt4" } }, "channels": { diff --git a/README.zh.md b/README.zh.md index 4d739c5eb..dca149fa9 100644 --- a/README.zh.md +++ b/README.zh.md @@ -221,7 +221,7 @@ picoclaw onboard "agents": { "defaults": { "workspace": "~/.picoclaw/workspace", - "model": "gpt4", + "model_name": "gpt4", "max_tokens": 8192, "temperature": 0.7, "max_tool_iterations": 20 diff --git a/cmd/picoclaw/cmd_agent.go b/cmd/picoclaw/cmd_agent.go index 6d6ff935f..6331fdd4a 100644 --- a/cmd/picoclaw/cmd_agent.go +++ b/cmd/picoclaw/cmd_agent.go @@ -56,7 +56,7 @@ func agentCmd() { } if modelOverride != "" { - cfg.Agents.Defaults.Model = modelOverride + cfg.Agents.Defaults.ModelName = modelOverride } provider, modelID, err := providers.CreateProvider(cfg) @@ -66,7 +66,7 @@ func agentCmd() { } // Use the resolved model ID from provider creation if modelID != "" { - cfg.Agents.Defaults.Model = modelID + cfg.Agents.Defaults.ModelName = modelID } msgBus := bus.NewMessageBus() diff --git a/cmd/picoclaw/cmd_auth.go b/cmd/picoclaw/cmd_auth.go index 729c56177..55eb3cec3 100644 --- a/cmd/picoclaw/cmd_auth.go +++ b/cmd/picoclaw/cmd_auth.go @@ -144,7 +144,7 @@ func authLoginOpenAI(useDeviceCode bool) { } // Update default model to use OpenAI - appCfg.Agents.Defaults.Model = "gpt-5.2" + appCfg.Agents.Defaults.ModelName = "gpt-5.2" if err := config.SaveConfig(getConfigPath(), appCfg); err != nil { fmt.Printf("Warning: could not update config: %v\n", err) @@ -218,7 +218,7 @@ func authLoginGoogleAntigravity() { } // Update default model - appCfg.Agents.Defaults.Model = "gemini-flash" + appCfg.Agents.Defaults.ModelName = "gemini-flash" if err := config.SaveConfig(getConfigPath(), appCfg); err != nil { fmt.Printf("Warning: could not update config: %v\n", err) @@ -292,7 +292,7 @@ func authLoginPasteToken(provider string) { }) } // Update default model - appCfg.Agents.Defaults.Model = "claude-sonnet-4.6" + appCfg.Agents.Defaults.ModelName = "claude-sonnet-4.6" case "openai": appCfg.Providers.OpenAI.AuthMethod = "token" // Update ModelList @@ -312,7 +312,7 @@ func authLoginPasteToken(provider string) { }) } // Update default model - appCfg.Agents.Defaults.Model = "gpt-5.2" + appCfg.Agents.Defaults.ModelName = "gpt-5.2" } if err := config.SaveConfig(getConfigPath(), appCfg); err != nil { fmt.Printf("Warning: could not update config: %v\n", err) @@ -320,7 +320,7 @@ func authLoginPasteToken(provider string) { } fmt.Printf("Token saved for %s!\n", provider) - fmt.Printf("Default model set to: %s\n", appCfg.Agents.Defaults.Model) + fmt.Printf("Default model set to: %s\n", appCfg.Agents.Defaults.GetModelName()) } func authLogoutCmd() { diff --git a/cmd/picoclaw/cmd_gateway.go b/cmd/picoclaw/cmd_gateway.go index 9a3b6aa19..bd1cdd7a8 100644 --- a/cmd/picoclaw/cmd_gateway.go +++ b/cmd/picoclaw/cmd_gateway.go @@ -51,7 +51,7 @@ func gatewayCmd() { } // Use the resolved model ID from provider creation if modelID != "" { - cfg.Agents.Defaults.Model = modelID + cfg.Agents.Defaults.ModelName = modelID } msgBus := bus.NewMessageBus() diff --git a/cmd/picoclaw/cmd_status.go b/cmd/picoclaw/cmd_status.go index 07296784e..6a117bd17 100644 --- a/cmd/picoclaw/cmd_status.go +++ b/cmd/picoclaw/cmd_status.go @@ -41,7 +41,7 @@ func statusCmd() { } if _, err := os.Stat(configPath); err == nil { - fmt.Printf("Model: %s\n", cfg.Agents.Defaults.Model) + fmt.Printf("Model: %s\n", cfg.Agents.Defaults.GetModelName()) hasOpenRouter := cfg.Providers.OpenRouter.APIKey != "" hasAnthropic := cfg.Providers.Anthropic.APIKey != "" diff --git a/config/config.example.json b/config/config.example.json index 77a8c0683..1795fed9f 100644 --- a/config/config.example.json +++ b/config/config.example.json @@ -3,7 +3,7 @@ "defaults": { "workspace": "~/.picoclaw/workspace", "restrict_to_workspace": true, - "model": "gpt4", + "model_name": "gpt4", "max_tokens": 8192, "temperature": 0.7, "max_tool_iterations": 20 diff --git a/pkg/agent/instance.go b/pkg/agent/instance.go index dfbef9fbc..c6a54c7d2 100644 --- a/pkg/agent/instance.go +++ b/pkg/agent/instance.go @@ -133,7 +133,7 @@ func resolveAgentModel(agentCfg *config.AgentConfig, defaults *config.AgentDefau if agentCfg != nil && agentCfg.Model != nil && strings.TrimSpace(agentCfg.Model.Primary) != "" { return strings.TrimSpace(agentCfg.Model.Primary) } - return defaults.Model + return defaults.GetModelName() } // resolveAgentFallbacks resolves the fallback models for an agent. diff --git a/pkg/channels/telegram_commands.go b/pkg/channels/telegram_commands.go index a084b641b..f28434f46 100644 --- a/pkg/channels/telegram_commands.go +++ b/pkg/channels/telegram_commands.go @@ -81,7 +81,7 @@ func (c *cmd) Show(ctx context.Context, message telego.Message) error { switch args { case "model": response = fmt.Sprintf("Current Model: %s (Provider: %s)", - c.config.Agents.Defaults.Model, + c.config.Agents.Defaults.GetModelName(), c.config.Agents.Defaults.Provider) case "channel": response = "Current Channel: telegram" @@ -120,7 +120,7 @@ func (c *cmd) List(ctx context.Context, message telego.Message) error { provider = "configured default" } response = fmt.Sprintf("Configured Model: %s\nProvider: %s\n\nTo change models, update config.yaml", - c.config.Agents.Defaults.Model, provider) + c.config.Agents.Defaults.GetModelName(), provider) case "channels": var enabled []string diff --git a/pkg/config/config.go b/pkg/config/config.go index 20556011a..c103963c8 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -170,7 +170,8 @@ type AgentDefaults struct { Workspace string `json:"workspace" env:"PICOCLAW_AGENTS_DEFAULTS_WORKSPACE"` RestrictToWorkspace bool `json:"restrict_to_workspace" env:"PICOCLAW_AGENTS_DEFAULTS_RESTRICT_TO_WORKSPACE"` Provider string `json:"provider" env:"PICOCLAW_AGENTS_DEFAULTS_PROVIDER"` - Model string `json:"model" env:"PICOCLAW_AGENTS_DEFAULTS_MODEL"` + ModelName string `json:"model_name,omitempty" env:"PICOCLAW_AGENTS_DEFAULTS_MODEL_NAME"` + Model string `json:"model,omitempty" env:"PICOCLAW_AGENTS_DEFAULTS_MODEL"` // Deprecated: use model_name instead ModelFallbacks []string `json:"model_fallbacks,omitempty"` ImageModel string `json:"image_model,omitempty" env:"PICOCLAW_AGENTS_DEFAULTS_IMAGE_MODEL"` ImageModelFallbacks []string `json:"image_model_fallbacks,omitempty"` @@ -179,6 +180,15 @@ type AgentDefaults struct { MaxToolIterations int `json:"max_tool_iterations" env:"PICOCLAW_AGENTS_DEFAULTS_MAX_TOOL_ITERATIONS"` } +// GetModelName returns the effective model name for the agent defaults. +// It prefers the new "model_name" field but falls back to "model" for backward compatibility. +func (d *AgentDefaults) GetModelName() string { + if d.ModelName != "" { + return d.ModelName + } + return d.Model +} + type ChannelsConfig struct { WhatsApp WhatsAppConfig `json:"whatsapp"` Telegram TelegramConfig `json:"telegram"` diff --git a/pkg/config/migration.go b/pkg/config/migration.go index 689e2312f..e51d4efb2 100644 --- a/pkg/config/migration.go +++ b/pkg/config/migration.go @@ -41,7 +41,7 @@ func ConvertProvidersToModelList(cfg *Config) []ModelConfig { // Get user's configured provider and model userProvider := strings.ToLower(cfg.Agents.Defaults.Provider) - userModel := cfg.Agents.Defaults.Model + userModel := cfg.Agents.Defaults.GetModelName() p := cfg.Providers diff --git a/pkg/config/model_config_test.go b/pkg/config/model_config_test.go index 3c411dc0f..c89029e8c 100644 --- a/pkg/config/model_config_test.go +++ b/pkg/config/model_config_test.go @@ -6,6 +6,7 @@ package config import ( + "encoding/json" "strings" "sync" "testing" @@ -114,6 +115,137 @@ func TestGetModelConfig_Concurrent(t *testing.T) { } } +func TestAgentDefaults_GetModelName_BackwardCompat(t *testing.T) { + tests := []struct { + name string + defaults AgentDefaults + wantName string + }{ + { + name: "new model_name field only", + defaults: AgentDefaults{ModelName: "new-model"}, + wantName: "new-model", + }, + { + name: "old model field only", + defaults: AgentDefaults{Model: "legacy-model"}, + wantName: "legacy-model", + }, + { + name: "both fields - model_name takes precedence", + defaults: AgentDefaults{ModelName: "new-model", Model: "old-model"}, + wantName: "new-model", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.defaults.GetModelName(); got != tt.wantName { + t.Errorf("GetModelName() = %q, want %q", got, tt.wantName) + } + }) + } +} + +func TestAgentDefaults_JSON_BackwardCompat(t *testing.T) { + tests := []struct { + name string + json string + wantName string + }{ + { + name: "new model_name field", + json: `{"model_name": "gpt4"}`, + wantName: "gpt4", + }, + { + name: "old model field", + json: `{"model": "gpt4"}`, + wantName: "gpt4", + }, + { + name: "both fields - model_name wins", + json: `{"model_name": "new", "model": "old"}`, + wantName: "new", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var defaults AgentDefaults + if err := json.Unmarshal([]byte(tt.json), &defaults); err != nil { + t.Fatalf("Unmarshal error: %v", err) + } + if got := defaults.GetModelName(); got != tt.wantName { + t.Errorf("GetModelName() = %q, want %q", got, tt.wantName) + } + }) + } +} + +func TestFullConfig_JSON_BackwardCompat(t *testing.T) { + // Test complete config with both old and new formats + oldFormat := `{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "model": "gpt4", + "max_tokens": 4096 + } + }, + "model_list": [ + { + "model_name": "gpt4", + "model": "openai/gpt-4o", + "api_key": "test-key" + } + ] + }` + + newFormat := `{ + "agents": { + "defaults": { + "workspace": "~/.picoclaw/workspace", + "model_name": "gpt4", + "max_tokens": 4096 + } + }, + "model_list": [ + { + "model_name": "gpt4", + "model": "openai/gpt-4o", + "api_key": "test-key" + } + ] + }` + + for name, jsonStr := range map[string]string{ + "old format (model)": oldFormat, + "new format (model_name)": newFormat, + } { + t.Run(name, func(t *testing.T) { + cfg := &Config{} + if err := json.Unmarshal([]byte(jsonStr), cfg); err != nil { + t.Fatalf("Unmarshal error: %v", err) + } + + // Check that GetModelName returns correct value + if got := cfg.Agents.Defaults.GetModelName(); got != "gpt4" { + t.Errorf("GetModelName() = %q, want %q", got, "gpt4") + } + + // Check that GetModelConfig works + modelCfg, err := cfg.GetModelConfig("gpt4") + if err != nil { + t.Fatalf("GetModelConfig error: %v", err) + } + if modelCfg.Model != "openai/gpt-4o" { + t.Errorf("Model = %q, want %q", modelCfg.Model, "openai/gpt-4o") + } + }) + } +} + func TestModelConfig_Validate(t *testing.T) { tests := []struct { name string diff --git a/pkg/migrate/config.go b/pkg/migrate/config.go index 2237a1429..d9552db9f 100644 --- a/pkg/migrate/config.go +++ b/pkg/migrate/config.go @@ -72,7 +72,10 @@ func ConvertConfig(data map[string]any) (*config.Config, []string, error) { if agents, ok := getMap(data, "agents"); ok { if defaults, ok := getMap(agents, "defaults"); ok { - if v, ok := getString(defaults, "model"); ok { + // Prefer model_name, fallback to model for backward compatibility + if v, ok := getString(defaults, "model_name"); ok { + cfg.Agents.Defaults.ModelName = v + } else if v, ok := getString(defaults, "model"); ok { cfg.Agents.Defaults.Model = v } if v, ok := getFloat(defaults, "max_tokens"); ok { diff --git a/pkg/providers/factory.go b/pkg/providers/factory.go index b6f1b5e21..b9abfdc61 100644 --- a/pkg/providers/factory.go +++ b/pkg/providers/factory.go @@ -36,7 +36,7 @@ type providerSelection struct { } func resolveProviderSelection(cfg *config.Config) (providerSelection, error) { - model := cfg.Agents.Defaults.Model + model := cfg.Agents.Defaults.GetModelName() providerName := strings.ToLower(cfg.Agents.Defaults.Provider) lowerModel := strings.ToLower(model) diff --git a/pkg/providers/legacy_provider.go b/pkg/providers/legacy_provider.go index eb13cec65..23f137538 100644 --- a/pkg/providers/legacy_provider.go +++ b/pkg/providers/legacy_provider.go @@ -16,7 +16,7 @@ import ( // The old providers config is automatically converted to model_list during config loading. // Returns the provider, the model ID to use, and any error. func CreateProvider(cfg *config.Config) (LLMProvider, string, error) { - model := cfg.Agents.Defaults.Model + model := cfg.Agents.Defaults.GetModelName() // Ensure model_list is populated (should be done by LoadConfig, but handle edge cases) if len(cfg.ModelList) == 0 && cfg.HasProvidersConfig() { From 19c698356c2aef8f618a110acef671def19f5261 Mon Sep 17 00:00:00 2001 From: 0x5487 Date: Mon, 23 Feb 2026 17:09:53 +0800 Subject: [PATCH 25/40] fix(security): workspace sandbox avoid time-of-check/time-of-use (TOCTOU) races (#464) * chore: Update default host bindings from 0.0.0.0 to 127.0.0.1 for various services and examples. * config: Update default host bindings to 0.0.0.0 for improved Docker accessibility and add related documentation. * refactor: reimplement filesystem tools with `os.OpenRoot` for enhanced security and simplified path validation. * chore: revert other PR content from this branch * docs: Update Chinese README. * docs: Update Chinese README. * docs: Update Chinese README. * refactor: Reorder filesystem helper functions, extract directory entry formatting logic, and enhance `WriteFileTool`'s result message. * feat: Enhance `mkdirAllInRoot` to prevent creating directories over existing files and add tests for directory creation functionality. * Refactor filesystem tools to use a `fileReadWriter` interface for both host and sandboxed I/O, improving atomic writes and error handling. * refactor: unify filesystem read/write operations with atomic write guarantees and clearer naming. * refactor: rename `appendFileWithRW` function to `appendFile` * refactor: unify filesystem access by introducing a `fileSystem` interface and updating tools to use it directly, removing `os.Root` dependency from `sandboxFs`. * chore: run make fmt * fix: `validatePath` now returns an error when the workspace is empty. --- pkg/tools/edit.go | 118 ++++++++++-------- pkg/tools/edit_test.go | 160 +++++++++++++++++++++++- pkg/tools/filesystem.go | 234 +++++++++++++++++++++++++++++------ pkg/tools/filesystem_test.go | 227 +++++++++++++++++++++++++++++++-- 4 files changed, 630 insertions(+), 109 deletions(-) diff --git a/pkg/tools/edit.go b/pkg/tools/edit.go index c28ca6ca2..d3ab267bf 100644 --- a/pkg/tools/edit.go +++ b/pkg/tools/edit.go @@ -2,24 +2,27 @@ package tools import ( "context" + "errors" "fmt" - "os" + "io/fs" "strings" ) // EditFileTool edits a file by replacing old_text with new_text. // The old_text must exist exactly in the file. type EditFileTool struct { - allowedDir string - restrict bool + fs fileSystem } // NewEditFileTool creates a new EditFileTool with optional directory restriction. -func NewEditFileTool(allowedDir string, restrict bool) *EditFileTool { - return &EditFileTool{ - allowedDir: allowedDir, - restrict: restrict, +func NewEditFileTool(workspace string, restrict bool) *EditFileTool { + var fs fileSystem + if restrict { + fs = &sandboxFs{workspace: workspace} + } else { + fs = &hostFs{} } + return &EditFileTool{fs: fs} } func (t *EditFileTool) Name() string { @@ -67,49 +70,24 @@ func (t *EditFileTool) Execute(ctx context.Context, args map[string]any) *ToolRe return ErrorResult("new_text is required") } - resolvedPath, err := validatePath(path, t.allowedDir, t.restrict) - if err != nil { + if err := editFile(t.fs, path, oldText, newText); err != nil { return ErrorResult(err.Error()) } - - if _, err = os.Stat(resolvedPath); os.IsNotExist(err) { - return ErrorResult(fmt.Sprintf("file not found: %s", path)) - } - - content, err := os.ReadFile(resolvedPath) - if err != nil { - return ErrorResult(fmt.Sprintf("failed to read file: %v", err)) - } - - contentStr := string(content) - - if !strings.Contains(contentStr, oldText) { - return ErrorResult("old_text not found in file. Make sure it matches exactly") - } - - count := strings.Count(contentStr, oldText) - if count > 1 { - return ErrorResult( - fmt.Sprintf("old_text appears %d times. Please provide more context to make it unique", count), - ) - } - - newContent := strings.Replace(contentStr, oldText, newText, 1) - - if err := os.WriteFile(resolvedPath, []byte(newContent), 0o644); err != nil { - return ErrorResult(fmt.Sprintf("failed to write file: %v", err)) - } - return SilentResult(fmt.Sprintf("File edited: %s", path)) } type AppendFileTool struct { - workspace string - restrict bool + fs fileSystem } func NewAppendFileTool(workspace string, restrict bool) *AppendFileTool { - return &AppendFileTool{workspace: workspace, restrict: restrict} + var fs fileSystem + if restrict { + fs = &sandboxFs{workspace: workspace} + } else { + fs = &hostFs{} + } + return &AppendFileTool{fs: fs} } func (t *AppendFileTool) Name() string { @@ -148,20 +126,52 @@ func (t *AppendFileTool) Execute(ctx context.Context, args map[string]any) *Tool return ErrorResult("content is required") } - resolvedPath, err := validatePath(path, t.workspace, t.restrict) - if err != nil { + if err := appendFile(t.fs, path, content); err != nil { return ErrorResult(err.Error()) } - - f, err := os.OpenFile(resolvedPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644) - if err != nil { - return ErrorResult(fmt.Sprintf("failed to open file: %v", err)) - } - defer f.Close() - - if _, err := f.WriteString(content); err != nil { - return ErrorResult(fmt.Sprintf("failed to append to file: %v", err)) - } - return SilentResult(fmt.Sprintf("Appended to %s", path)) } + +// editFile reads the file via sysFs, performs the replacement, and writes back. +// It uses a fileSystem interface, allowing the same logic for both restricted and unrestricted modes. +func editFile(sysFs fileSystem, path, oldText, newText string) error { + content, err := sysFs.ReadFile(path) + if err != nil { + return err + } + + newContent, err := replaceEditContent(content, oldText, newText) + if err != nil { + return err + } + + return sysFs.WriteFile(path, newContent) +} + +// appendFile reads the existing content (if any) via sysFs, appends new content, and writes back. +func appendFile(sysFs fileSystem, path, appendContent string) error { + content, err := sysFs.ReadFile(path) + if err != nil && !errors.Is(err, fs.ErrNotExist) { + return err + } + + newContent := append(content, []byte(appendContent)...) + return sysFs.WriteFile(path, newContent) +} + +// replaceEditContent handles the core logic of finding and replacing a single occurrence of oldText. +func replaceEditContent(content []byte, oldText, newText string) ([]byte, error) { + contentStr := string(content) + + if !strings.Contains(contentStr, oldText) { + return nil, fmt.Errorf("old_text not found in file. Make sure it matches exactly") + } + + count := strings.Count(contentStr, oldText) + if count > 1 { + return nil, fmt.Errorf("old_text appears %d times. Please provide more context to make it unique", count) + } + + newContent := strings.Replace(contentStr, oldText, newText, 1) + return []byte(newContent), nil +} diff --git a/pkg/tools/edit_test.go b/pkg/tools/edit_test.go index 6780dd9f6..83a7e778c 100644 --- a/pkg/tools/edit_test.go +++ b/pkg/tools/edit_test.go @@ -6,6 +6,8 @@ import ( "path/filepath" "strings" "testing" + + "github.com/stretchr/testify/assert" ) // TestEditTool_EditFile_Success verifies successful file editing @@ -151,14 +153,18 @@ func TestEditTool_EditFile_OutsideAllowedDir(t *testing.T) { result := tool.Execute(ctx, args) // Should return error result - if !result.IsError { - t.Errorf("Expected error when path is outside allowed directory") - } + assert.True(t, result.IsError, "Expected error when path is outside allowed directory") // Should mention outside allowed directory - if !strings.Contains(result.ForLLM, "outside") && !strings.Contains(result.ForUser, "outside") { - t.Errorf("Expected 'outside allowed' message, got ForLLM: %s", result.ForLLM) - } + // Note: ErrorResult only sets ForLLM by default, so ForUser might be empty. + // We check ForLLM as it's the primary error channel. + assert.True( + t, + strings.Contains(result.ForLLM, "outside") || strings.Contains(result.ForLLM, "access denied") || + strings.Contains(result.ForLLM, "escapes"), + "Expected 'outside allowed' or 'access denied' message, got ForLLM: %s", + result.ForLLM, + ) } // TestEditTool_EditFile_MissingPath verifies error handling for missing path @@ -287,3 +293,145 @@ func TestEditTool_AppendFile_MissingContent(t *testing.T) { t.Errorf("Expected error when content is missing") } } + +// TestReplaceEditContent verifies the helper function replaceEditContent +func TestReplaceEditContent(t *testing.T) { + tests := []struct { + name string + content []byte + oldText string + newText string + expected []byte + expectError bool + }{ + { + name: "successful replacement", + content: []byte("hello world"), + oldText: "world", + newText: "universe", + expected: []byte("hello universe"), + expectError: false, + }, + { + name: "old text not found", + content: []byte("hello world"), + oldText: "golang", + newText: "rust", + expected: nil, + expectError: true, + }, + { + name: "multiple matches found", + content: []byte("test text test"), + oldText: "test", + newText: "done", + expected: nil, + expectError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := replaceEditContent(tt.content, tt.oldText, tt.newText) + if tt.expectError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.expected, result) + } + }) + } +} + +// TestAppendFileTool_AppendToNonExistent_Restricted verifies that AppendFileTool in restricted mode +// can append to a file that does not yet exist — it should silently create the file. +// This exercises the errors.Is(err, fs.ErrNotExist) path in appendFileWithRW + rootRW. +func TestAppendFileTool_AppendToNonExistent_Restricted(t *testing.T) { + workspace := t.TempDir() + tool := NewAppendFileTool(workspace, true) + ctx := context.Background() + + args := map[string]any{ + "path": "brand_new_file.txt", + "content": "first content", + } + + result := tool.Execute(ctx, args) + assert.False( + t, + result.IsError, + "Expected success when appending to non-existent file in restricted mode, got: %s", + result.ForLLM, + ) + + // Verify the file was created with correct content + data, err := os.ReadFile(filepath.Join(workspace, "brand_new_file.txt")) + assert.NoError(t, err) + assert.Equal(t, "first content", string(data)) +} + +// TestAppendFileTool_Restricted_Success verifies that AppendFileTool in restricted mode +// correctly appends to an existing file within the sandbox. +func TestAppendFileTool_Restricted_Success(t *testing.T) { + workspace := t.TempDir() + testFile := "existing.txt" + err := os.WriteFile(filepath.Join(workspace, testFile), []byte("initial"), 0o644) + assert.NoError(t, err) + + tool := NewAppendFileTool(workspace, true) + ctx := context.Background() + args := map[string]any{ + "path": testFile, + "content": " appended", + } + + result := tool.Execute(ctx, args) + assert.False(t, result.IsError, "Expected success, got: %s", result.ForLLM) + assert.True(t, result.Silent) + + data, err := os.ReadFile(filepath.Join(workspace, testFile)) + assert.NoError(t, err) + assert.Equal(t, "initial appended", string(data)) +} + +// TestEditFileTool_Restricted_InPlaceEdit verifies that EditFileTool in restricted mode +// correctly edits a file using the single-open editFileInRoot path. +func TestEditFileTool_Restricted_InPlaceEdit(t *testing.T) { + workspace := t.TempDir() + testFile := "edit_target.txt" + err := os.WriteFile(filepath.Join(workspace, testFile), []byte("Hello World"), 0o644) + assert.NoError(t, err) + + tool := NewEditFileTool(workspace, true) + ctx := context.Background() + args := map[string]any{ + "path": testFile, + "old_text": "World", + "new_text": "Go", + } + + result := tool.Execute(ctx, args) + assert.False(t, result.IsError, "Expected success, got: %s", result.ForLLM) + assert.True(t, result.Silent) + + data, err := os.ReadFile(filepath.Join(workspace, testFile)) + assert.NoError(t, err) + assert.Equal(t, "Hello Go", string(data)) +} + +// TestEditFileTool_Restricted_FileNotFound verifies that editFileInRoot returns a proper +// error message when the target file does not exist. +func TestEditFileTool_Restricted_FileNotFound(t *testing.T) { + workspace := t.TempDir() + tool := NewEditFileTool(workspace, true) + ctx := context.Background() + args := map[string]any{ + "path": "no_such_file.txt", + "old_text": "old", + "new_text": "new", + } + + result := tool.Execute(ctx, args) + assert.True(t, result.IsError) + assert.Contains(t, result.ForLLM, "not found") +} diff --git a/pkg/tools/filesystem.go b/pkg/tools/filesystem.go index 1bf50906e..37db8b4ae 100644 --- a/pkg/tools/filesystem.go +++ b/pkg/tools/filesystem.go @@ -3,15 +3,17 @@ package tools import ( "context" "fmt" + "io/fs" "os" "path/filepath" "strings" + "time" ) // validatePath ensures the given path is within the workspace if restrict is true. func validatePath(path, workspace string, restrict bool) (string, error) { if workspace == "" { - return path, nil + return path, fmt.Errorf("workspace is not defined") } absWorkspace, err := filepath.Abs(workspace) @@ -76,16 +78,21 @@ func resolveExistingAncestor(path string) (string, error) { func isWithinWorkspace(candidate, workspace string) bool { rel, err := filepath.Rel(filepath.Clean(workspace), filepath.Clean(candidate)) - return err == nil && rel != ".." && !strings.HasPrefix(rel, ".."+string(os.PathSeparator)) + return err == nil && filepath.IsLocal(rel) } type ReadFileTool struct { - workspace string - restrict bool + fs fileSystem } func NewReadFileTool(workspace string, restrict bool) *ReadFileTool { - return &ReadFileTool{workspace: workspace, restrict: restrict} + var fs fileSystem + if restrict { + fs = &sandboxFs{workspace: workspace} + } else { + fs = &hostFs{} + } + return &ReadFileTool{fs: fs} } func (t *ReadFileTool) Name() string { @@ -115,26 +122,25 @@ func (t *ReadFileTool) Execute(ctx context.Context, args map[string]any) *ToolRe return ErrorResult("path is required") } - resolvedPath, err := validatePath(path, t.workspace, t.restrict) + content, err := t.fs.ReadFile(path) if err != nil { return ErrorResult(err.Error()) } - - content, err := os.ReadFile(resolvedPath) - if err != nil { - return ErrorResult(fmt.Sprintf("failed to read file: %v", err)) - } - return NewToolResult(string(content)) } type WriteFileTool struct { - workspace string - restrict bool + fs fileSystem } func NewWriteFileTool(workspace string, restrict bool) *WriteFileTool { - return &WriteFileTool{workspace: workspace, restrict: restrict} + var fs fileSystem + if restrict { + fs = &sandboxFs{workspace: workspace} + } else { + fs = &hostFs{} + } + return &WriteFileTool{fs: fs} } func (t *WriteFileTool) Name() string { @@ -173,30 +179,25 @@ func (t *WriteFileTool) Execute(ctx context.Context, args map[string]any) *ToolR return ErrorResult("content is required") } - resolvedPath, err := validatePath(path, t.workspace, t.restrict) - if err != nil { + if err := t.fs.WriteFile(path, []byte(content)); err != nil { return ErrorResult(err.Error()) } - dir := filepath.Dir(resolvedPath) - if err := os.MkdirAll(dir, 0o755); err != nil { - return ErrorResult(fmt.Sprintf("failed to create directory: %v", err)) - } - - if err := os.WriteFile(resolvedPath, []byte(content), 0o644); err != nil { - return ErrorResult(fmt.Sprintf("failed to write file: %v", err)) - } - return SilentResult(fmt.Sprintf("File written: %s", path)) } type ListDirTool struct { - workspace string - restrict bool + fs fileSystem } func NewListDirTool(workspace string, restrict bool) *ListDirTool { - return &ListDirTool{workspace: workspace, restrict: restrict} + var fs fileSystem + if restrict { + fs = &sandboxFs{workspace: workspace} + } else { + fs = &hostFs{} + } + return &ListDirTool{fs: fs} } func (t *ListDirTool) Name() string { @@ -226,24 +227,179 @@ func (t *ListDirTool) Execute(ctx context.Context, args map[string]any) *ToolRes path = "." } - resolvedPath, err := validatePath(path, t.workspace, t.restrict) - if err != nil { - return ErrorResult(err.Error()) - } - - entries, err := os.ReadDir(resolvedPath) + entries, err := t.fs.ReadDir(path) if err != nil { return ErrorResult(fmt.Sprintf("failed to read directory: %v", err)) } + return formatDirEntries(entries) +} - result := "" +func formatDirEntries(entries []os.DirEntry) *ToolResult { + var result strings.Builder for _, entry := range entries { if entry.IsDir() { - result += "DIR: " + entry.Name() + "\n" + result.WriteString("DIR: " + entry.Name() + "\n") } else { - result += "FILE: " + entry.Name() + "\n" + result.WriteString("FILE: " + entry.Name() + "\n") + } + } + return NewToolResult(result.String()) +} + +// fileSystem abstracts reading, writing, and listing files, allowing both +// unrestricted (host filesystem) and sandbox (os.Root) implementations to share the same polymorphic interface. +type fileSystem interface { + ReadFile(path string) ([]byte, error) + WriteFile(path string, data []byte) error + ReadDir(path string) ([]os.DirEntry, error) +} + +// hostFs is an unrestricted fileReadWriter that operates directly on the host filesystem. +type hostFs struct{} + +func (h *hostFs) ReadFile(path string) ([]byte, error) { + content, err := os.ReadFile(path) + if err != nil { + if os.IsNotExist(err) { + return nil, fmt.Errorf("failed to read file: file not found: %w", err) + } + if os.IsPermission(err) { + return nil, fmt.Errorf("failed to read file: access denied: %w", err) + } + return nil, fmt.Errorf("failed to read file: %w", err) + } + return content, nil +} + +func (h *hostFs) ReadDir(path string) ([]os.DirEntry, error) { + return os.ReadDir(path) +} + +func (h *hostFs) WriteFile(path string, data []byte) error { + dir := filepath.Dir(path) + if err := os.MkdirAll(dir, 0o755); err != nil { + return fmt.Errorf("failed to create parent directories: %w", err) + } + + // We use a "write-then-rename" pattern here to ensure an atomic write. + // This prevents the target file from being left in a truncated or partial state + // if the operation is interrupted, as the rename operation is atomic on Linux. + tmpPath := fmt.Sprintf("%s.%d.tmp", path, time.Now().UnixNano()) + if err := os.WriteFile(tmpPath, data, 0o644); err != nil { + os.Remove(tmpPath) // Ensure cleanup of partial/empty temp file + return fmt.Errorf("failed to write temp file: %w", err) + } + + if err := os.Rename(tmpPath, path); err != nil { + os.Remove(tmpPath) + return fmt.Errorf("failed to replace original file: %w", err) + } + return nil +} + +// sandboxFs is a sandboxed fileSystem that operates within a strictly defined workspace using os.Root. +type sandboxFs struct { + workspace string +} + +func (r *sandboxFs) execute(path string, fn func(root *os.Root, relPath string) error) error { + if r.workspace == "" { + return fmt.Errorf("workspace is not defined") + } + + root, err := os.OpenRoot(r.workspace) + if err != nil { + return fmt.Errorf("failed to open workspace: %w", err) + } + defer root.Close() + + relPath, err := getSafeRelPath(r.workspace, path) + if err != nil { + return err + } + + return fn(root, relPath) +} + +func (r *sandboxFs) ReadFile(path string) ([]byte, error) { + var content []byte + err := r.execute(path, func(root *os.Root, relPath string) error { + fileContent, err := root.ReadFile(relPath) + if err != nil { + if os.IsNotExist(err) { + return fmt.Errorf("failed to read file: file not found: %w", err) + } + // os.Root returns "escapes from parent" for paths outside the root + if os.IsPermission(err) || strings.Contains(err.Error(), "escapes from parent") || + strings.Contains(err.Error(), "permission denied") { + return fmt.Errorf("failed to read file: access denied: %w", err) + } + return fmt.Errorf("failed to read file: %w", err) + } + content = fileContent + return nil + }) + return content, err +} + +func (r *sandboxFs) WriteFile(path string, data []byte) error { + return r.execute(path, func(root *os.Root, relPath string) error { + dir := filepath.Dir(relPath) + if dir != "." && dir != "/" { + if err := root.MkdirAll(dir, 0o755); err != nil { + return fmt.Errorf("failed to create parent directories: %w", err) + } + } + + // We use a "write-then-rename" pattern here to ensure an atomic write. + // This prevents the target file from being left in a truncated or partial state + // if the operation is interrupted, as the rename operation is atomic on Linux. + tmpRelPath := fmt.Sprintf("%s.%d.tmp", relPath, time.Now().UnixNano()) + + if err := root.WriteFile(tmpRelPath, data, 0o644); err != nil { + root.Remove(tmpRelPath) // Ensure cleanup of partial/empty temp file + return fmt.Errorf("failed to write to temp file: %w", err) + } + + if err := root.Rename(tmpRelPath, relPath); err != nil { + root.Remove(tmpRelPath) + return fmt.Errorf("failed to rename temp file over target: %w", err) + } + return nil + }) +} + +func (r *sandboxFs) ReadDir(path string) ([]os.DirEntry, error) { + var entries []os.DirEntry + err := r.execute(path, func(root *os.Root, relPath string) error { + dirEntries, err := fs.ReadDir(root.FS(), relPath) + if err != nil { + return err + } + entries = dirEntries + return nil + }) + return entries, err +} + +// Helper to get a safe relative path for os.Root usage +func getSafeRelPath(workspace, path string) (string, error) { + if workspace == "" { + return "", fmt.Errorf("workspace is not defined") + } + + rel := filepath.Clean(path) + if filepath.IsAbs(rel) { + var err error + rel, err = filepath.Rel(workspace, rel) + if err != nil { + return "", fmt.Errorf("failed to calculate relative path: %w", err) } } - return NewToolResult(result) + if !filepath.IsLocal(rel) { + return "", fmt.Errorf("path escapes workspace: %s", path) + } + + return rel, nil } diff --git a/pkg/tools/filesystem_test.go b/pkg/tools/filesystem_test.go index 5daa3dcea..6f896e22d 100644 --- a/pkg/tools/filesystem_test.go +++ b/pkg/tools/filesystem_test.go @@ -2,10 +2,13 @@ package tools import ( "context" + "io" "os" "path/filepath" "strings" "testing" + + "github.com/stretchr/testify/assert" ) // TestFilesystemTool_ReadFile_Success verifies successful file reading @@ -14,7 +17,7 @@ func TestFilesystemTool_ReadFile_Success(t *testing.T) { testFile := filepath.Join(tmpDir, "test.txt") os.WriteFile(testFile, []byte("test content"), 0o644) - tool := &ReadFileTool{} + tool := NewReadFileTool("", false) ctx := context.Background() args := map[string]any{ "path": testFile, @@ -41,7 +44,7 @@ func TestFilesystemTool_ReadFile_Success(t *testing.T) { // TestFilesystemTool_ReadFile_NotFound verifies error handling for missing file func TestFilesystemTool_ReadFile_NotFound(t *testing.T) { - tool := &ReadFileTool{} + tool := NewReadFileTool("", false) ctx := context.Background() args := map[string]any{ "path": "/nonexistent_file_12345.txt", @@ -84,7 +87,7 @@ func TestFilesystemTool_WriteFile_Success(t *testing.T) { tmpDir := t.TempDir() testFile := filepath.Join(tmpDir, "newfile.txt") - tool := &WriteFileTool{} + tool := NewWriteFileTool("", false) ctx := context.Background() args := map[string]any{ "path": testFile, @@ -123,7 +126,7 @@ func TestFilesystemTool_WriteFile_CreateDir(t *testing.T) { tmpDir := t.TempDir() testFile := filepath.Join(tmpDir, "subdir", "newfile.txt") - tool := &WriteFileTool{} + tool := NewWriteFileTool("", false) ctx := context.Background() args := map[string]any{ "path": testFile, @@ -149,7 +152,7 @@ func TestFilesystemTool_WriteFile_CreateDir(t *testing.T) { // TestFilesystemTool_WriteFile_MissingPath verifies error handling for missing path func TestFilesystemTool_WriteFile_MissingPath(t *testing.T) { - tool := &WriteFileTool{} + tool := NewWriteFileTool("", false) ctx := context.Background() args := map[string]any{ "content": "test", @@ -165,7 +168,7 @@ func TestFilesystemTool_WriteFile_MissingPath(t *testing.T) { // TestFilesystemTool_WriteFile_MissingContent verifies error handling for missing content func TestFilesystemTool_WriteFile_MissingContent(t *testing.T) { - tool := &WriteFileTool{} + tool := NewWriteFileTool("", false) ctx := context.Background() args := map[string]any{ "path": "/tmp/test.txt", @@ -192,7 +195,7 @@ func TestFilesystemTool_ListDir_Success(t *testing.T) { os.WriteFile(filepath.Join(tmpDir, "file2.txt"), []byte("content"), 0o644) os.Mkdir(filepath.Join(tmpDir, "subdir"), 0o755) - tool := &ListDirTool{} + tool := NewListDirTool("", false) ctx := context.Background() args := map[string]any{ "path": tmpDir, @@ -216,7 +219,7 @@ func TestFilesystemTool_ListDir_Success(t *testing.T) { // TestFilesystemTool_ListDir_NotFound verifies error handling for non-existent directory func TestFilesystemTool_ListDir_NotFound(t *testing.T) { - tool := &ListDirTool{} + tool := NewListDirTool("", false) ctx := context.Background() args := map[string]any{ "path": "/nonexistent_directory_12345", @@ -237,7 +240,7 @@ func TestFilesystemTool_ListDir_NotFound(t *testing.T) { // TestFilesystemTool_ListDir_DefaultPath verifies default to current directory func TestFilesystemTool_ListDir_DefaultPath(t *testing.T) { - tool := &ListDirTool{} + tool := NewListDirTool("", false) ctx := context.Background() args := map[string]any{} @@ -275,7 +278,211 @@ func TestFilesystemTool_ReadFile_RejectsSymlinkEscape(t *testing.T) { if !result.IsError { t.Fatalf("expected symlink escape to be blocked") } - if !strings.Contains(result.ForLLM, "symlink resolves outside workspace") { + // os.Root might return different errors depending on platform/implementation + // but it definitely should error. + // Our wrapper returns "access denied or file not found" + if !strings.Contains(result.ForLLM, "access denied") && !strings.Contains(result.ForLLM, "file not found") && + !strings.Contains(result.ForLLM, "no such file") { t.Fatalf("expected symlink escape error, got: %s", result.ForLLM) } } + +func TestFilesystemTool_EmptyWorkspace_AccessDenied(t *testing.T) { + tool := NewReadFileTool("", true) // restrict=true but workspace="" + + // Try to read a sensitive file (simulated by a temp file outside workspace) + tmpDir := t.TempDir() + secretFile := filepath.Join(tmpDir, "shadow") + os.WriteFile(secretFile, []byte("secret data"), 0o600) + + result := tool.Execute(context.Background(), map[string]any{ + "path": secretFile, + }) + + // We EXPECT IsError=true (access blocked due to empty workspace) + assert.True(t, result.IsError, "Security Regression: Empty workspace allowed access! content: %s", result.ForLLM) + + // Verify it failed for the right reason + assert.Contains(t, result.ForLLM, "workspace is not defined", "Expected 'workspace is not defined' error") +} + +// TestRootMkdirAll verifies that root.MkdirAll (used by atomicWriteFileInRoot) handles all cases: +// single dir, deeply nested dirs, already-existing dirs, and a file blocking a directory path. +func TestRootMkdirAll(t *testing.T) { + workspace := t.TempDir() + root, err := os.OpenRoot(workspace) + if err != nil { + t.Fatalf("failed to open root: %v", err) + } + defer root.Close() + + // Case 1: Single directory + err = root.MkdirAll("dir1", 0o755) + assert.NoError(t, err) + _, err = os.Stat(filepath.Join(workspace, "dir1")) + assert.NoError(t, err) + + // Case 2: Deeply nested directory + err = root.MkdirAll("a/b/c/d", 0o755) + assert.NoError(t, err) + _, err = os.Stat(filepath.Join(workspace, "a/b/c/d")) + assert.NoError(t, err) + + // Case 3: Already exists — must be idempotent + err = root.MkdirAll("a/b/c/d", 0o755) + assert.NoError(t, err) + + // Case 4: A regular file blocks directory creation — must error + err = os.WriteFile(filepath.Join(workspace, "file_exists"), []byte("data"), 0o644) + assert.NoError(t, err) + err = root.MkdirAll("file_exists", 0o755) + assert.Error(t, err, "expected error when a file exists at the directory path") +} + +func TestFilesystemTool_WriteFile_Restricted_CreateDir(t *testing.T) { + workspace := t.TempDir() + tool := NewWriteFileTool(workspace, true) + ctx := context.Background() + + testFile := "deep/nested/path/to/file.txt" + content := "deep content" + args := map[string]any{ + "path": testFile, + "content": content, + } + + result := tool.Execute(ctx, args) + assert.False(t, result.IsError, "Expected success, got: %s", result.ForLLM) + + // Verify file content + actualPath := filepath.Join(workspace, testFile) + data, err := os.ReadFile(actualPath) + assert.NoError(t, err) + assert.Equal(t, content, string(data)) +} + +// TestHostRW_Read_PermissionDenied verifies that hostRW.Read surfaces access denied errors. +func TestHostRW_Read_PermissionDenied(t *testing.T) { + if os.Getuid() == 0 { + t.Skip("skipping permission test: running as root") + } + tmpDir := t.TempDir() + protected := filepath.Join(tmpDir, "protected.txt") + err := os.WriteFile(protected, []byte("secret"), 0o000) + assert.NoError(t, err) + defer os.Chmod(protected, 0o644) // ensure cleanup + + _, err = (&hostFs{}).ReadFile(protected) + assert.Error(t, err) + assert.Contains(t, err.Error(), "access denied") +} + +// TestHostRW_Read_Directory verifies that hostRW.Read returns an error when given a directory path. +func TestHostRW_Read_Directory(t *testing.T) { + tmpDir := t.TempDir() + + _, err := (&hostFs{}).ReadFile(tmpDir) + assert.Error(t, err, "expected error when reading a directory as a file") +} + +// TestRootRW_Read_Directory verifies that rootRW.Read returns an error when given a directory. +func TestRootRW_Read_Directory(t *testing.T) { + workspace := t.TempDir() + root, err := os.OpenRoot(workspace) + assert.NoError(t, err) + defer root.Close() + + // Create a subdirectory + err = root.Mkdir("subdir", 0o755) + assert.NoError(t, err) + + _, err = (&sandboxFs{workspace: workspace}).ReadFile("subdir") + assert.Error(t, err, "expected error when reading a directory as a file") +} + +// TestHostRW_Write_ParentDirMissing verifies that hostRW.Write creates parent dirs automatically. +func TestHostRW_Write_ParentDirMissing(t *testing.T) { + tmpDir := t.TempDir() + target := filepath.Join(tmpDir, "a", "b", "c", "file.txt") + + err := (&hostFs{}).WriteFile(target, []byte("hello")) + assert.NoError(t, err) + + data, err := os.ReadFile(target) + assert.NoError(t, err) + assert.Equal(t, "hello", string(data)) +} + +// TestRootRW_Write_ParentDirMissing verifies that rootRW.Write creates +// nested parent directories automatically within the sandbox. +func TestRootRW_Write_ParentDirMissing(t *testing.T) { + workspace := t.TempDir() + + relPath := "x/y/z/file.txt" + err := (&sandboxFs{workspace: workspace}).WriteFile(relPath, []byte("nested")) + assert.NoError(t, err) + + data, err := os.ReadFile(filepath.Join(workspace, relPath)) + assert.NoError(t, err) + assert.Equal(t, "nested", string(data)) +} + +// TestHostRW_Write verifies the hostRW.Write helper function +func TestHostRW_Write(t *testing.T) { + tmpDir := t.TempDir() + testFile := filepath.Join(tmpDir, "atomic_test.txt") + testData := []byte("atomic test content") + + err := (&hostFs{}).WriteFile(testFile, testData) + assert.NoError(t, err) + + content, err := os.ReadFile(testFile) + assert.NoError(t, err) + assert.Equal(t, testData, content) + + // Verify it overwrites correctly + newData := []byte("new atomic content") + err = (&hostFs{}).WriteFile(testFile, newData) + assert.NoError(t, err) + + content, err = os.ReadFile(testFile) + assert.NoError(t, err) + assert.Equal(t, newData, content) +} + +// TestRootRW_Write verifies the rootRW.Write helper function +func TestRootRW_Write(t *testing.T) { + tmpDir := t.TempDir() + + relPath := "atomic_root_test.txt" + testData := []byte("atomic root test content") + + erw := &sandboxFs{workspace: tmpDir} + err := erw.WriteFile(relPath, testData) + assert.NoError(t, err) + + root, err := os.OpenRoot(tmpDir) + assert.NoError(t, err) + defer root.Close() + + f, err := root.Open(relPath) + assert.NoError(t, err) + defer f.Close() + + content, err := io.ReadAll(f) + assert.NoError(t, err) + assert.Equal(t, testData, content) + + // Verify it overwrites correctly + newData := []byte("new root atomic content") + err = erw.WriteFile(relPath, newData) + assert.NoError(t, err) + + f2, err := root.Open(relPath) + assert.NoError(t, err) + defer f2.Close() + + content, err = io.ReadAll(f2) + assert.NoError(t, err) + assert.Equal(t, newData, content) +} From 6d487a12b26ae2131a573915ee4f55a4da424c30 Mon Sep 17 00:00:00 2001 From: Zenix Date: Mon, 23 Feb 2026 19:29:43 +0900 Subject: [PATCH 26/40] fix: make install should be aware of the textfile busy since it tries to overwrite the file with non-atomic operation (#558) --- Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a5ad4a02d..29e2fc964 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,7 @@ GOLANGCI_LINT?=golangci-lint INSTALL_PREFIX?=$(HOME)/.local INSTALL_BIN_DIR=$(INSTALL_PREFIX)/bin INSTALL_MAN_DIR=$(INSTALL_PREFIX)/share/man/man1 +INSTALL_TMP_SUFFIX=.new # Workspace and Skills PICOCLAW_HOME?=$(HOME)/.picoclaw @@ -99,8 +100,10 @@ build-all: generate install: build @echo "Installing $(BINARY_NAME)..." @mkdir -p $(INSTALL_BIN_DIR) - @cp $(BUILD_DIR)/$(BINARY_NAME) $(INSTALL_BIN_DIR)/$(BINARY_NAME) - @chmod +x $(INSTALL_BIN_DIR)/$(BINARY_NAME) + # Copy binary with temporary suffix to ensure atomic update + @cp $(BUILD_DIR)/$(BINARY_NAME) $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(INSTALL_TMP_SUFFIX) + @chmod +x $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(INSTALL_TMP_SUFFIX) + @mv -f $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(INSTALL_TMP_SUFFIX) $(INSTALL_BIN_DIR)/$(BINARY_NAME) @echo "Installed binary to $(INSTALL_BIN_DIR)/$(BINARY_NAME)" @echo "Installation complete!" From 8a53cb96651fad13c665417aadbedddf3e14a284 Mon Sep 17 00:00:00 2001 From: Chujiang <110hqc@gmail.com> Date: Tue, 24 Feb 2026 05:52:16 +0800 Subject: [PATCH 27/40] fix: align Docker Go version with go.mod and optimize logger (#596) - Update Dockerfile to use golang:1.25-alpine to match go.mod (go 1.25.7) - Optimize logger by avoiding string concatenation in file writes - Add explicit empty string assignment for fieldStr when no fields These changes improve build consistency and reduce memory allocations in the hot logging path, which is important for the project's goal of running on resource-constrained devices (<10MB RAM). Co-authored-by: Claude Sonnet 4.6 --- Dockerfile | 2 +- pkg/logger/logger.go | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0360cfda6..480244127 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # ============================================================ # Stage 1: Build the picoclaw binary # ============================================================ -FROM golang:1.26.0-alpine AS builder +FROM golang:1.25-alpine AS builder RUN apk add --no-cache git make diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index 54de66bf9..c14fbd464 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -119,13 +119,15 @@ func logMessage(level LogLevel, component string, message string, fields map[str if logger.file != nil { jsonData, err := json.Marshal(entry) if err == nil { - logger.file.WriteString(string(jsonData) + "\n") + logger.file.Write(append(jsonData, '\n')) } } var fieldStr string if len(fields) > 0 { fieldStr = " " + formatFields(fields) + } else { + fieldStr = "" } logLine := fmt.Sprintf("[%s] [%s]%s %s%s", From 2fa51d7b868672ab2fd054396216fa68184b3ad6 Mon Sep 17 00:00:00 2001 From: 0x5487 Date: Tue, 24 Feb 2026 05:54:10 +0800 Subject: [PATCH 28/40] fix(security): change gateway default bind to 127.0.0.1 (#393) * chore: Update default host bindings from 0.0.0.0 to 127.0.0.1 for various services and examples. * config: Update default host bindings to 0.0.0.0 for improved Docker accessibility and add related documentation. * chore: resolve conflict * chore: remove link * docs: Add a tip for Docker users regarding gateway host configuration to the French and Vietnamese READMEs. * fix: typo issue * docs: Update Chinese README.zh.md. --- README.fr.md | 4 ++++ README.ja.md | 4 ++++ README.md | 4 ++++ README.pt-br.md | 4 ++++ README.vi.md | 4 ++++ README.zh.md | 3 +++ config/config.example.json | 2 +- pkg/config/config_test.go | 4 ++-- pkg/config/defaults.go | 2 +- 9 files changed, 27 insertions(+), 4 deletions(-) diff --git a/README.fr.md b/README.fr.md index a762870ff..d09276c27 100644 --- a/README.fr.md +++ b/README.fr.md @@ -171,6 +171,10 @@ vim config/config.json # Configurez DISCORD_BOT_TOKEN, clés API, etc. # 3. Compiler & Démarrer docker compose --profile gateway up -d +> [!TIP] +> **Utilisateurs Docker** : Par défaut, le Gateway écoute sur `127.0.0.1`, ce qui n'est pas accessible depuis l'hôte. Si vous avez besoin d'accéder aux endpoints de santé ou d'exposer des ports, définissez `PICOCLAW_GATEWAY_HOST=0.0.0.0` dans votre environnement ou mettez à jour `config.json`. + + # 4. Voir les logs docker compose logs -f picoclaw-gateway diff --git a/README.ja.md b/README.ja.md index 3506c77c2..67eccddc2 100644 --- a/README.ja.md +++ b/README.ja.md @@ -133,6 +133,10 @@ vim config/config.json # DISCORD_BOT_TOKEN, プロバイダーの API キ # 3. ビルドと起動 docker compose --profile gateway up -d +> [!TIP] +> **Docker ユーザー**: デフォルトでは、Gateway は `127.0.0.1` でリッスンしており、ホストからアクセスできません。ヘルスチェックエンドポイントにアクセスしたり、ポートを公開したりする必要がある場合は、環境変数で `PICOCLAW_GATEWAY_HOST=0.0.0.0` を設定するか、`config.json` を更新してください。 + + # 4. ログ確認 docker compose logs -f picoclaw-gateway diff --git a/README.md b/README.md index 955255f2e..84d92115b 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,10 @@ vim config/config.json # Set DISCORD_BOT_TOKEN, API keys, etc. # 3. Build & Start docker compose --profile gateway up -d +> [!TIP] +> **Docker Users**: By default, the Gateway listens on `127.0.0.1` which is not accessible from the host. If you need to access the health endpoints or expose ports, set `PICOCLAW_GATEWAY_HOST=0.0.0.0` in your environment or update `config.json`. + + # 4. Check logs docker compose logs -f picoclaw-gateway diff --git a/README.pt-br.md b/README.pt-br.md index 900ee7932..8d87333bc 100644 --- a/README.pt-br.md +++ b/README.pt-br.md @@ -172,6 +172,10 @@ vim config/config.json # Configure DISCORD_BOT_TOKEN, API keys, etc. # 3. Build & Iniciar docker compose --profile gateway up -d +> [!TIP] +> **Usuários Docker**: Por padrão, o Gateway ouve em `127.0.0.1`, o que não é acessível a partir do host. Se você precisar acessar os endpoints de integridade ou expor portas, defina `PICOCLAW_GATEWAY_HOST=0.0.0.0` em seu ambiente ou atualize o `config.json`. + + # 4. Ver logs docker compose logs -f picoclaw-gateway diff --git a/README.vi.md b/README.vi.md index 29ff12bb0..1be58d9f6 100644 --- a/README.vi.md +++ b/README.vi.md @@ -152,6 +152,10 @@ vim config/config.json # Thiết lập DISCORD_BOT_TOKEN, API keys, v.v. # 3. Build & Khởi động docker compose --profile gateway up -d +> [!TIP] +> **Người dùng Docker**: Theo mặc định, Gateway lắng nghe trên `127.0.0.1`, không thể truy cập từ máy chủ. Nếu bạn cần truy cập các endpoint kiểm tra sức khỏe hoặc mở cổng, hãy đặt `PICOCLAW_GATEWAY_HOST=0.0.0.0` trong môi trường của bạn hoặc cập nhật `config.json`. + + # 4. Xem logs docker compose logs -f picoclaw-gateway diff --git a/README.zh.md b/README.zh.md index 17a736fec..74760b3b1 100644 --- a/README.zh.md +++ b/README.zh.md @@ -173,6 +173,9 @@ vim config/config.json # 设置 DISCORD_BOT_TOKEN, API keys 等 # 3. 构建并启动 docker compose --profile gateway up -d +> [!TIP] +**Docker 用户**: 默认情况下, Gateway监听 `127.0.0.1`,这使得这个端口未暴露到容器外。如果你需要通过端口映射访问健康检查接口, 请在环境变量中设置 `PICOCLAW_GATEWAY_HOST=0.0.0.0` 或修改 `config.json`。 + # 4. 查看日志 docker compose logs -f picoclaw-gateway diff --git a/config/config.example.json b/config/config.example.json index e814fcbb8..555509732 100644 --- a/config/config.example.json +++ b/config/config.example.json @@ -247,7 +247,7 @@ "monitor_usb": true }, "gateway": { - "host": "0.0.0.0", + "host": "127.0.0.1", "port": 18790 } } diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 0898217d6..f88c0269c 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -246,7 +246,7 @@ func TestDefaultConfig_Temperature(t *testing.T) { func TestDefaultConfig_Gateway(t *testing.T) { cfg := DefaultConfig() - if cfg.Gateway.Host != "0.0.0.0" { + if cfg.Gateway.Host != "127.0.0.1" { t.Error("Gateway host should have default value") } if cfg.Gateway.Port == 0 { @@ -343,7 +343,7 @@ func TestConfig_Complete(t *testing.T) { if cfg.Agents.Defaults.MaxToolIterations == 0 { t.Error("MaxToolIterations should not be zero") } - if cfg.Gateway.Host != "0.0.0.0" { + if cfg.Gateway.Host != "127.0.0.1" { t.Error("Gateway host should have default value") } if cfg.Gateway.Port == 0 { diff --git a/pkg/config/defaults.go b/pkg/config/defaults.go index 065273c28..b96ee4d89 100644 --- a/pkg/config/defaults.go +++ b/pkg/config/defaults.go @@ -272,7 +272,7 @@ func DefaultConfig() *Config { }, }, Gateway: GatewayConfig{ - Host: "0.0.0.0", + Host: "127.0.0.1", Port: 18790, }, Tools: ToolsConfig{ From 09b1992dd79cac46b7a48176074eabae36b9c1bc Mon Sep 17 00:00:00 2001 From: Goksu Ceylan <79890826+GoCeylan@users.noreply.github.com> Date: Mon, 23 Feb 2026 17:02:44 -0500 Subject: [PATCH 29/40] fix(security): ensure custom deny patterns extend defaults instead of replacing them (#479) * fix (security): custom deny patterns denying default patterns * fix formatting whitespace --- pkg/tools/shell.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/tools/shell.go b/pkg/tools/shell.go index a1ee0b6e1..6883172cd 100644 --- a/pkg/tools/shell.go +++ b/pkg/tools/shell.go @@ -81,6 +81,7 @@ func NewExecToolWithConfig(workingDir string, restrict bool, config *config.Conf execConfig := config.Tools.Exec enableDenyPatterns = execConfig.EnableDenyPatterns if enableDenyPatterns { + denyPatterns = append(denyPatterns, defaultDenyPatterns...) if len(execConfig.CustomDenyPatterns) > 0 { fmt.Printf("Using custom deny patterns: %v\n", execConfig.CustomDenyPatterns) for _, pattern := range execConfig.CustomDenyPatterns { @@ -91,8 +92,6 @@ func NewExecToolWithConfig(workingDir string, restrict bool, config *config.Conf } denyPatterns = append(denyPatterns, re) } - } else { - denyPatterns = append(denyPatterns, defaultDenyPatterns...) } } else { // If deny patterns are disabled, we won't add any patterns, allowing all commands. From 6fe3920a4d836b97c838fd39874cc6a5d07d1d40 Mon Sep 17 00:00:00 2001 From: mattn Date: Tue, 24 Feb 2026 08:07:09 +0900 Subject: [PATCH 30/40] perf: refactoring collecting skills (#688) * perf: refactoring collecting skills * Fix order to store dir.Name() * Add tests --- pkg/skills/loader.go | 140 +++++++++++--------------------------- pkg/skills/loader_test.go | 131 +++++++++++++++++++++++++++++++++++ 2 files changed, 170 insertions(+), 101 deletions(-) diff --git a/pkg/skills/loader.go b/pkg/skills/loader.go index eb0d5f322..f4f55a698 100644 --- a/pkg/skills/loader.go +++ b/pkg/skills/loader.go @@ -71,112 +71,50 @@ func NewSkillsLoader(workspace string, globalSkills string, builtinSkills string func (sl *SkillsLoader) ListSkills() []SkillInfo { skills := make([]SkillInfo, 0) + seen := make(map[string]bool) - if sl.workspaceSkills != "" { - if dirs, err := os.ReadDir(sl.workspaceSkills); err == nil { - for _, dir := range dirs { - if dir.IsDir() { - skillFile := filepath.Join(sl.workspaceSkills, dir.Name(), "SKILL.md") - if _, err := os.Stat(skillFile); err == nil { - info := SkillInfo{ - Name: dir.Name(), - Path: skillFile, - Source: "workspace", - } - metadata := sl.getSkillMetadata(skillFile) - if metadata != nil { - info.Description = metadata.Description - info.Name = metadata.Name - } - if err := info.validate(); err != nil { - slog.Warn("invalid skill from workspace", "name", info.Name, "error", err) - continue - } - skills = append(skills, info) - } - } + addSkills := func(dir, source string) { + if dir == "" { + return + } + dirs, err := os.ReadDir(dir) + if err != nil { + return + } + for _, d := range dirs { + if !d.IsDir() { + continue } + skillFile := filepath.Join(dir, d.Name(), "SKILL.md") + if _, err := os.Stat(skillFile); err != nil { + continue + } + info := SkillInfo{ + Name: d.Name(), + Path: skillFile, + Source: source, + } + metadata := sl.getSkillMetadata(skillFile) + if metadata != nil { + info.Description = metadata.Description + info.Name = metadata.Name + } + if err := info.validate(); err != nil { + slog.Warn("invalid skill from "+source, "name", info.Name, "error", err) + continue + } + if seen[info.Name] { + continue + } + seen[info.Name] = true + skills = append(skills, info) } } - // 全局 skills (~/.picoclaw/skills) - 被 workspace skills 覆盖 - if sl.globalSkills != "" { - if dirs, err := os.ReadDir(sl.globalSkills); err == nil { - for _, dir := range dirs { - if dir.IsDir() { - skillFile := filepath.Join(sl.globalSkills, dir.Name(), "SKILL.md") - if _, err := os.Stat(skillFile); err == nil { - // 检查是否已被 workspace skills 覆盖 - exists := false - for _, s := range skills { - if s.Name == dir.Name() && s.Source == "workspace" { - exists = true - break - } - } - if exists { - continue - } - - info := SkillInfo{ - Name: dir.Name(), - Path: skillFile, - Source: "global", - } - metadata := sl.getSkillMetadata(skillFile) - if metadata != nil { - info.Description = metadata.Description - info.Name = metadata.Name - } - if err := info.validate(); err != nil { - slog.Warn("invalid skill from global", "name", info.Name, "error", err) - continue - } - skills = append(skills, info) - } - } - } - } - } - - if sl.builtinSkills != "" { - if dirs, err := os.ReadDir(sl.builtinSkills); err == nil { - for _, dir := range dirs { - if dir.IsDir() { - skillFile := filepath.Join(sl.builtinSkills, dir.Name(), "SKILL.md") - if _, err := os.Stat(skillFile); err == nil { - // 检查是否已被 workspace 或 global skills 覆盖 - exists := false - for _, s := range skills { - if s.Name == dir.Name() && (s.Source == "workspace" || s.Source == "global") { - exists = true - break - } - } - if exists { - continue - } - - info := SkillInfo{ - Name: dir.Name(), - Path: skillFile, - Source: "builtin", - } - metadata := sl.getSkillMetadata(skillFile) - if metadata != nil { - info.Description = metadata.Description - info.Name = metadata.Name - } - if err := info.validate(); err != nil { - slog.Warn("invalid skill from builtin", "name", info.Name, "error", err) - continue - } - skills = append(skills, info) - } - } - } - } - } + // Priority: workspace > global > builtin + addSkills(sl.workspaceSkills, "workspace") + addSkills(sl.globalSkills, "global") + addSkills(sl.builtinSkills, "builtin") return skills } diff --git a/pkg/skills/loader_test.go b/pkg/skills/loader_test.go index aca901d33..9428bea62 100644 --- a/pkg/skills/loader_test.go +++ b/pkg/skills/loader_test.go @@ -1,9 +1,12 @@ package skills import ( + "os" + "path/filepath" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSkillsInfoValidate(t *testing.T) { @@ -135,6 +138,134 @@ func TestExtractFrontmatter(t *testing.T) { } } +// createSkillDir creates a skill directory with a SKILL.md file containing the given frontmatter. +func createSkillDir(t *testing.T, base, dirName, name, description string) { + t.Helper() + dir := filepath.Join(base, dirName) + require.NoError(t, os.MkdirAll(dir, 0o755)) + content := "---\nname: " + name + "\ndescription: " + description + "\n---\n\n# " + name + require.NoError(t, os.WriteFile(filepath.Join(dir, "SKILL.md"), []byte(content), 0o644)) +} + +func TestListSkillsWorkspaceOverridesGlobal(t *testing.T) { + tmp := t.TempDir() + ws := filepath.Join(tmp, "workspace") + global := filepath.Join(tmp, "global") + + createSkillDir(t, filepath.Join(ws, "skills"), "my-skill", "my-skill", "workspace version") + createSkillDir(t, global, "my-skill", "my-skill", "global version") + + sl := NewSkillsLoader(ws, global, "") + skills := sl.ListSkills() + + assert.Len(t, skills, 1) + assert.Equal(t, "workspace", skills[0].Source) + assert.Equal(t, "workspace version", skills[0].Description) +} + +func TestListSkillsGlobalOverridesBuiltin(t *testing.T) { + tmp := t.TempDir() + ws := filepath.Join(tmp, "workspace") + global := filepath.Join(tmp, "global") + builtin := filepath.Join(tmp, "builtin") + + createSkillDir(t, global, "my-skill", "my-skill", "global version") + createSkillDir(t, builtin, "my-skill", "my-skill", "builtin version") + + sl := NewSkillsLoader(ws, global, builtin) + skills := sl.ListSkills() + + assert.Len(t, skills, 1) + assert.Equal(t, "global", skills[0].Source) + assert.Equal(t, "global version", skills[0].Description) +} + +func TestListSkillsMetadataNameDedup(t *testing.T) { + tmp := t.TempDir() + ws := filepath.Join(tmp, "workspace") + global := filepath.Join(tmp, "global") + + // Different directory names but same metadata name + createSkillDir(t, filepath.Join(ws, "skills"), "dir-a", "shared-name", "workspace version") + createSkillDir(t, global, "dir-b", "shared-name", "global version") + + sl := NewSkillsLoader(ws, global, "") + skills := sl.ListSkills() + + assert.Len(t, skills, 1) + assert.Equal(t, "shared-name", skills[0].Name) + assert.Equal(t, "workspace", skills[0].Source) +} + +func TestListSkillsMultipleDistinctSkills(t *testing.T) { + tmp := t.TempDir() + ws := filepath.Join(tmp, "workspace") + global := filepath.Join(tmp, "global") + builtin := filepath.Join(tmp, "builtin") + + createSkillDir(t, filepath.Join(ws, "skills"), "skill-a", "skill-a", "desc a") + createSkillDir(t, global, "skill-b", "skill-b", "desc b") + createSkillDir(t, builtin, "skill-c", "skill-c", "desc c") + + sl := NewSkillsLoader(ws, global, builtin) + skills := sl.ListSkills() + + assert.Len(t, skills, 3) + names := map[string]string{} + for _, s := range skills { + names[s.Name] = s.Source + } + assert.Equal(t, "workspace", names["skill-a"]) + assert.Equal(t, "global", names["skill-b"]) + assert.Equal(t, "builtin", names["skill-c"]) +} + +func TestListSkillsInvalidSkillSkipped(t *testing.T) { + tmp := t.TempDir() + ws := filepath.Join(tmp, "workspace") + global := filepath.Join(tmp, "global") + + // Invalid name (underscore) + createSkillDir(t, filepath.Join(ws, "skills"), "bad_skill", "bad_skill", "desc") + // Valid skill + createSkillDir(t, global, "good-skill", "good-skill", "desc") + + sl := NewSkillsLoader(ws, global, "") + skills := sl.ListSkills() + + assert.Len(t, skills, 1) + assert.Equal(t, "good-skill", skills[0].Name) +} + +func TestListSkillsEmptyAndNonexistentDirs(t *testing.T) { + tmp := t.TempDir() + ws := filepath.Join(tmp, "workspace") + emptyDir := filepath.Join(tmp, "empty") + require.NoError(t, os.MkdirAll(emptyDir, 0o755)) + + sl := NewSkillsLoader(ws, emptyDir, filepath.Join(tmp, "nonexistent")) + skills := sl.ListSkills() + + assert.Empty(t, skills) +} + +func TestListSkillsDirWithoutSkillMD(t *testing.T) { + tmp := t.TempDir() + ws := filepath.Join(tmp, "workspace") + global := filepath.Join(tmp, "global") + + // Directory exists but has no SKILL.md + require.NoError(t, os.MkdirAll(filepath.Join(global, "no-skillmd"), 0o755)) + // Valid skill alongside + createSkillDir(t, global, "real-skill", "real-skill", "desc") + + sl := NewSkillsLoader(ws, global, "") + skills := sl.ListSkills() + + assert.Len(t, skills, 1) + assert.Equal(t, "real-skill", skills[0].Name) +} + func TestStripFrontmatter(t *testing.T) { sl := &SkillsLoader{} From 6fb61539d779dd155ba82422fe7d0f1094f0893e Mon Sep 17 00:00:00 2001 From: Kai Xia Date: Tue, 24 Feb 2026 10:27:49 +1100 Subject: [PATCH 31/40] translate Chinese comments Signed-off-by: Kai Xia --- cmd/picoclaw/main.go | 2 +- pkg/channels/qq.go | 46 ++++++++++++++++++++-------------------- pkg/channels/slack.go | 6 +++--- pkg/channels/telegram.go | 6 +++--- pkg/skills/loader.go | 12 +++++------ 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/cmd/picoclaw/main.go b/cmd/picoclaw/main.go index 1e4b393f8..25ad701ca 100644 --- a/cmd/picoclaw/main.go +++ b/cmd/picoclaw/main.go @@ -131,7 +131,7 @@ func main() { workspace := cfg.WorkspacePath() installer := skills.NewSkillInstaller(workspace) - // 获取全局配置目录和内置 skills 目录 + // get global config directory and builtin skills directory globalDir := filepath.Dir(getConfigPath()) globalSkillsDir := filepath.Join(globalDir, "skills") builtinSkillsDir := filepath.Join(globalDir, "picoclaw", "skills") diff --git a/pkg/channels/qq.go b/pkg/channels/qq.go index e66cac533..b10776db6 100644 --- a/pkg/channels/qq.go +++ b/pkg/channels/qq.go @@ -47,31 +47,31 @@ func (c *QQChannel) Start(ctx context.Context) error { logger.InfoC("qq", "Starting QQ bot (WebSocket mode)") - // 创建 token source + // create token source credentials := &token.QQBotCredentials{ AppID: c.config.AppID, AppSecret: c.config.AppSecret, } c.tokenSource = token.NewQQBotTokenSource(credentials) - // 创建子 context + // create child context c.ctx, c.cancel = context.WithCancel(ctx) - // 启动自动刷新 token 协程 + // start auto-refresh token goroutine if err := token.StartRefreshAccessToken(c.ctx, c.tokenSource); err != nil { return fmt.Errorf("failed to start token refresh: %w", err) } - // 初始化 OpenAPI 客户端 + // initialize OpenAPI client c.api = botgo.NewOpenAPI(c.config.AppID, c.tokenSource).WithTimeout(5 * time.Second) - // 注册事件处理器 + // register event handlers intent := event.RegisterHandlers( c.handleC2CMessage(), c.handleGroupATMessage(), ) - // 获取 WebSocket 接入点 + // get WebSocket endpoint wsInfo, err := c.api.WS(c.ctx, nil, "") if err != nil { return fmt.Errorf("failed to get websocket info: %w", err) @@ -81,10 +81,10 @@ func (c *QQChannel) Start(ctx context.Context) error { "shards": wsInfo.Shards, }) - // 创建并保存 sessionManager + // create and save sessionManager c.sessionManager = botgo.NewSessionManager() - // 在 goroutine 中启动 WebSocket 连接,避免阻塞 + // start WebSocket connection in goroutine to avoid blocking go func() { if err := c.sessionManager.Start(wsInfo, c.tokenSource, &intent); err != nil { logger.ErrorCF("qq", "WebSocket session error", map[string]any{ @@ -116,12 +116,12 @@ func (c *QQChannel) Send(ctx context.Context, msg bus.OutboundMessage) error { return fmt.Errorf("QQ bot not running") } - // 构造消息 + // construct message msgToCreate := &dto.MessageToCreate{ Content: msg.Content, } - // C2C 消息发送 + // send C2C message _, err := c.api.PostC2CMessage(ctx, msg.ChatID, msgToCreate) if err != nil { logger.ErrorCF("qq", "Failed to send C2C message", map[string]any{ @@ -133,15 +133,15 @@ func (c *QQChannel) Send(ctx context.Context, msg bus.OutboundMessage) error { return nil } -// handleC2CMessage 处理 QQ 私聊消息 +// handleC2CMessage handles QQ private messages func (c *QQChannel) handleC2CMessage() event.C2CMessageEventHandler { return func(event *dto.WSPayload, data *dto.WSC2CMessageData) error { - // 去重检查 + // deduplication check if c.isDuplicate(data.ID) { return nil } - // 提取用户信息 + // extract user info var senderID string if data.Author != nil && data.Author.ID != "" { senderID = data.Author.ID @@ -150,7 +150,7 @@ func (c *QQChannel) handleC2CMessage() event.C2CMessageEventHandler { return nil } - // 提取消息内容 + // extract message content content := data.Content if content == "" { logger.DebugC("qq", "Received empty message, ignoring") @@ -162,7 +162,7 @@ func (c *QQChannel) handleC2CMessage() event.C2CMessageEventHandler { "length": len(content), }) - // 转发到消息总线 + // forward to message bus metadata := map[string]string{ "message_id": data.ID, "peer_kind": "direct", @@ -175,15 +175,15 @@ func (c *QQChannel) handleC2CMessage() event.C2CMessageEventHandler { } } -// handleGroupATMessage 处理群@消息 +// handleGroupATMessage handles group @messages func (c *QQChannel) handleGroupATMessage() event.GroupATMessageEventHandler { return func(event *dto.WSPayload, data *dto.WSGroupATMessageData) error { - // 去重检查 + // deduplication check if c.isDuplicate(data.ID) { return nil } - // 提取用户信息 + // extract user info var senderID string if data.Author != nil && data.Author.ID != "" { senderID = data.Author.ID @@ -192,7 +192,7 @@ func (c *QQChannel) handleGroupATMessage() event.GroupATMessageEventHandler { return nil } - // 提取消息内容(去掉 @ 机器人部分) + // extract message content (remove @bot part) content := data.Content if content == "" { logger.DebugC("qq", "Received empty group message, ignoring") @@ -205,7 +205,7 @@ func (c *QQChannel) handleGroupATMessage() event.GroupATMessageEventHandler { "length": len(content), }) - // 转发到消息总线(使用 GroupID 作为 ChatID) + // forward to message bus (use GroupID as ChatID) metadata := map[string]string{ "message_id": data.ID, "group_id": data.GroupID, @@ -219,7 +219,7 @@ func (c *QQChannel) handleGroupATMessage() event.GroupATMessageEventHandler { } } -// isDuplicate 检查消息是否重复 +// isDuplicate checks if message is duplicate func (c *QQChannel) isDuplicate(messageID string) bool { c.mu.Lock() defer c.mu.Unlock() @@ -230,9 +230,9 @@ func (c *QQChannel) isDuplicate(messageID string) bool { c.processedIDs[messageID] = true - // 简单清理:限制 map 大小 + // simple cleanup: limit map size if len(c.processedIDs) > 10000 { - // 清空一半 + // clear half count := 0 for id := range c.processedIDs { if count >= 5000 { diff --git a/pkg/channels/slack.go b/pkg/channels/slack.go index f7359cd6d..f087aa8da 100644 --- a/pkg/channels/slack.go +++ b/pkg/channels/slack.go @@ -200,7 +200,7 @@ func (c *SlackChannel) handleMessageEvent(ev *slackevents.MessageEvent) { return } - // 检查白名单,避免为被拒绝的用户下载附件 + // check allowlist to avoid downloading attachments for rejected users if !c.IsAllowed(ev.User) { logger.DebugCF("slack", "Message rejected by allowlist", map[string]any{ "user_id": ev.User, @@ -232,9 +232,9 @@ func (c *SlackChannel) handleMessageEvent(ev *slackevents.MessageEvent) { content = c.stripBotMention(content) var mediaPaths []string - localFiles := []string{} // 跟踪需要清理的本地文件 + localFiles := []string{} // track local files that need cleanup - // 确保临时文件在函数返回时被清理 + // ensure temp files are cleaned up when function returns defer func() { for _, file := range localFiles { if err := os.Remove(file); err != nil { diff --git a/pkg/channels/telegram.go b/pkg/channels/telegram.go index a0a1c8d0a..5cd51e8bc 100644 --- a/pkg/channels/telegram.go +++ b/pkg/channels/telegram.go @@ -208,7 +208,7 @@ func (c *TelegramChannel) handleMessage(ctx context.Context, message *telego.Mes senderID = fmt.Sprintf("%d|%s", user.ID, user.Username) } - // 检查白名单,避免为被拒绝的用户下载附件 + // check allowlist to avoid downloading attachments for rejected users if !c.IsAllowed(senderID) { logger.DebugCF("telegram", "Message rejected by allowlist", map[string]any{ "user_id": senderID, @@ -221,9 +221,9 @@ func (c *TelegramChannel) handleMessage(ctx context.Context, message *telego.Mes content := "" mediaPaths := []string{} - localFiles := []string{} // 跟踪需要清理的本地文件 + localFiles := []string{} // track local files that need cleanup - // 确保临时文件在函数返回时被清理 + // ensure temp files are cleaned up when function returns defer func() { for _, file := range localFiles { if err := os.Remove(file); err != nil { diff --git a/pkg/skills/loader.go b/pkg/skills/loader.go index f4f55a698..5749d8983 100644 --- a/pkg/skills/loader.go +++ b/pkg/skills/loader.go @@ -55,9 +55,9 @@ func (info SkillInfo) validate() error { type SkillsLoader struct { workspace string - workspaceSkills string // workspace skills (项目级别) - globalSkills string // 全局 skills (~/.picoclaw/skills) - builtinSkills string // 内置 skills + workspaceSkills string // workspace skills (project-level) + globalSkills string // global skills (~/.picoclaw/skills) + builtinSkills string // builtin skills } func NewSkillsLoader(workspace string, globalSkills string, builtinSkills string) *SkillsLoader { @@ -120,7 +120,7 @@ func (sl *SkillsLoader) ListSkills() []SkillInfo { } func (sl *SkillsLoader) LoadSkill(name string) (string, bool) { - // 1. 优先从 workspace skills 加载(项目级别) + // 1. load from workspace skills first (project-level) if sl.workspaceSkills != "" { skillFile := filepath.Join(sl.workspaceSkills, name, "SKILL.md") if content, err := os.ReadFile(skillFile); err == nil { @@ -128,7 +128,7 @@ func (sl *SkillsLoader) LoadSkill(name string) (string, bool) { } } - // 2. 其次从全局 skills 加载 (~/.picoclaw/skills) + // 2. then load from global skills (~/.picoclaw/skills) if sl.globalSkills != "" { skillFile := filepath.Join(sl.globalSkills, name, "SKILL.md") if content, err := os.ReadFile(skillFile); err == nil { @@ -136,7 +136,7 @@ func (sl *SkillsLoader) LoadSkill(name string) (string, bool) { } } - // 3. 最后从内置 skills 加载 + // 3. finally load from builtin skills if sl.builtinSkills != "" { skillFile := filepath.Join(sl.builtinSkills, name, "SKILL.md") if content, err := os.ReadFile(skillFile); err == nil { From 0434b49e8d9f85ae52b9b68efddd1147afd54d30 Mon Sep 17 00:00:00 2001 From: Guoguo <16666742+imguoguo@users.noreply.github.com> Date: Tue, 24 Feb 2026 13:58:54 +0800 Subject: [PATCH 32/40] docs: update wechat qrcode (#705) --- assets/wechat.png | Bin 144045 -> 150574 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/assets/wechat.png b/assets/wechat.png index a34217c335542a13aace2103bd15ccebf94acde2..e30c34e4ed81210338d63ee4486c4356d01ae30b 100644 GIT binary patch literal 150574 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 [中文](README.zh.md) | [日本語](README.ja.md) | [Português](README.pt-br.md) | [Tiếng Việt](README.vi.md) | [Français](README.fr.md) | **English** From 76f2b42d5b88bebec2a247b180cf1f19bc69464c Mon Sep 17 00:00:00 2001 From: nayihz Date: Tue, 24 Feb 2026 17:16:16 +0800 Subject: [PATCH 34/40] feat: improve web proxy handling and coverage --- config/config.example.json | 3 +- pkg/agent/loop.go | 3 +- pkg/config/config.go | 3 + pkg/config/config_test.go | 21 +++++ pkg/tools/web.go | 101 +++++++++++++++++----- pkg/tools/web_test.go | 167 +++++++++++++++++++++++++++++++++++++ 6 files changed, 275 insertions(+), 23 deletions(-) diff --git a/config/config.example.json b/config/config.example.json index 555509732..c73d327d6 100644 --- a/config/config.example.json +++ b/config/config.example.json @@ -217,7 +217,8 @@ "enabled": false, "api_key": "pplx-xxx", "max_results": 5 - } + }, + "proxy": "" }, "cron": { "exec_timeout_minutes": 5 diff --git a/pkg/agent/loop.go b/pkg/agent/loop.go index 9a2bb1198..dbc4a9b87 100644 --- a/pkg/agent/loop.go +++ b/pkg/agent/loop.go @@ -106,10 +106,11 @@ func registerSharedTools( PerplexityAPIKey: cfg.Tools.Web.Perplexity.APIKey, PerplexityMaxResults: cfg.Tools.Web.Perplexity.MaxResults, PerplexityEnabled: cfg.Tools.Web.Perplexity.Enabled, + Proxy: cfg.Tools.Web.Proxy, }); searchTool != nil { agent.Tools.Register(searchTool) } - agent.Tools.Register(tools.NewWebFetchTool(50000)) + agent.Tools.Register(tools.NewWebFetchToolWithProxy(50000, cfg.Tools.Web.Proxy)) // Hardware tools (I2C, SPI) - Linux only, returns error on other platforms agent.Tools.Register(tools.NewI2CTool()) diff --git a/pkg/config/config.go b/pkg/config/config.go index 2595398c7..67adca5c3 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -443,6 +443,9 @@ type WebToolsConfig struct { Tavily TavilyConfig `json:"tavily"` DuckDuckGo DuckDuckGoConfig `json:"duckduckgo"` Perplexity PerplexityConfig `json:"perplexity"` + // Proxy is an optional proxy URL for web tools (http/https/socks5/socks5h). + // For authenticated proxies, prefer HTTP_PROXY/HTTPS_PROXY env vars instead of embedding credentials in config. + Proxy string `json:"proxy,omitempty" env:"PICOCLAW_TOOLS_WEB_PROXY"` } type CronToolsConfig struct { diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index f88c0269c..223ac798d 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -392,3 +392,24 @@ func TestLoadConfig_OpenAIWebSearchCanBeDisabled(t *testing.T) { t.Fatal("OpenAI codex web search should be false when disabled in config file") } } + +func TestLoadConfig_WebToolsProxy(t *testing.T) { + tmpDir := t.TempDir() + configPath := filepath.Join(tmpDir, "config.json") + configJSON := `{ + "agents": {"defaults":{"workspace":"./workspace","model":"gpt4","max_tokens":8192,"max_tool_iterations":20}}, + "model_list": [{"model_name":"gpt4","model":"openai/gpt-5.2","api_key":"x"}], + "tools": {"web":{"proxy":"http://127.0.0.1:7890"}} +}` + if err := os.WriteFile(configPath, []byte(configJSON), 0o600); err != nil { + t.Fatalf("os.WriteFile() error: %v", err) + } + + cfg, err := LoadConfig(configPath) + if err != nil { + t.Fatalf("LoadConfig() error: %v", err) + } + if cfg.Tools.Web.Proxy != "http://127.0.0.1:7890" { + t.Fatalf("Tools.Web.Proxy = %q, want %q", cfg.Tools.Web.Proxy, "http://127.0.0.1:7890") + } +} diff --git a/pkg/tools/web.go b/pkg/tools/web.go index 452e95e0f..968579dea 100644 --- a/pkg/tools/web.go +++ b/pkg/tools/web.go @@ -17,12 +17,50 @@ const ( userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" ) +// createHTTPClient creates an HTTP client with optional proxy support +func createHTTPClient(proxyURL string, timeout time.Duration) (*http.Client, error) { + client := &http.Client{ + Timeout: timeout, + Transport: &http.Transport{ + MaxIdleConns: 10, + IdleConnTimeout: 30 * time.Second, + DisableCompression: false, + TLSHandshakeTimeout: 15 * time.Second, + }, + } + + if proxyURL != "" { + proxy, err := url.Parse(proxyURL) + if err != nil { + return nil, fmt.Errorf("invalid proxy URL: %w", err) + } + scheme := strings.ToLower(proxy.Scheme) + switch scheme { + case "http", "https", "socks5", "socks5h": + default: + return nil, fmt.Errorf( + "unsupported proxy scheme %q (supported: http, https, socks5, socks5h)", + proxy.Scheme, + ) + } + if proxy.Host == "" { + return nil, fmt.Errorf("invalid proxy URL: missing host") + } + client.Transport.(*http.Transport).Proxy = http.ProxyURL(proxy) + } else { + client.Transport.(*http.Transport).Proxy = http.ProxyFromEnvironment + } + + return client, nil +} + type SearchProvider interface { Search(ctx context.Context, query string, count int) (string, error) } type BraveSearchProvider struct { apiKey string + proxy string } func (p *BraveSearchProvider) Search(ctx context.Context, query string, count int) (string, error) { @@ -37,7 +75,10 @@ func (p *BraveSearchProvider) Search(ctx context.Context, query string, count in req.Header.Set("Accept", "application/json") req.Header.Set("X-Subscription-Token", p.apiKey) - client := &http.Client{Timeout: 10 * time.Second} + client, err := createHTTPClient(p.proxy, 10*time.Second) + if err != nil { + return "", fmt.Errorf("failed to create HTTP client: %w", err) + } resp, err := client.Do(req) if err != nil { return "", fmt.Errorf("request failed: %w", err) @@ -167,7 +208,9 @@ func (p *TavilySearchProvider) Search(ctx context.Context, query string, count i return strings.Join(lines, "\n"), nil } -type DuckDuckGoSearchProvider struct{} +type DuckDuckGoSearchProvider struct { + proxy string +} func (p *DuckDuckGoSearchProvider) Search(ctx context.Context, query string, count int) (string, error) { searchURL := fmt.Sprintf("https://html.duckduckgo.com/html/?q=%s", url.QueryEscape(query)) @@ -179,7 +222,10 @@ func (p *DuckDuckGoSearchProvider) Search(ctx context.Context, query string, cou req.Header.Set("User-Agent", userAgent) - client := &http.Client{Timeout: 10 * time.Second} + client, err := createHTTPClient(p.proxy, 10*time.Second) + if err != nil { + return "", fmt.Errorf("failed to create HTTP client: %w", err) + } resp, err := client.Do(req) if err != nil { return "", fmt.Errorf("request failed: %w", err) @@ -261,6 +307,7 @@ func stripTags(content string) string { type PerplexitySearchProvider struct { apiKey string + proxy string } func (p *PerplexitySearchProvider) Search(ctx context.Context, query string, count int) (string, error) { @@ -295,7 +342,10 @@ func (p *PerplexitySearchProvider) Search(ctx context.Context, query string, cou req.Header.Set("Authorization", "Bearer "+p.apiKey) req.Header.Set("User-Agent", userAgent) - client := &http.Client{Timeout: 30 * time.Second} + client, err := createHTTPClient(p.proxy, 30*time.Second) + if err != nil { + return "", fmt.Errorf("failed to create HTTP client: %w", err) + } resp, err := client.Do(req) if err != nil { return "", fmt.Errorf("request failed: %w", err) @@ -348,6 +398,7 @@ type WebSearchToolOptions struct { PerplexityAPIKey string PerplexityMaxResults int PerplexityEnabled bool + Proxy string } func NewWebSearchTool(opts WebSearchToolOptions) *WebSearchTool { @@ -356,12 +407,12 @@ func NewWebSearchTool(opts WebSearchToolOptions) *WebSearchTool { // Priority: Perplexity > Brave > Tavily > DuckDuckGo if opts.PerplexityEnabled && opts.PerplexityAPIKey != "" { - provider = &PerplexitySearchProvider{apiKey: opts.PerplexityAPIKey} + provider = &PerplexitySearchProvider{apiKey: opts.PerplexityAPIKey, proxy: opts.Proxy} if opts.PerplexityMaxResults > 0 { maxResults = opts.PerplexityMaxResults } } else if opts.BraveEnabled && opts.BraveAPIKey != "" { - provider = &BraveSearchProvider{apiKey: opts.BraveAPIKey} + provider = &BraveSearchProvider{apiKey: opts.BraveAPIKey, proxy: opts.Proxy} if opts.BraveMaxResults > 0 { maxResults = opts.BraveMaxResults } @@ -374,7 +425,7 @@ func NewWebSearchTool(opts WebSearchToolOptions) *WebSearchTool { maxResults = opts.TavilyMaxResults } } else if opts.DuckDuckGoEnabled { - provider = &DuckDuckGoSearchProvider{} + provider = &DuckDuckGoSearchProvider{proxy: opts.Proxy} if opts.DuckDuckGoMaxResults > 0 { maxResults = opts.DuckDuckGoMaxResults } @@ -441,6 +492,7 @@ func (t *WebSearchTool) Execute(ctx context.Context, args map[string]any) *ToolR type WebFetchTool struct { maxChars int + proxy string } func NewWebFetchTool(maxChars int) *WebFetchTool { @@ -452,6 +504,16 @@ func NewWebFetchTool(maxChars int) *WebFetchTool { } } +func NewWebFetchToolWithProxy(maxChars int, proxy string) *WebFetchTool { + if maxChars <= 0 { + maxChars = 50000 + } + return &WebFetchTool{ + maxChars: maxChars, + proxy: proxy, + } +} + func (t *WebFetchTool) Name() string { return "web_fetch" } @@ -511,20 +573,17 @@ func (t *WebFetchTool) Execute(ctx context.Context, args map[string]any) *ToolRe req.Header.Set("User-Agent", userAgent) - client := &http.Client{ - Timeout: 60 * time.Second, - Transport: &http.Transport{ - MaxIdleConns: 10, - IdleConnTimeout: 30 * time.Second, - DisableCompression: false, - TLSHandshakeTimeout: 15 * time.Second, - }, - CheckRedirect: func(req *http.Request, via []*http.Request) error { - if len(via) >= 5 { - return fmt.Errorf("stopped after 5 redirects") - } - return nil - }, + client, err := createHTTPClient(t.proxy, 60*time.Second) + if err != nil { + return ErrorResult(fmt.Sprintf("failed to create HTTP client: %v", err)) + } + + // Configure redirect handling + client.CheckRedirect = func(req *http.Request, via []*http.Request) error { + if len(via) >= 5 { + return fmt.Errorf("stopped after 5 redirects") + } + return nil } resp, err := client.Do(req) diff --git a/pkg/tools/web_test.go b/pkg/tools/web_test.go index 75e0d8d16..2cd79eb24 100644 --- a/pkg/tools/web_test.go +++ b/pkg/tools/web_test.go @@ -7,6 +7,7 @@ import ( "net/http/httptest" "strings" "testing" + "time" ) // TestWebTool_WebFetch_Success verifies successful URL fetching @@ -334,6 +335,172 @@ func TestWebTool_WebFetch_MissingDomain(t *testing.T) { } } +func TestCreateHTTPClient_ProxyConfigured(t *testing.T) { + client, err := createHTTPClient("http://127.0.0.1:7890", 12*time.Second) + if err != nil { + t.Fatalf("createHTTPClient() error: %v", err) + } + if client.Timeout != 12*time.Second { + t.Fatalf("client.Timeout = %v, want %v", client.Timeout, 12*time.Second) + } + + tr, ok := client.Transport.(*http.Transport) + if !ok { + t.Fatalf("client.Transport type = %T, want *http.Transport", client.Transport) + } + if tr.Proxy == nil { + t.Fatal("transport.Proxy is nil, want non-nil") + } + + req, err := http.NewRequest("GET", "https://example.com", nil) + if err != nil { + t.Fatalf("http.NewRequest() error: %v", err) + } + proxyURL, err := tr.Proxy(req) + if err != nil { + t.Fatalf("transport.Proxy(req) error: %v", err) + } + if proxyURL == nil || proxyURL.String() != "http://127.0.0.1:7890" { + t.Fatalf("proxy URL = %v, want %q", proxyURL, "http://127.0.0.1:7890") + } +} + +func TestCreateHTTPClient_InvalidProxy(t *testing.T) { + _, err := createHTTPClient("://bad-proxy", 10*time.Second) + if err == nil { + t.Fatal("createHTTPClient() expected error for invalid proxy URL, got nil") + } +} + +func TestCreateHTTPClient_Socks5ProxyConfigured(t *testing.T) { + client, err := createHTTPClient("socks5://127.0.0.1:1080", 8*time.Second) + if err != nil { + t.Fatalf("createHTTPClient() error: %v", err) + } + + tr, ok := client.Transport.(*http.Transport) + if !ok { + t.Fatalf("client.Transport type = %T, want *http.Transport", client.Transport) + } + req, err := http.NewRequest("GET", "https://example.com", nil) + if err != nil { + t.Fatalf("http.NewRequest() error: %v", err) + } + proxyURL, err := tr.Proxy(req) + if err != nil { + t.Fatalf("transport.Proxy(req) error: %v", err) + } + if proxyURL == nil || proxyURL.String() != "socks5://127.0.0.1:1080" { + t.Fatalf("proxy URL = %v, want %q", proxyURL, "socks5://127.0.0.1:1080") + } +} + +func TestCreateHTTPClient_UnsupportedProxyScheme(t *testing.T) { + _, err := createHTTPClient("ftp://127.0.0.1:21", 10*time.Second) + if err == nil { + t.Fatal("createHTTPClient() expected error for unsupported scheme, got nil") + } + if !strings.Contains(err.Error(), "unsupported proxy scheme") { + t.Fatalf("error = %q, want to contain %q", err.Error(), "unsupported proxy scheme") + } +} + +func TestCreateHTTPClient_ProxyFromEnvironmentWhenConfigEmpty(t *testing.T) { + t.Setenv("HTTP_PROXY", "http://127.0.0.1:8888") + t.Setenv("http_proxy", "http://127.0.0.1:8888") + t.Setenv("HTTPS_PROXY", "http://127.0.0.1:8888") + t.Setenv("https_proxy", "http://127.0.0.1:8888") + t.Setenv("ALL_PROXY", "") + t.Setenv("all_proxy", "") + t.Setenv("NO_PROXY", "") + t.Setenv("no_proxy", "") + + client, err := createHTTPClient("", 10*time.Second) + if err != nil { + t.Fatalf("createHTTPClient() error: %v", err) + } + + tr, ok := client.Transport.(*http.Transport) + if !ok { + t.Fatalf("client.Transport type = %T, want *http.Transport", client.Transport) + } + if tr.Proxy == nil { + t.Fatal("transport.Proxy is nil, want proxy function from environment") + } + + req, err := http.NewRequest("GET", "https://example.com", nil) + if err != nil { + t.Fatalf("http.NewRequest() error: %v", err) + } + if _, err := tr.Proxy(req); err != nil { + t.Fatalf("transport.Proxy(req) error: %v", err) + } +} + +func TestNewWebFetchToolWithProxy(t *testing.T) { + tool := NewWebFetchToolWithProxy(1024, "http://127.0.0.1:7890") + if tool.maxChars != 1024 { + t.Fatalf("maxChars = %d, want %d", tool.maxChars, 1024) + } + if tool.proxy != "http://127.0.0.1:7890" { + t.Fatalf("proxy = %q, want %q", tool.proxy, "http://127.0.0.1:7890") + } + + tool = NewWebFetchToolWithProxy(0, "http://127.0.0.1:7890") + if tool.maxChars != 50000 { + t.Fatalf("default maxChars = %d, want %d", tool.maxChars, 50000) + } +} + +func TestNewWebSearchTool_PropagatesProxy(t *testing.T) { + t.Run("perplexity", func(t *testing.T) { + tool := NewWebSearchTool(WebSearchToolOptions{ + PerplexityEnabled: true, + PerplexityAPIKey: "k", + PerplexityMaxResults: 3, + Proxy: "http://127.0.0.1:7890", + }) + p, ok := tool.provider.(*PerplexitySearchProvider) + if !ok { + t.Fatalf("provider type = %T, want *PerplexitySearchProvider", tool.provider) + } + if p.proxy != "http://127.0.0.1:7890" { + t.Fatalf("provider proxy = %q, want %q", p.proxy, "http://127.0.0.1:7890") + } + }) + + t.Run("brave", func(t *testing.T) { + tool := NewWebSearchTool(WebSearchToolOptions{ + BraveEnabled: true, + BraveAPIKey: "k", + BraveMaxResults: 3, + Proxy: "http://127.0.0.1:7890", + }) + p, ok := tool.provider.(*BraveSearchProvider) + if !ok { + t.Fatalf("provider type = %T, want *BraveSearchProvider", tool.provider) + } + if p.proxy != "http://127.0.0.1:7890" { + t.Fatalf("provider proxy = %q, want %q", p.proxy, "http://127.0.0.1:7890") + } + }) + + t.Run("duckduckgo", func(t *testing.T) { + tool := NewWebSearchTool(WebSearchToolOptions{ + DuckDuckGoEnabled: true, + DuckDuckGoMaxResults: 3, + Proxy: "http://127.0.0.1:7890", + }) + p, ok := tool.provider.(*DuckDuckGoSearchProvider) + if !ok { + t.Fatalf("provider type = %T, want *DuckDuckGoSearchProvider", tool.provider) + } + if p.proxy != "http://127.0.0.1:7890" { + t.Fatalf("provider proxy = %q, want %q", p.proxy, "http://127.0.0.1:7890") + } + }) +} + // TestWebTool_TavilySearch_Success verifies successful Tavily search func TestWebTool_TavilySearch_Success(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { From 8405d390dfaca26fba80fd63728d5f87353e1b92 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 24 Feb 2026 04:19:18 -0500 Subject: [PATCH 35/40] fix: add CGO_ENABLED=0 for static build to fix cross-platform GLIBC errors --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 29e2fc964..111908a79 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ GO_VERSION=$(shell $(GO) version | awk '{print $$3}') LDFLAGS=-ldflags "-X main.version=$(VERSION) -X main.gitCommit=$(GIT_COMMIT) -X main.buildTime=$(BUILD_TIME) -X main.goVersion=$(GO_VERSION) -s -w" # Go variables -GO?=go +GO?=CGO_ENABLED=0 go GOFLAGS?=-v -tags stdjson # Golangci-lint From 0d761ca6084efb1344591870ce58d96b6a9be051 Mon Sep 17 00:00:00 2001 From: yangmanqing Date: Tue, 24 Feb 2026 17:57:28 +0800 Subject: [PATCH 36/40] fix: prevent DefaultConfig template values from leaking into user model_list entries --- pkg/config/config.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pkg/config/config.go b/pkg/config/config.go index 2595398c7..a15a19b91 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -499,6 +499,20 @@ func LoadConfig(path string) (*Config, error) { return nil, err } + // Pre-scan the JSON to check how many model_list entries the user provided. + // Go's JSON decoder reuses existing slice backing-array elements rather than + // zero-initializing them, so fields absent from the user's JSON (e.g. api_base) + // would silently inherit values from the DefaultConfig template at the same + // index position. We only reset cfg.ModelList when the user actually provides + // entries; when count is 0 we keep DefaultConfig's built-in list as fallback. + var tmp Config + if err := json.Unmarshal(data, &tmp); err != nil { + return nil, err + } + if len(tmp.ModelList) > 0 { + cfg.ModelList = nil + } + if err := json.Unmarshal(data, cfg); err != nil { return nil, err } From 78e5bdad29c9c927b72b99b40b3da87d5dc28431 Mon Sep 17 00:00:00 2001 From: Kai Xia Date: Tue, 24 Feb 2026 22:04:23 +1100 Subject: [PATCH 37/40] minor improvements in Makefile Signed-off-by: Kai Xia --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 29e2fc964..30522e7b9 100644 --- a/Makefile +++ b/Makefile @@ -144,6 +144,10 @@ fmt: lint: @$(GOLANGCI_LINT) run +## fix: Fix linting issues +fix: + @$(GOLANGCI_LINT) run --fix + ## deps: Download dependencies deps: @$(GO) mod download @@ -169,7 +173,7 @@ help: @echo " make [target]" @echo "" @echo "Targets:" - @grep -E '^## ' $(MAKEFILE_LIST) | sed 's/## / /' + @grep -E '^## ' $(MAKEFILE_LIST) | sort | awk -F': ' '{printf " %-16s %s\n", substr($$1, 4), $$2}' @echo "" @echo "Examples:" @echo " make build # Build for current platform" From 01e2354b977d580679871379beef24f371bf521e Mon Sep 17 00:00:00 2001 From: yinwm Date: Tue, 24 Feb 2026 19:04:38 +0800 Subject: [PATCH 38/40] fix: align map values for proper formatting --- pkg/config/model_config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/model_config_test.go b/pkg/config/model_config_test.go index c89029e8c..99eea2782 100644 --- a/pkg/config/model_config_test.go +++ b/pkg/config/model_config_test.go @@ -220,7 +220,7 @@ func TestFullConfig_JSON_BackwardCompat(t *testing.T) { }` for name, jsonStr := range map[string]string{ - "old format (model)": oldFormat, + "old format (model)": oldFormat, "new format (model_name)": newFormat, } { t.Run(name, func(t *testing.T) { From 100356e8ec029f689a6b43363ada3556a2163365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20Xia=28=E5=A4=8F=E6=81=BA=29?= Date: Wed, 25 Feb 2026 00:52:25 +1100 Subject: [PATCH 39/40] refactor: cleanup dead code and turn on dead code detection in CI (#515) * cleanup dead code. Signed-off-by: Kai Xia * add these two back with flag. Signed-off-by: Kai Xia * fix ci Signed-off-by: Kai Xia * remove this confusing line Signed-off-by: Kai Xia * make fmt Signed-off-by: Kai Xia * remove unused method. picked up by golangci-lint run Signed-off-by: Kai Xia --------- Signed-off-by: Kai Xia --- .golangci.yaml | 4 +- pkg/agent/context.go | 19 --------- pkg/channels/wecom_app.go | 55 ------------------------- pkg/devices/sources/usb_linux.go | 5 +-- pkg/providers/antigravity_provider.go | 58 --------------------------- pkg/providers/fallback_test.go | 6 --- pkg/tools/i2c.go | 8 ++++ pkg/tools/spi.go | 4 ++ 8 files changed, 17 insertions(+), 142 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index d45d69e67..dd3cbae19 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -66,7 +66,6 @@ linters: - testifylint - thelper - unparam - - unused - usestdlibvars - usetesting - wastedassign @@ -152,6 +151,9 @@ linters: - gocognit - gocyclo path: _test\.go$ + - linters: + - nolintlint + path: 'pkg/tools/(i2c\.go|spi\.go)$' issues: max-issues-per-linter: 0 diff --git a/pkg/agent/context.go b/pkg/agent/context.go index a9db5afdd..ba07e33d3 100644 --- a/pkg/agent/context.go +++ b/pkg/agent/context.go @@ -288,25 +288,6 @@ func (cb *ContextBuilder) AddAssistantMessage( return messages } -func (cb *ContextBuilder) loadSkills() string { - allSkills := cb.skillsLoader.ListSkills() - if len(allSkills) == 0 { - return "" - } - - var skillNames []string - for _, s := range allSkills { - skillNames = append(skillNames, s.Name) - } - - content := cb.skillsLoader.LoadSkillsForContext(skillNames) - if content == "" { - return "" - } - - return "# Skill Definitions\n\n" + content -} - // GetSkillsInfo returns information about loaded skills. func (cb *ContextBuilder) GetSkillsInfo() map[string]any { allSkills := cb.skillsLoader.ListSkills() diff --git a/pkg/channels/wecom_app.go b/pkg/channels/wecom_app.go index 715c48707..302603445 100644 --- a/pkg/channels/wecom_app.go +++ b/pkg/channels/wecom_app.go @@ -571,61 +571,6 @@ func (c *WeComAppChannel) sendTextMessage(ctx context.Context, accessToken, user return nil } -// sendMarkdownMessage sends a markdown message to a user -func (c *WeComAppChannel) sendMarkdownMessage(ctx context.Context, accessToken, userID, content string) error { - apiURL := fmt.Sprintf("%s/cgi-bin/message/send?access_token=%s", wecomAPIBase, accessToken) - - msg := WeComMarkdownMessage{ - ToUser: userID, - MsgType: "markdown", - AgentID: c.config.AgentID, - } - msg.Markdown.Content = content - - jsonData, err := json.Marshal(msg) - if err != nil { - return fmt.Errorf("failed to marshal message: %w", err) - } - - // Use configurable timeout (default 5 seconds) - timeout := c.config.ReplyTimeout - if timeout <= 0 { - timeout = 5 - } - - reqCtx, cancel := context.WithTimeout(ctx, time.Duration(timeout)*time.Second) - defer cancel() - - req, err := http.NewRequestWithContext(reqCtx, http.MethodPost, apiURL, bytes.NewBuffer(jsonData)) - if err != nil { - return fmt.Errorf("failed to create request: %w", err) - } - req.Header.Set("Content-Type", "application/json") - - client := &http.Client{Timeout: time.Duration(timeout) * time.Second} - resp, err := client.Do(req) - if err != nil { - return fmt.Errorf("failed to send message: %w", err) - } - defer resp.Body.Close() - - body, err := io.ReadAll(resp.Body) - if err != nil { - return fmt.Errorf("failed to read response: %w", err) - } - - var sendResp WeComSendMessageResponse - if err := json.Unmarshal(body, &sendResp); err != nil { - return fmt.Errorf("failed to parse response: %w", err) - } - - if sendResp.ErrCode != 0 { - return fmt.Errorf("API error: %s (code: %d)", sendResp.ErrMsg, sendResp.ErrCode) - } - - return nil -} - // handleHealth handles health check requests func (c *WeComAppChannel) handleHealth(w http.ResponseWriter, r *http.Request) { status := map[string]any{ diff --git a/pkg/devices/sources/usb_linux.go b/pkg/devices/sources/usb_linux.go index be0193cfb..2bb38941f 100644 --- a/pkg/devices/sources/usb_linux.go +++ b/pkg/devices/sources/usb_linux.go @@ -35,9 +35,8 @@ var usbClassToCapability = map[string]string{ } type USBMonitor struct { - cmd *exec.Cmd - cancel context.CancelFunc - mu sync.Mutex + cmd *exec.Cmd + mu sync.Mutex } func NewUSBMonitor() *USBMonitor { diff --git a/pkg/providers/antigravity_provider.go b/pkg/providers/antigravity_provider.go index cff67c88c..d4ee528b7 100644 --- a/pkg/providers/antigravity_provider.go +++ b/pkg/providers/antigravity_provider.go @@ -404,64 +404,6 @@ type antigravityJSONResponse struct { } `json:"usageMetadata"` } -func (p *AntigravityProvider) parseJSONResponse(body []byte) (*LLMResponse, error) { - var resp antigravityJSONResponse - if err := json.Unmarshal(body, &resp); err != nil { - return nil, fmt.Errorf("parsing antigravity response: %w", err) - } - - if len(resp.Candidates) == 0 { - return nil, fmt.Errorf("antigravity: no candidates in response") - } - - candidate := resp.Candidates[0] - var contentParts []string - var toolCalls []ToolCall - - for _, part := range candidate.Content.Parts { - if part.Text != "" { - contentParts = append(contentParts, part.Text) - } - if part.FunctionCall != nil { - argumentsJSON, _ := json.Marshal(part.FunctionCall.Args) - toolCalls = append(toolCalls, ToolCall{ - ID: fmt.Sprintf("call_%s_%d", part.FunctionCall.Name, time.Now().UnixNano()), - Name: part.FunctionCall.Name, - Arguments: part.FunctionCall.Args, - Function: &FunctionCall{ - Name: part.FunctionCall.Name, - Arguments: string(argumentsJSON), - ThoughtSignature: extractPartThoughtSignature(part.ThoughtSignature, part.ThoughtSignatureSnake), - }, - }) - } - } - - finishReason := "stop" - if len(toolCalls) > 0 { - finishReason = "tool_calls" - } - if candidate.FinishReason == "MAX_TOKENS" { - finishReason = "length" - } - - var usage *UsageInfo - if resp.UsageMetadata.TotalTokenCount > 0 { - usage = &UsageInfo{ - PromptTokens: resp.UsageMetadata.PromptTokenCount, - CompletionTokens: resp.UsageMetadata.CandidatesTokenCount, - TotalTokens: resp.UsageMetadata.TotalTokenCount, - } - } - - return &LLMResponse{ - Content: strings.Join(contentParts, ""), - ToolCalls: toolCalls, - FinishReason: finishReason, - Usage: usage, - }, nil -} - func (p *AntigravityProvider) parseSSEResponse(body string) (*LLMResponse, error) { var contentParts []string var toolCalls []ToolCall diff --git a/pkg/providers/fallback_test.go b/pkg/providers/fallback_test.go index e872c672e..ebba054ef 100644 --- a/pkg/providers/fallback_test.go +++ b/pkg/providers/fallback_test.go @@ -17,12 +17,6 @@ func successRun(content string) func(ctx context.Context, provider, model string } } -func failRun(err error) func(ctx context.Context, provider, model string) (*LLMResponse, error) { - return func(ctx context.Context, provider, model string) (*LLMResponse, error) { - return nil, err - } -} - func TestFallback_SingleCandidate_Success(t *testing.T) { ct := NewCooldownTracker() fc := NewFallbackChain(ct) diff --git a/pkg/tools/i2c.go b/pkg/tools/i2c.go index 0387a26d3..779b1d5a7 100644 --- a/pkg/tools/i2c.go +++ b/pkg/tools/i2c.go @@ -117,13 +117,19 @@ func (t *I2CTool) detect() *ToolResult { return SilentResult(fmt.Sprintf("Found %d I2C bus(es):\n%s", len(buses), string(result))) } +// Helper functions for I2C operations (used by platform-specific implementations) + // isValidBusID checks that a bus identifier is a simple number (prevents path injection) +// +//nolint:unused // Used by i2c_linux.go func isValidBusID(id string) bool { matched, _ := regexp.MatchString(`^\d+$`, id) return matched } // parseI2CAddress extracts and validates an I2C address from args +// +//nolint:unused // Used by i2c_linux.go func parseI2CAddress(args map[string]any) (int, *ToolResult) { addrFloat, ok := args["address"].(float64) if !ok { @@ -137,6 +143,8 @@ func parseI2CAddress(args map[string]any) (int, *ToolResult) { } // parseI2CBus extracts and validates an I2C bus from args +// +//nolint:unused // Used by i2c_linux.go func parseI2CBus(args map[string]any) (string, *ToolResult) { bus, ok := args["bus"].(string) if !ok || bus == "" { diff --git a/pkg/tools/spi.go b/pkg/tools/spi.go index d6a88a5b0..0ca17e84f 100644 --- a/pkg/tools/spi.go +++ b/pkg/tools/spi.go @@ -119,7 +119,11 @@ func (t *SPITool) list() *ToolResult { return SilentResult(fmt.Sprintf("Found %d SPI device(s):\n%s", len(devices), string(result))) } +// Helper function for SPI operations (used by platform-specific implementations) + // parseSPIArgs extracts and validates common SPI parameters +// +//nolint:unused // Used by spi_linux.go func parseSPIArgs(args map[string]any) (device string, speed uint32, mode uint8, bits uint8, errMsg string) { dev, ok := args["device"].(string) if !ok || dev == "" { From d09c64fcee20e9eabb13ca9c8de483747aafa930 Mon Sep 17 00:00:00 2001 From: Lixeer <1612655510@qq.com> Date: Tue, 24 Feb 2026 22:33:04 +0800 Subject: [PATCH 40/40] fix: implement code review suggestions Address all feedback from PR review: - Lock granularity - Empty response handling - Shutdown race condition - Interface naming --- cmd/picoclaw/cmd_gateway.go | 4 ++-- pkg/providers/github_copilot_provider.go | 21 +++++++++++++-------- pkg/providers/types.go | 2 +- pkg/tools/registry_test.go | 20 ++++++++++---------- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/cmd/picoclaw/cmd_gateway.go b/cmd/picoclaw/cmd_gateway.go index 30d61aec3..fea569381 100644 --- a/cmd/picoclaw/cmd_gateway.go +++ b/cmd/picoclaw/cmd_gateway.go @@ -211,10 +211,10 @@ func gatewayCmd() { <-sigChan fmt.Println("\nShutting down...") - cancel() - if cp, ok := provider.(providers.SessionProvider); ok { + if cp, ok := provider.(providers.StatefulProvider); ok { cp.Close() } + cancel() healthServer.Stop(context.Background()) deviceService.Stop() heartbeatService.Stop() diff --git a/pkg/providers/github_copilot_provider.go b/pkg/providers/github_copilot_provider.go index c69658b44..9210021e1 100644 --- a/pkg/providers/github_copilot_provider.go +++ b/pkg/providers/github_copilot_provider.go @@ -94,19 +94,24 @@ func (p *GitHubCopilotProvider) Chat( return nil, fmt.Errorf("marshal messages: %w", err) } p.mu.Lock() - defer p.mu.Unlock() + session := p.session + p.mu.Unlock() - resp, err := p.session.SendAndWait(ctx, copilot.MessageOptions{ + if session == nil { + return nil, fmt.Errorf("provider closed") + } + + resp, err := session.SendAndWait(ctx, copilot.MessageOptions{ Prompt: string(fullcontent), }) - if err != nil { - return nil, err - } - var content string - if resp != nil && resp.Data.Content != nil { - content = *resp.Data.Content + if resp == nil { + return nil, fmt.Errorf("empty response from copilot") } + if resp.Data.Content == nil { + return nil, fmt.Errorf("no content in copilot response") + } + content := *resp.Data.Content return &LLMResponse{ FinishReason: "stop", diff --git a/pkg/providers/types.go b/pkg/providers/types.go index 40ff6f7c8..b2dda04a5 100644 --- a/pkg/providers/types.go +++ b/pkg/providers/types.go @@ -30,7 +30,7 @@ type LLMProvider interface { GetDefaultModel() string } -type SessionProvider interface { +type StatefulProvider interface { LLMProvider Close() } diff --git a/pkg/tools/registry_test.go b/pkg/tools/registry_test.go index 8ae13b20c..33978e543 100644 --- a/pkg/tools/registry_test.go +++ b/pkg/tools/registry_test.go @@ -14,14 +14,14 @@ import ( type mockRegistryTool struct { name string desc string - params map[string]any + params map[string]interface{} result *ToolResult } -func (m *mockRegistryTool) Name() string { return m.name } -func (m *mockRegistryTool) Description() string { return m.desc } -func (m *mockRegistryTool) Parameters() map[string]any { return m.params } -func (m *mockRegistryTool) Execute(_ context.Context, _ map[string]any) *ToolResult { +func (m *mockRegistryTool) Name() string { return m.name } +func (m *mockRegistryTool) Description() string { return m.desc } +func (m *mockRegistryTool) Parameters() map[string]interface{} { return m.params } +func (m *mockRegistryTool) Execute(_ context.Context, _ map[string]interface{}) *ToolResult { return m.result } @@ -51,7 +51,7 @@ func newMockTool(name, desc string) *mockRegistryTool { return &mockRegistryTool{ name: name, desc: desc, - params: map[string]any{"type": "object"}, + params: map[string]interface{}{"type": "object"}, result: SilentResult("ok"), } } @@ -109,7 +109,7 @@ func TestToolRegistry_Execute_Success(t *testing.T) { r.Register(&mockRegistryTool{ name: "greet", desc: "says hello", - params: map[string]any{}, + params: map[string]interface{}{}, result: SilentResult("hello"), }) @@ -203,7 +203,7 @@ func TestToolRegistry_GetDefinitions(t *testing.T) { if defs[0]["type"] != "function" { t.Errorf("expected type 'function', got %v", defs[0]["type"]) } - fn, ok := defs[0]["function"].(map[string]any) + fn, ok := defs[0]["function"].(map[string]interface{}) if !ok { t.Fatal("expected 'function' key to be a map") } @@ -217,7 +217,7 @@ func TestToolRegistry_GetDefinitions(t *testing.T) { func TestToolRegistry_ToProviderDefs(t *testing.T) { r := NewToolRegistry() - params := map[string]any{"type": "object", "properties": map[string]any{}} + params := map[string]interface{}{"type": "object", "properties": map[string]interface{}{}} r.Register(&mockRegistryTool{ name: "beta", desc: "tool B", @@ -310,7 +310,7 @@ func TestToolToSchema(t *testing.T) { if schema["type"] != "function" { t.Errorf("expected type 'function', got %v", schema["type"]) } - fn, ok := schema["function"].(map[string]any) + fn, ok := schema["function"].(map[string]interface{}) if !ok { t.Fatal("expected 'function' to be a map") }

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 Date: Tue, 24 Feb 2026 14:47:40 +0800 Subject: [PATCH 33/40] docs: add wechat and discord badge (#707) Signed-off-by: Guoguo --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 84d92115b..778530db5 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,9 @@
Website Twitter +
+ + Discord

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 ZcS`}Nmr^nhTC?^iWQVnMgke}I{a<4CA~*m5 From d224397f40a798ae9ddf4e7a9f00aaf3d62620dd Mon Sep 17 00:00:00 2001 From: winterfx Date: Sat, 21 Feb 2026 23:29:40 +0800 Subject: [PATCH 10/40] fix: preserve reasoning_content for OpenAI-compatible reasoning models Models like Moonshot kimi-k2.5 and DeepSeek-R1 return a reasoning_content field in assistant messages. When thinking is enabled, the API requires this field to be echoed back in subsequent requests. PicoClaw was silently dropping it, causing 400 errors on tool-call round-trips. - Add ReasoningContent to Message and LLMResponse types - Parse reasoning_content in openai_compat parseResponse() - Carry reasoning_content through assistant tool-call messages - Add unit test for reasoning_content parsing Fixes #588 --- pkg/agent/loop.go | 5 ++- pkg/providers/openai_compat/provider.go | 14 ++++--- pkg/providers/openai_compat/provider_test.go | 44 ++++++++++++++++++++ pkg/providers/protocoltypes/types.go | 18 ++++---- 4 files changed, 65 insertions(+), 16 deletions(-) diff --git a/pkg/agent/loop.go b/pkg/agent/loop.go index b36f4a0c4..92cede616 100644 --- a/pkg/agent/loop.go +++ b/pkg/agent/loop.go @@ -622,8 +622,9 @@ func (al *AgentLoop) runLLMIteration( // Build assistant message with tool calls assistantMsg := providers.Message{ - Role: "assistant", - Content: response.Content, + Role: "assistant", + Content: response.Content, + ReasoningContent: response.ReasoningContent, } for _, tc := range normalizedToolCalls { argumentsJSON, _ := json.Marshal(tc.Arguments) diff --git a/pkg/providers/openai_compat/provider.go b/pkg/providers/openai_compat/provider.go index b8528953a..f35d89c85 100644 --- a/pkg/providers/openai_compat/provider.go +++ b/pkg/providers/openai_compat/provider.go @@ -148,8 +148,9 @@ func parseResponse(body []byte) (*LLMResponse, error) { var apiResponse struct { Choices []struct { Message struct { - Content string `json:"content"` - ToolCalls []struct { + Content string `json:"content"` + ReasoningContent string `json:"reasoning_content"` + ToolCalls []struct { ID string `json:"id"` Type string `json:"type"` Function *struct { @@ -221,10 +222,11 @@ func parseResponse(body []byte) (*LLMResponse, error) { } return &LLMResponse{ - Content: choice.Message.Content, - ToolCalls: toolCalls, - FinishReason: choice.FinishReason, - Usage: apiResponse.Usage, + Content: choice.Message.Content, + ReasoningContent: choice.Message.ReasoningContent, + ToolCalls: toolCalls, + FinishReason: choice.FinishReason, + Usage: apiResponse.Usage, }, nil } diff --git a/pkg/providers/openai_compat/provider_test.go b/pkg/providers/openai_compat/provider_test.go index 42f9d42ab..594a48213 100644 --- a/pkg/providers/openai_compat/provider_test.go +++ b/pkg/providers/openai_compat/provider_test.go @@ -101,6 +101,50 @@ func TestProviderChat_ParsesToolCalls(t *testing.T) { } } +func TestProviderChat_ParsesReasoningContent(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + resp := map[string]any{ + "choices": []map[string]any{ + { + "message": map[string]any{ + "content": "The answer is 2", + "reasoning_content": "Let me think step by step... 1+1=2", + "tool_calls": []map[string]any{ + { + "id": "call_1", + "type": "function", + "function": map[string]any{ + "name": "calculator", + "arguments": "{\"expr\":\"1+1\"}", + }, + }, + }, + }, + "finish_reason": "tool_calls", + }, + }, + } + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(resp) + })) + defer server.Close() + + p := NewProvider("key", server.URL, "") + out, err := p.Chat(t.Context(), []Message{{Role: "user", Content: "1+1=?"}}, nil, "kimi-k2.5", nil) + if err != nil { + t.Fatalf("Chat() error = %v", err) + } + if out.ReasoningContent != "Let me think step by step... 1+1=2" { + t.Fatalf("ReasoningContent = %q, want %q", out.ReasoningContent, "Let me think step by step... 1+1=2") + } + if out.Content != "The answer is 2" { + t.Fatalf("Content = %q, want %q", out.Content, "The answer is 2") + } + if len(out.ToolCalls) != 1 { + t.Fatalf("len(ToolCalls) = %d, want 1", len(out.ToolCalls)) + } +} + func TestProviderChat_HTTPError(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "bad request", http.StatusBadRequest) diff --git a/pkg/providers/protocoltypes/types.go b/pkg/providers/protocoltypes/types.go index 3a089ca47..d6928e1ed 100644 --- a/pkg/providers/protocoltypes/types.go +++ b/pkg/providers/protocoltypes/types.go @@ -25,10 +25,11 @@ type FunctionCall struct { } type LLMResponse struct { - Content string `json:"content"` - ToolCalls []ToolCall `json:"tool_calls,omitempty"` - FinishReason string `json:"finish_reason"` - Usage *UsageInfo `json:"usage,omitempty"` + Content string `json:"content"` + ReasoningContent string `json:"reasoning_content,omitempty"` + ToolCalls []ToolCall `json:"tool_calls,omitempty"` + FinishReason string `json:"finish_reason"` + Usage *UsageInfo `json:"usage,omitempty"` } type UsageInfo struct { @@ -38,10 +39,11 @@ type UsageInfo struct { } type Message struct { - Role string `json:"role"` - Content string `json:"content"` - ToolCalls []ToolCall `json:"tool_calls,omitempty"` - ToolCallID string `json:"tool_call_id,omitempty"` + Role string `json:"role"` + Content string `json:"content"` + ReasoningContent string `json:"reasoning_content,omitempty"` + ToolCalls []ToolCall `json:"tool_calls,omitempty"` + ToolCallID string `json:"tool_call_id,omitempty"` } type ToolDefinition struct { From c51ceac70b66acc30d42a31e9f77d784b190890c Mon Sep 17 00:00:00 2001 From: Albert Simon <47634918+willyw0nka@users.noreply.github.com> Date: Sat, 21 Feb 2026 23:53:53 +0100 Subject: [PATCH 11/40] fix: updated model configuration links at readme (#544) Signed-off-by: Albert Simon From b9a66248d8fd88644f1fec3f8be35fbbc23d4803 Mon Sep 17 00:00:00 2001 From: kernoeb Date: Sun, 22 Feb 2026 01:32:44 +0100 Subject: [PATCH 12/40] fix: resolve Groq STT key from model_list when providers.groq is absent (#602) When users migrate from the legacy `providers` config to the new `model_list` format, voice transcription silently breaks on Telegram, Discord and Slack channels. The gateway was reading the Groq API key exclusively from `cfg.Providers.Groq.APIKey`, which is empty once the key is defined only inside a `model_list` entry. The transcriber was never initialized, so voice messages fell back to a plain `[voice]` placeholder. This fix also scans `model_list` for any entry whose `model` field starts with `groq/` and uses its `api_key` as a fallback, preserving full backward compatibility with the legacy `providers.groq` field. --- cmd/picoclaw/cmd_gateway.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cmd/picoclaw/cmd_gateway.go b/cmd/picoclaw/cmd_gateway.go index 9a3b6aa19..28ef76ad3 100644 --- a/cmd/picoclaw/cmd_gateway.go +++ b/cmd/picoclaw/cmd_gateway.go @@ -10,6 +10,7 @@ import ( "os" "os/signal" "path/filepath" + "strings" "time" "github.com/sipeed/picoclaw/pkg/agent" @@ -121,8 +122,17 @@ func gatewayCmd() { agentLoop.SetChannelManager(channelManager) var transcriber *voice.GroqTranscriber - if cfg.Providers.Groq.APIKey != "" { - transcriber = voice.NewGroqTranscriber(cfg.Providers.Groq.APIKey) + groqAPIKey := cfg.Providers.Groq.APIKey + if groqAPIKey == "" { + for _, mc := range cfg.ModelList { + if strings.HasPrefix(mc.Model, "groq/") && mc.APIKey != "" { + groqAPIKey = mc.APIKey + break + } + } + } + if groqAPIKey != "" { + transcriber = voice.NewGroqTranscriber(groqAPIKey) logger.InfoC("voice", "Groq voice transcription enabled") } From cec6fd4cd4689bac068b4710aed0b26e98c77541 Mon Sep 17 00:00:00 2001 From: Yoftahe Abraham Date: Sun, 22 Feb 2026 10:27:38 +0300 Subject: [PATCH 13/40] fix: should use fmt.Printf instead of fmt.Print(fmt.Sprintf(...)) (#623) --- cmd/picoclaw/cmd_agent.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/picoclaw/cmd_agent.go b/cmd/picoclaw/cmd_agent.go index 6d6ff935f..8658c9d32 100644 --- a/cmd/picoclaw/cmd_agent.go +++ b/cmd/picoclaw/cmd_agent.go @@ -148,7 +148,7 @@ func interactiveMode(agentLoop *agent.AgentLoop, sessionKey string) { func simpleInteractiveMode(agentLoop *agent.AgentLoop, sessionKey string) { reader := bufio.NewReader(os.Stdin) for { - fmt.Print(fmt.Sprintf("%s You: ", logo)) + fmt.Printf("%s You: ", logo) line, err := reader.ReadString('\n') if err != nil { if err == io.EOF { From 65422a16a4f9a04ecc55b066b800e92859b9f376 Mon Sep 17 00:00:00 2001 From: Edouard CLAUDE Date: Fri, 20 Feb 2026 19:31:35 +0400 Subject: [PATCH 14/40] feat: add native Mistral AI provider support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Mistral as a first-class provider alongside the 17 existing ones. Mistral uses the OpenAI-compatible API at https://api.mistral.ai/v1 with provider-specific model prefix stripping (mistral/model → model). Changes: - Add Mistral to ProvidersConfig, IsEmpty(), HasProvidersConfig() - Add mistral entry in default model_list (defaults.go) - Add mistral protocol in factory_provider.go and getDefaultAPIBase() - Add mistral prefix stripping in openai_compat normalizeModel() - Add mistral case in legacy factory.go resolveProviderSelection() - Add mistral migration entry in ConvertProvidersToModelList() - Add mistral to supported providers in migrate/config.go - Add mistral section in config.example.json - Update AllProviders test (17 → 18 providers) Tested end-to-end with mistral-small-latest model. --- config/config.example.json | 4 ++++ pkg/config/config.go | 7 +++++-- pkg/config/defaults.go | 8 ++++++++ pkg/config/migration.go | 16 ++++++++++++++++ pkg/config/migration_test.go | 7 ++++--- pkg/migrate/config.go | 1 + pkg/providers/factory.go | 16 ++++++++++++++++ pkg/providers/factory_provider.go | 4 +++- pkg/providers/openai_compat/provider.go | 2 +- 9 files changed, 58 insertions(+), 7 deletions(-) diff --git a/config/config.example.json b/config/config.example.json index 77a8c0683..e814fcbb8 100644 --- a/config/config.example.json +++ b/config/config.example.json @@ -196,6 +196,10 @@ "volcengine": { "api_key": "", "api_base": "" + }, + "mistral": { + "api_key": "", + "api_base": "https://api.mistral.ai/v1" } }, "tools": { diff --git a/pkg/config/config.go b/pkg/config/config.go index 20556011a..440ac5436 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -324,6 +324,7 @@ type ProvidersConfig struct { GitHubCopilot ProviderConfig `json:"github_copilot"` Antigravity ProviderConfig `json:"antigravity"` Qwen ProviderConfig `json:"qwen"` + Mistral ProviderConfig `json:"mistral"` } // IsEmpty checks if all provider configs are empty (no API keys or API bases set) @@ -345,7 +346,8 @@ func (p ProvidersConfig) IsEmpty() bool { p.VolcEngine.APIKey == "" && p.VolcEngine.APIBase == "" && p.GitHubCopilot.APIKey == "" && p.GitHubCopilot.APIBase == "" && p.Antigravity.APIKey == "" && p.Antigravity.APIBase == "" && - p.Qwen.APIKey == "" && p.Qwen.APIBase == "" + p.Qwen.APIKey == "" && p.Qwen.APIBase == "" && + p.Mistral.APIKey == "" && p.Mistral.APIBase == "" } // MarshalJSON implements custom JSON marshaling for ProvidersConfig @@ -636,7 +638,8 @@ func (c *Config) HasProvidersConfig() bool { v.VolcEngine.APIKey != "" || v.VolcEngine.APIBase != "" || v.GitHubCopilot.APIKey != "" || v.GitHubCopilot.APIBase != "" || v.Antigravity.APIKey != "" || v.Antigravity.APIBase != "" || - v.Qwen.APIKey != "" || v.Qwen.APIBase != "" + v.Qwen.APIKey != "" || v.Qwen.APIBase != "" || + v.Mistral.APIKey != "" || v.Mistral.APIBase != "" } // ValidateModelList validates all ModelConfig entries in the model_list. diff --git a/pkg/config/defaults.go b/pkg/config/defaults.go index 7654326e7..065273c28 100644 --- a/pkg/config/defaults.go +++ b/pkg/config/defaults.go @@ -255,6 +255,14 @@ func DefaultConfig() *Config { APIKey: "ollama", }, + // Mistral AI - https://console.mistral.ai/api-keys + { + ModelName: "mistral-small", + Model: "mistral/mistral-small-latest", + APIBase: "https://api.mistral.ai/v1", + APIKey: "", + }, + // VLLM (local) - http://localhost:8000 { ModelName: "local-model", diff --git a/pkg/config/migration.go b/pkg/config/migration.go index 689e2312f..30eaa7474 100644 --- a/pkg/config/migration.go +++ b/pkg/config/migration.go @@ -324,6 +324,22 @@ func ConvertProvidersToModelList(cfg *Config) []ModelConfig { }, true }, }, + { + providerNames: []string{"mistral"}, + protocol: "mistral", + buildConfig: func(p ProvidersConfig) (ModelConfig, bool) { + if p.Mistral.APIKey == "" && p.Mistral.APIBase == "" { + return ModelConfig{}, false + } + return ModelConfig{ + ModelName: "mistral", + Model: "mistral/mistral-small-latest", + APIKey: p.Mistral.APIKey, + APIBase: p.Mistral.APIBase, + Proxy: p.Mistral.Proxy, + }, true + }, + }, } // Process each provider migration diff --git a/pkg/config/migration_test.go b/pkg/config/migration_test.go index 1e8139e68..42165cb71 100644 --- a/pkg/config/migration_test.go +++ b/pkg/config/migration_test.go @@ -131,14 +131,15 @@ func TestConvertProvidersToModelList_AllProviders(t *testing.T) { GitHubCopilot: ProviderConfig{ConnectMode: "grpc"}, Antigravity: ProviderConfig{AuthMethod: "oauth"}, Qwen: ProviderConfig{APIKey: "key17"}, + Mistral: ProviderConfig{APIKey: "key18"}, }, } result := ConvertProvidersToModelList(cfg) - // All 17 providers should be converted - if len(result) != 17 { - t.Errorf("len(result) = %d, want 17", len(result)) + // All 18 providers should be converted + if len(result) != 18 { + t.Errorf("len(result) = %d, want 18", len(result)) } } diff --git a/pkg/migrate/config.go b/pkg/migrate/config.go index 2237a1429..24ce33e94 100644 --- a/pkg/migrate/config.go +++ b/pkg/migrate/config.go @@ -22,6 +22,7 @@ var supportedProviders = map[string]bool{ "qwen": true, "deepseek": true, "github_copilot": true, + "mistral": true, } var supportedChannels = map[string]bool{ diff --git a/pkg/providers/factory.go b/pkg/providers/factory.go index b6f1b5e21..cda4753ea 100644 --- a/pkg/providers/factory.go +++ b/pkg/providers/factory.go @@ -172,6 +172,15 @@ func resolveProviderSelection(cfg *config.Config) (providerSelection, error) { sel.model = "deepseek-chat" } } + case "mistral": + if cfg.Providers.Mistral.APIKey != "" { + sel.apiKey = cfg.Providers.Mistral.APIKey + sel.apiBase = cfg.Providers.Mistral.APIBase + sel.proxy = cfg.Providers.Mistral.Proxy + if sel.apiBase == "" { + sel.apiBase = "https://api.mistral.ai/v1" + } + } case "github_copilot", "copilot": sel.providerType = providerTypeGitHubCopilot if cfg.Providers.GitHubCopilot.APIBase != "" { @@ -275,6 +284,13 @@ func resolveProviderSelection(cfg *config.Config) (providerSelection, error) { if sel.apiBase == "" { sel.apiBase = "http://localhost:11434/v1" } + case (strings.Contains(lowerModel, "mistral") || strings.HasPrefix(model, "mistral/")) && cfg.Providers.Mistral.APIKey != "": + sel.apiKey = cfg.Providers.Mistral.APIKey + sel.apiBase = cfg.Providers.Mistral.APIBase + sel.proxy = cfg.Providers.Mistral.Proxy + if sel.apiBase == "" { + sel.apiBase = "https://api.mistral.ai/v1" + } case cfg.Providers.VLLM.APIBase != "": sel.apiKey = cfg.Providers.VLLM.APIKey sel.apiBase = cfg.Providers.VLLM.APIBase diff --git a/pkg/providers/factory_provider.go b/pkg/providers/factory_provider.go index 74fe8a36c..7d5566eef 100644 --- a/pkg/providers/factory_provider.go +++ b/pkg/providers/factory_provider.go @@ -88,7 +88,7 @@ func CreateProviderFromConfig(cfg *config.ModelConfig) (LLMProvider, string, err case "openrouter", "groq", "zhipu", "gemini", "nvidia", "ollama", "moonshot", "shengsuanyun", "deepseek", "cerebras", - "volcengine", "vllm", "qwen": + "volcengine", "vllm", "qwen", "mistral": // All other OpenAI-compatible HTTP providers if cfg.APIKey == "" && cfg.APIBase == "" { return nil, "", fmt.Errorf("api_key or api_base is required for HTTP-based protocol %q", protocol) @@ -186,6 +186,8 @@ func getDefaultAPIBase(protocol string) string { return "https://dashscope.aliyuncs.com/compatible-mode/v1" case "vllm": return "http://localhost:8000/v1" + case "mistral": + return "https://api.mistral.ai/v1" default: return "" } diff --git a/pkg/providers/openai_compat/provider.go b/pkg/providers/openai_compat/provider.go index b8528953a..236a048c4 100644 --- a/pkg/providers/openai_compat/provider.go +++ b/pkg/providers/openai_compat/provider.go @@ -240,7 +240,7 @@ func normalizeModel(model, apiBase string) string { prefix := strings.ToLower(model[:idx]) switch prefix { - case "moonshot", "nvidia", "groq", "ollama", "deepseek", "google", "openrouter", "zhipu": + case "moonshot", "nvidia", "groq", "ollama", "deepseek", "google", "openrouter", "zhipu", "mistral": return model[idx+1:] default: return model From 34a8ce5af05618057837db05828f3867e6cd4fdf Mon Sep 17 00:00:00 2001 From: Edouard CLAUDE Date: Sat, 21 Feb 2026 05:32:18 +0400 Subject: [PATCH 15/40] fix: remove extra fields from ToolCall JSON serialization Mistral's API strictly validates tool_calls in assistant messages and rejects non-standard fields. The ToolCall struct had Name and Arguments as top-level JSON fields, duplicating data already in Function.Name and Function.Arguments. OpenAI silently ignored these extras but Mistral returns 422. Change json tags to "-" so these internal fields are no longer serialized to API payloads while remaining available in Go code. --- pkg/providers/protocoltypes/types.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/providers/protocoltypes/types.go b/pkg/providers/protocoltypes/types.go index 3a089ca47..5e1c6d397 100644 --- a/pkg/providers/protocoltypes/types.go +++ b/pkg/providers/protocoltypes/types.go @@ -4,8 +4,8 @@ type ToolCall struct { ID string `json:"id"` Type string `json:"type,omitempty"` Function *FunctionCall `json:"function,omitempty"` - Name string `json:"name,omitempty"` - Arguments map[string]any `json:"arguments,omitempty"` + Name string `json:"-"` + Arguments map[string]any `json:"-"` ThoughtSignature string `json:"-"` // Internal use only ExtraContent *ExtraContent `json:"extra_content,omitempty"` } From 6b55fb5f1df3ee6852c31d579b3dc04b742cc704 Mon Sep 17 00:00:00 2001 From: Ali Zulfiqar Date: Sun, 22 Feb 2026 15:00:15 +0500 Subject: [PATCH 16/40] docs: fix typos, broken links and inconsistencies in README (#608) * docs: fix typos, broken links and inconsistencies in README * docs: revert unintentional bullet style changes * docs: fix changes * docs: fixing issues * docs: updating roadmap link * docs: removing * --- README.md | 142 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 78 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 7bc7b1089..de6fd87ea 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,8 @@ Twitter