diff --git a/pkg/channels/manager_test.go b/pkg/channels/manager_test.go index 7d9ea700e..baedcbdcf 100644 --- a/pkg/channels/manager_test.go +++ b/pkg/channels/manager_test.go @@ -52,7 +52,6 @@ func TestSendMessageWithID_FallsBackToBusWithoutError(t *testing.T) { ChatID: "1", Content: "hello", }) - if err != nil { t.Fatalf("expected nil error for async fallback, got %v", err) } diff --git a/pkg/channels/telegram/telegram.go b/pkg/channels/telegram/telegram.go index 73f0cd2db..c4ebbfe18 100644 --- a/pkg/channels/telegram/telegram.go +++ b/pkg/channels/telegram/telegram.go @@ -201,7 +201,11 @@ func (c *TelegramChannel) SendMessageWithID(ctx context.Context, msg bus.Outboun // sendHTMLChunk sends a single HTML message, falling back to the original // markdown as plain text on parse failure so users never see raw HTML tags. -func (c *TelegramChannel) sendHTMLChunk(ctx context.Context, chatID int64, htmlContent, mdFallback string) (int, error) { +func (c *TelegramChannel) sendHTMLChunk( + ctx context.Context, + chatID int64, + htmlContent, mdFallback string, +) (int, error) { tgMsg := tu.Message(tu.ID(chatID), htmlContent) tgMsg.ParseMode = telego.ModeHTML @@ -647,7 +651,12 @@ func parseTelegramMessageIDs(messageID string) ([]int, error) { return ids, nil } -func (c *TelegramChannel) editHTMLChunk(ctx context.Context, chatID int64, messageID int, htmlContent, mdFallback string) error { +func (c *TelegramChannel) editHTMLChunk( + ctx context.Context, + chatID int64, + messageID int, + htmlContent, mdFallback string, +) error { editMsg := tu.EditMessageText(tu.ID(chatID), messageID, htmlContent) editMsg.ParseMode = telego.ModeHTML diff --git a/pkg/channels/telegram/telegram_test.go b/pkg/channels/telegram/telegram_test.go index ffb9bbad0..7ae16e28a 100644 --- a/pkg/channels/telegram/telegram_test.go +++ b/pkg/channels/telegram/telegram_test.go @@ -125,7 +125,10 @@ func TestSendMessageWithID_ShortMessage_SingleCall(t *testing.T) { } ch := newTestChannel(t, caller) - msgID, err := ch.SendMessageWithID(context.Background(), bus.OutboundMessage{ChatID: "12345", Content: "Hello, world!"}) + msgID, err := ch.SendMessageWithID( + context.Background(), + bus.OutboundMessage{ChatID: "12345", Content: "Hello, world!"}, + ) assert.NoError(t, err) assert.Equal(t, "1", msgID) @@ -162,7 +165,10 @@ func TestSendMessageWithID_HTMLFallback_PerChunk(t *testing.T) { } ch := newTestChannel(t, caller) - msgID, err := ch.SendMessageWithID(context.Background(), bus.OutboundMessage{ChatID: "12345", Content: "Hello **world**"}) + msgID, err := ch.SendMessageWithID( + context.Background(), + bus.OutboundMessage{ChatID: "12345", Content: "Hello **world**"}, + ) assert.NoError(t, err) assert.Equal(t, "1", msgID) @@ -215,10 +221,18 @@ func TestSendMessageWithID_MarkdownShortButHTMLLong_MultipleCalls(t *testing.T) markdownContent := strings.Repeat("**a** ", 600) assert.LessOrEqual(t, len([]rune(markdownContent)), 4000) - msgID, err := ch.SendMessageWithID(context.Background(), bus.OutboundMessage{ChatID: "12345", Content: markdownContent}) + msgID, err := ch.SendMessageWithID( + context.Background(), + bus.OutboundMessage{ChatID: "12345", Content: markdownContent}, + ) assert.NoError(t, err) - assert.Greater(t, len(caller.calls), 1, "markdown-short but HTML-long message should be split into multiple SendMessage calls") + assert.Greater( + t, + len(caller.calls), + 1, + "markdown-short but HTML-long message should be split into multiple SendMessage calls", + ) assert.Equal(t, "1,2", msgID) } @@ -264,7 +278,10 @@ func TestSendMessageWithID_InvalidChatID(t *testing.T) { } ch := newTestChannel(t, caller) - msgID, err := ch.SendMessageWithID(context.Background(), bus.OutboundMessage{ChatID: "not-a-number", Content: "Hello"}) + msgID, err := ch.SendMessageWithID( + context.Background(), + bus.OutboundMessage{ChatID: "not-a-number", Content: "Hello"}, + ) assert.Error(t, err) assert.Empty(t, msgID) diff --git a/pkg/config/config.go b/pkg/config/config.go index 46f0e88b4..ff42df1e7 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -702,8 +702,8 @@ type ToolsConfig struct { } type TaskToolConfig struct { - ToolConfig `envPrefix:"PICOCLAW_TOOLS_TASK_TOOL_"` - Icons TaskToolIconsConfig `json:"icons"` + ToolConfig ` envPrefix:"PICOCLAW_TOOLS_TASK_TOOL_"` + Icons TaskToolIconsConfig ` json:"icons"` } type TaskToolIconsConfig struct { diff --git a/pkg/tools/tasktool.go b/pkg/tools/tasktool.go index 738007d31..ba733a1ff 100644 --- a/pkg/tools/tasktool.go +++ b/pkg/tools/tasktool.go @@ -19,7 +19,6 @@ type TaskTool struct { } func NewTaskTool(taskManager *session.TaskManager, icons config.TaskToolIconsConfig) *TaskTool { - return &TaskTool{ taskManager: taskManager, icons: icons, @@ -130,15 +129,22 @@ func (t *TaskTool) Execute(ctx context.Context, args map[string]any) *ToolResult } } -func (t *TaskTool) handleCreatePlan(ctx context.Context, sessionKey, channel, chatID string, args map[string]any) *ToolResult { - tasksRaw, ok := args["tasks"].([]interface{}) +func (t *TaskTool) handleCreatePlan( + ctx context.Context, + sessionKey, channel, chatID string, + args map[string]any, +) *ToolResult { + tasksRaw, ok := args["tasks"].([]any) if !ok || len(tasksRaw) == 0 { - return &ToolResult{ForLLM: "tasktool: tasks array is required and cannot be empty for 'create_plan'", IsError: true} + return &ToolResult{ + ForLLM: "tasktool: tasks array is required and cannot be empty for 'create_plan'", + IsError: true, + } } var parsedTasks []session.Task for i, raw := range tasksRaw { - taskMap, ok := raw.(map[string]interface{}) + taskMap, ok := raw.(map[string]any) if !ok { return &ToolResult{ForLLM: fmt.Sprintf("tasktool: invalid task at index %d", i), IsError: true} } @@ -150,7 +156,10 @@ func (t *TaskTool) handleCreatePlan(ctx context.Context, sessionKey, channel, ch desc, ok := taskMap["description"].(string) if !ok || desc == "" { - return &ToolResult{ForLLM: fmt.Sprintf("tasktool: missing description for task at index %d", i), IsError: true} + return &ToolResult{ + ForLLM: fmt.Sprintf("tasktool: missing description for task at index %d", i), + IsError: true, + } } parsedTasks = append(parsedTasks, session.Task{ @@ -236,7 +245,11 @@ func (t *TaskTool) handleResendPlan(ctx context.Context, sessionKey, channel, ch return t.newPlanResult(summary, content, delivered, deliveryErr) } -func (t *TaskTool) handleUpdateTask(ctx context.Context, sessionKey, channel, chatID string, args map[string]any) *ToolResult { +func (t *TaskTool) handleUpdateTask( + ctx context.Context, + sessionKey, channel, chatID string, + args map[string]any, +) *ToolResult { taskID, _ := args["task_id"].(string) if taskID == "" { return &ToolResult{ForLLM: "tasktool: task_id is required for 'update_task'", IsError: true} @@ -331,11 +344,20 @@ func (t *TaskTool) newPlanResult(summary, content string, delivered bool, delive } } - forLLM := summary + var forLLM string if deliveryErr != nil { - forLLM = fmt.Sprintf("%s\nAutomatic delivery failed (%v). Respond to the user with the following plan content:\n\n%s", summary, deliveryErr, content) + forLLM = fmt.Sprintf( + "%s\nAutomatic delivery failed (%v). Respond to the user with the following plan content:\n\n%s", + summary, + deliveryErr, + content, + ) } else { - forLLM = fmt.Sprintf("%s\nAutomatic delivery is unavailable in this context. Respond to the user with the following plan content:\n\n%s", summary, content) + forLLM = fmt.Sprintf( + "%s\nAutomatic delivery is unavailable in this context. Respond to the user with the following plan content:\n\n%s", + summary, + content, + ) } return &ToolResult{