mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
Merge pull request #770 from xiaket/ci-golangci-cleanup
(ci) golangci cleanup
This commit is contained in:
@@ -28,9 +28,7 @@ linters:
|
||||
- wsl_v5
|
||||
|
||||
# TODO: Disabled, because they are failing at the moment, we should fix them and enable (step by step)
|
||||
- bodyclose
|
||||
- contextcheck
|
||||
- dogsled
|
||||
- embeddedstructfieldcheck
|
||||
- errcheck
|
||||
- errchkjson
|
||||
@@ -45,21 +43,16 @@ linters:
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- godox
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- ineffassign
|
||||
- lll
|
||||
- maintidx
|
||||
- misspell
|
||||
- mnd
|
||||
- modernize
|
||||
- nakedret
|
||||
- nestif
|
||||
- nilnil
|
||||
- paralleltest
|
||||
- perfsprint
|
||||
- prealloc
|
||||
- predeclared
|
||||
- revive
|
||||
- staticcheck
|
||||
- tagalign
|
||||
@@ -68,8 +61,6 @@ linters:
|
||||
- unparam
|
||||
- usestdlibvars
|
||||
- usetesting
|
||||
- wastedassign
|
||||
- whitespace
|
||||
settings:
|
||||
errcheck:
|
||||
check-type-assertions: true
|
||||
|
||||
@@ -37,15 +37,13 @@ func FormatVersion() string {
|
||||
}
|
||||
|
||||
// FormatBuildInfo returns build time and go version info
|
||||
func FormatBuildInfo() (build string, goVer string) {
|
||||
if buildTime != "" {
|
||||
build = buildTime
|
||||
}
|
||||
goVer = goVersion
|
||||
func FormatBuildInfo() (string, string) {
|
||||
build := buildTime
|
||||
goVer := goVersion
|
||||
if goVer == "" {
|
||||
goVer = runtime.Version()
|
||||
}
|
||||
return
|
||||
return build, goVer
|
||||
}
|
||||
|
||||
// GetVersion returns the version string
|
||||
|
||||
+1
-1
@@ -800,7 +800,7 @@ func (al *AgentLoop) forceCompression(agent *AgentInstance, sessionKey string) {
|
||||
droppedCount := mid
|
||||
keptConversation := conversation[mid:]
|
||||
|
||||
newHistory := make([]providers.Message, 0)
|
||||
newHistory := make([]providers.Message, 0, 1+len(keptConversation)+1)
|
||||
|
||||
// Append compression note to the original system prompt instead of adding a new system message
|
||||
// This avoids having two consecutive system messages which some APIs (like Zhipu) reject
|
||||
|
||||
+1
-1
@@ -156,7 +156,7 @@ func LoginBrowser(cfg OAuthProviderConfig) (*AuthCredential, error) {
|
||||
return exchangeCodeForTokens(cfg, result.code, pkce.CodeVerifier, redirectURI)
|
||||
case manualInput := <-manualCh:
|
||||
if manualInput == "" {
|
||||
return nil, fmt.Errorf("manual input cancelled")
|
||||
return nil, fmt.Errorf("manual input canceled")
|
||||
}
|
||||
// Extract code from URL if it's a full URL
|
||||
code := manualInput
|
||||
|
||||
@@ -233,7 +233,7 @@ func (c *DiscordChannel) handleMessage(s *discordgo.Session, m *discordgo.Messag
|
||||
if localPath != "" {
|
||||
localFiles = append(localFiles, localPath)
|
||||
|
||||
transcribedText := ""
|
||||
var transcribedText string
|
||||
if c.transcriber != nil && c.transcriber.IsAvailable() {
|
||||
ctx, cancel := context.WithTimeout(c.getContext(), transcriptionTimeout)
|
||||
result, err := c.transcriber.Transcribe(ctx, localPath)
|
||||
|
||||
@@ -174,7 +174,10 @@ func (c *OneBotChannel) connect() error {
|
||||
header["Authorization"] = []string{"Bearer " + c.config.AccessToken}
|
||||
}
|
||||
|
||||
conn, _, err := dialer.Dial(c.config.WSUrl, header)
|
||||
conn, resp, err := dialer.Dial(c.config.WSUrl, header)
|
||||
if resp != nil {
|
||||
resp.Body.Close()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -310,7 +313,7 @@ func (c *OneBotChannel) sendAPIRequest(action string, params any, timeout time.D
|
||||
case <-time.After(timeout):
|
||||
return nil, fmt.Errorf("API request %s timed out after %v", action, timeout)
|
||||
case <-c.ctx.Done():
|
||||
return nil, fmt.Errorf("context cancelled")
|
||||
return nil, fmt.Errorf("context canceled")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -695,7 +698,6 @@ func (c *OneBotChannel) parseMessageSegments(raw json.RawMessage, selfID int64)
|
||||
textParts = append(textParts, "[forward message]")
|
||||
|
||||
default:
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -439,5 +439,5 @@ func parseSlackChatID(chatID string) (channelID, threadTS string) {
|
||||
if len(parts) > 1 {
|
||||
threadTS = parts[1]
|
||||
}
|
||||
return
|
||||
return channelID, threadTS
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ func (c *TelegramChannel) handleMessage(ctx context.Context, message *telego.Mes
|
||||
localFiles = append(localFiles, voicePath)
|
||||
mediaPaths = append(mediaPaths, voicePath)
|
||||
|
||||
transcribedText := ""
|
||||
var transcribedText string
|
||||
if c.transcriber != nil && c.transcriber.IsAvailable() {
|
||||
transcriberCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
@@ -41,7 +41,10 @@ func (c *WhatsAppChannel) Start(ctx context.Context) error {
|
||||
dialer := websocket.DefaultDialer
|
||||
dialer.HandshakeTimeout = 10 * time.Second
|
||||
|
||||
conn, _, err := dialer.Dial(c.url, nil)
|
||||
conn, resp, err := dialer.Dial(c.url, nil)
|
||||
if resp != nil {
|
||||
resp.Body.Close()
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to connect to WhatsApp bridge: %w", err)
|
||||
}
|
||||
|
||||
+23
-23
@@ -166,7 +166,7 @@ func (hs *HeartbeatService) executeHeartbeat() {
|
||||
}
|
||||
|
||||
if handler == nil {
|
||||
hs.logError("Heartbeat handler not configured")
|
||||
hs.logErrorf("Heartbeat handler not configured")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -175,23 +175,23 @@ func (hs *HeartbeatService) executeHeartbeat() {
|
||||
channel, chatID := hs.parseLastChannel(lastChannel)
|
||||
|
||||
// Debug log for channel resolution
|
||||
hs.logInfo("Resolved channel: %s, chatID: %s (from lastChannel: %s)", channel, chatID, lastChannel)
|
||||
hs.logInfof("Resolved channel: %s, chatID: %s (from lastChannel: %s)", channel, chatID, lastChannel)
|
||||
|
||||
result := handler(prompt, channel, chatID)
|
||||
|
||||
if result == nil {
|
||||
hs.logInfo("Heartbeat handler returned nil result")
|
||||
hs.logInfof("Heartbeat handler returned nil result")
|
||||
return
|
||||
}
|
||||
|
||||
// Handle different result types
|
||||
if result.IsError {
|
||||
hs.logError("Heartbeat error: %s", result.ForLLM)
|
||||
hs.logErrorf("Heartbeat error: %s", result.ForLLM)
|
||||
return
|
||||
}
|
||||
|
||||
if result.Async {
|
||||
hs.logInfo("Async task started: %s", result.ForLLM)
|
||||
hs.logInfof("Async task started: %s", result.ForLLM)
|
||||
logger.InfoCF("heartbeat", "Async heartbeat task started",
|
||||
map[string]any{
|
||||
"message": result.ForLLM,
|
||||
@@ -201,7 +201,7 @@ func (hs *HeartbeatService) executeHeartbeat() {
|
||||
|
||||
// Check if silent
|
||||
if result.Silent {
|
||||
hs.logInfo("Heartbeat OK - silent")
|
||||
hs.logInfof("Heartbeat OK - silent")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ func (hs *HeartbeatService) executeHeartbeat() {
|
||||
hs.sendResponse(result.ForLLM)
|
||||
}
|
||||
|
||||
hs.logInfo("Heartbeat completed: %s", result.ForLLM)
|
||||
hs.logInfof("Heartbeat completed: %s", result.ForLLM)
|
||||
}
|
||||
|
||||
// buildPrompt builds the heartbeat prompt from HEARTBEAT.md
|
||||
@@ -225,7 +225,7 @@ func (hs *HeartbeatService) buildPrompt() string {
|
||||
hs.createDefaultHeartbeatTemplate()
|
||||
return ""
|
||||
}
|
||||
hs.logError("Error reading HEARTBEAT.md: %v", err)
|
||||
hs.logErrorf("Error reading HEARTBEAT.md: %v", err)
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -276,9 +276,9 @@ Add your heartbeat tasks below this line:
|
||||
`
|
||||
|
||||
if err := os.WriteFile(heartbeatPath, []byte(defaultContent), 0o644); err != nil {
|
||||
hs.logError("Failed to create default HEARTBEAT.md: %v", err)
|
||||
hs.logErrorf("Failed to create default HEARTBEAT.md: %v", err)
|
||||
} else {
|
||||
hs.logInfo("Created default HEARTBEAT.md template")
|
||||
hs.logInfof("Created default HEARTBEAT.md template")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,14 +289,14 @@ func (hs *HeartbeatService) sendResponse(response string) {
|
||||
hs.mu.RUnlock()
|
||||
|
||||
if msgBus == nil {
|
||||
hs.logInfo("No message bus configured, heartbeat result not sent")
|
||||
hs.logInfof("No message bus configured, heartbeat result not sent")
|
||||
return
|
||||
}
|
||||
|
||||
// Get last channel from state
|
||||
lastChannel := hs.state.GetLastChannel()
|
||||
if lastChannel == "" {
|
||||
hs.logInfo("No last channel recorded, heartbeat result not sent")
|
||||
hs.logInfof("No last channel recorded, heartbeat result not sent")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -313,7 +313,7 @@ func (hs *HeartbeatService) sendResponse(response string) {
|
||||
Content: response,
|
||||
})
|
||||
|
||||
hs.logInfo("Heartbeat result sent to %s", platform)
|
||||
hs.logInfof("Heartbeat result sent to %s", platform)
|
||||
}
|
||||
|
||||
// parseLastChannel parses the last channel string into platform and userID.
|
||||
@@ -326,7 +326,7 @@ func (hs *HeartbeatService) parseLastChannel(lastChannel string) (platform, user
|
||||
// Parse channel format: "platform:user_id" (e.g., "telegram:123456")
|
||||
parts := strings.SplitN(lastChannel, ":", 2)
|
||||
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
|
||||
hs.logError("Invalid last channel format: %s", lastChannel)
|
||||
hs.logErrorf("Invalid last channel format: %s", lastChannel)
|
||||
return "", ""
|
||||
}
|
||||
|
||||
@@ -334,25 +334,25 @@ func (hs *HeartbeatService) parseLastChannel(lastChannel string) (platform, user
|
||||
|
||||
// Skip internal channels
|
||||
if constants.IsInternalChannel(platform) {
|
||||
hs.logInfo("Skipping internal channel: %s", platform)
|
||||
hs.logInfof("Skipping internal channel: %s", platform)
|
||||
return "", ""
|
||||
}
|
||||
|
||||
return platform, userID
|
||||
}
|
||||
|
||||
// logInfo logs an informational message to the heartbeat log
|
||||
func (hs *HeartbeatService) logInfo(format string, args ...any) {
|
||||
hs.log("INFO", format, args...)
|
||||
// logInfof logs an informational message to the heartbeat log
|
||||
func (hs *HeartbeatService) logInfof(format string, args ...any) {
|
||||
hs.logf("INFO", format, args...)
|
||||
}
|
||||
|
||||
// logError logs an error message to the heartbeat log
|
||||
func (hs *HeartbeatService) logError(format string, args ...any) {
|
||||
hs.log("ERROR", format, args...)
|
||||
// logErrorf logs an error message to the heartbeat log
|
||||
func (hs *HeartbeatService) logErrorf(format string, args ...any) {
|
||||
hs.logf("ERROR", format, args...)
|
||||
}
|
||||
|
||||
// log writes a message to the heartbeat log file
|
||||
func (hs *HeartbeatService) log(level, format string, args ...any) {
|
||||
// logf writes a message to the heartbeat log file
|
||||
func (hs *HeartbeatService) logf(level, format string, args ...any) {
|
||||
logFile := filepath.Join(hs.workspace, "heartbeat.log")
|
||||
f, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
|
||||
if err != nil {
|
||||
|
||||
@@ -191,7 +191,7 @@ func TestLogPath(t *testing.T) {
|
||||
hs := NewHeartbeatService(tmpDir, 30, true)
|
||||
|
||||
// Write a log entry
|
||||
hs.log("INFO", "Test log entry")
|
||||
hs.logf("INFO", "Test log entry")
|
||||
|
||||
// Verify log file exists at workspace root
|
||||
expectedLogPath := filepath.Join(tmpDir, "heartbeat.log")
|
||||
|
||||
@@ -153,7 +153,7 @@ func formatComponent(component string) string {
|
||||
}
|
||||
|
||||
func formatFields(fields map[string]any) string {
|
||||
var parts []string
|
||||
parts := make([]string, 0, len(fields))
|
||||
for k, v := range fields {
|
||||
parts = append(parts, fmt.Sprintf("%s=%v", k, v))
|
||||
}
|
||||
|
||||
@@ -43,12 +43,18 @@ func TestReadCodexCliCredentials_Valid(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// readCodexCliCredentialsErr calls ReadCodexCliCredentials and returns only the
|
||||
// error, for tests that only need to assert on failure.
|
||||
func readCodexCliCredentialsErr() error {
|
||||
_, _, _, err := ReadCodexCliCredentials() //nolint:dogsled
|
||||
return err
|
||||
}
|
||||
|
||||
func TestReadCodexCliCredentials_MissingFile(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
t.Setenv("CODEX_HOME", tmpDir)
|
||||
|
||||
_, _, _, err := ReadCodexCliCredentials()
|
||||
if err == nil {
|
||||
if err := readCodexCliCredentialsErr(); err == nil {
|
||||
t.Fatal("expected error for missing auth.json")
|
||||
}
|
||||
}
|
||||
@@ -64,8 +70,7 @@ func TestReadCodexCliCredentials_EmptyToken(t *testing.T) {
|
||||
|
||||
t.Setenv("CODEX_HOME", tmpDir)
|
||||
|
||||
_, _, _, err := ReadCodexCliCredentials()
|
||||
if err == nil {
|
||||
if err := readCodexCliCredentialsErr(); err == nil {
|
||||
t.Fatal("expected error for empty access_token")
|
||||
}
|
||||
}
|
||||
@@ -80,8 +85,7 @@ func TestReadCodexCliCredentials_InvalidJSON(t *testing.T) {
|
||||
|
||||
t.Setenv("CODEX_HOME", tmpDir)
|
||||
|
||||
_, _, _, err := ReadCodexCliCredentials()
|
||||
if err == nil {
|
||||
if err := readCodexCliCredentialsErr(); err == nil {
|
||||
t.Fatal("expected error for invalid JSON")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,8 +106,8 @@ func (p *CodexProvider) Chat(
|
||||
if evt.Type == "response.completed" || evt.Type == "response.failed" || evt.Type == "response.incomplete" {
|
||||
evtResp := evt.Response
|
||||
if evtResp.ID != "" {
|
||||
copy := evtResp
|
||||
resp = ©
|
||||
evtRespCopy := evtResp
|
||||
resp = &evtRespCopy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@ func NewGitHubCopilotProvider(uri string, connectMode string, model string) (*Gi
|
||||
Hooks: &copilot.SessionHooks{},
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
client.Stop()
|
||||
return nil, fmt.Errorf("create session failed: %w", err)
|
||||
}
|
||||
@@ -101,7 +100,7 @@ func (p *GitHubCopilotProvider) Chat(
|
||||
return nil, fmt.Errorf("provider closed")
|
||||
}
|
||||
|
||||
resp, err := session.SendAndWait(ctx, copilot.MessageOptions{
|
||||
resp, _ := session.SendAndWait(ctx, copilot.MessageOptions{
|
||||
Prompt: string(fullcontent),
|
||||
})
|
||||
|
||||
|
||||
+1
-2
@@ -76,10 +76,9 @@ func NewExecTool(workingDir string, restrict bool) *ExecTool {
|
||||
func NewExecToolWithConfig(workingDir string, restrict bool, config *config.Config) *ExecTool {
|
||||
denyPatterns := make([]*regexp.Regexp, 0)
|
||||
|
||||
enableDenyPatterns := true
|
||||
if config != nil {
|
||||
execConfig := config.Tools.Exec
|
||||
enableDenyPatterns = execConfig.EnableDenyPatterns
|
||||
enableDenyPatterns := execConfig.EnableDenyPatterns
|
||||
if enableDenyPatterns {
|
||||
denyPatterns = append(denyPatterns, defaultDenyPatterns...)
|
||||
if len(execConfig.CustomDenyPatterns) > 0 {
|
||||
|
||||
@@ -132,12 +132,12 @@ After completing the task, provide a clear summary of what was done.`
|
||||
},
|
||||
}
|
||||
|
||||
// Check if context is already cancelled before starting
|
||||
// Check if context is already canceled before starting
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
sm.mu.Lock()
|
||||
task.Status = "cancelled"
|
||||
task.Result = "Task cancelled before execution"
|
||||
task.Status = "canceled"
|
||||
task.Result = "Task canceled before execution"
|
||||
sm.mu.Unlock()
|
||||
return
|
||||
default:
|
||||
@@ -185,10 +185,10 @@ After completing the task, provide a clear summary of what was done.`
|
||||
if err != nil {
|
||||
task.Status = "failed"
|
||||
task.Result = fmt.Sprintf("Error: %v", err)
|
||||
// Check if it was cancelled
|
||||
// Check if it was canceled
|
||||
if ctx.Err() != nil {
|
||||
task.Status = "cancelled"
|
||||
task.Result = "Task cancelled during execution"
|
||||
task.Status = "canceled"
|
||||
task.Result = "Task canceled during execution"
|
||||
}
|
||||
result = &ToolResult{
|
||||
ForLLM: task.Result,
|
||||
|
||||
Reference in New Issue
Block a user