From 45a80185f629864cb6a029ea7642f416a45f1b97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=95=BF=E7=9C=9F?= Date: Thu, 13 Aug 2026 14:42:26 +0800 Subject: [PATCH] fix(chat): pass explicit list-all times through --- .changes/973-chat-message-time-defaults.md | 2 +- internal/helpers/chat.go | 16 +---- .../helpers/chat_message_pagination_test.go | 59 ++++++++++--------- 3 files changed, 36 insertions(+), 41 deletions(-) diff --git a/.changes/973-chat-message-time-defaults.md b/.changes/973-chat-message-time-defaults.md index 1a6e5496..fbe6ba2c 100644 --- a/.changes/973-chat-message-time-defaults.md +++ b/.changes/973-chat-message-time-defaults.md @@ -2,4 +2,4 @@ category: Fixed --- -- **Chat message time defaults** (#973) — validates `chat message list-all` time ranges locally and defaults omitted message-query time bounds without creating reversed windows. +- **Chat message time defaults** (#973) — defaults omitted message-query time bounds without creating reversed windows. diff --git a/internal/helpers/chat.go b/internal/helpers/chat.go index 34a45d0f..c1c7e672 100644 --- a/internal/helpers/chat.go +++ b/internal/helpers/chat.go @@ -471,20 +471,10 @@ func chatMessageListAllArgs(cmd *cobra.Command) (map[string]any, error) { if err != nil { return nil, err } - startMs, err := parseISOTimeToMillis("start", startRaw) - if err != nil { - return nil, err - } - endMs, _ := parseISOTimeToMillis("end", endRaw) - if err := validateTimeRange(startMs, endMs); err != nil { - return nil, err - } - startTime := formatChatMessageListAllTime(startMs) - endTime := formatChatMessageListAllTime(endMs) cursor, _ := cmd.Flags().GetString("cursor") return map[string]any{ - "startTime": startTime, - "endTime": endTime, + "startTime": startRaw, + "endTime": endRaw, "limit": chatIntFlagOrFallback(cmd, "limit", "size"), "cursor": cursor, }, nil @@ -608,7 +598,7 @@ func defaultChatMessageTimeRange(cmd *cobra.Command, lookback time.Duration) (st anchor := time.Now() if endRaw == "" { endRaw = anchor.Format(time.RFC3339) - } else { + } else if startRaw == "" { endMs, err := parseISOTimeToMillis("end", endRaw) if err != nil { return "", "", err diff --git a/internal/helpers/chat_message_pagination_test.go b/internal/helpers/chat_message_pagination_test.go index 61ad4c2f..f373e130 100644 --- a/internal/helpers/chat_message_pagination_test.go +++ b/internal/helpers/chat_message_pagination_test.go @@ -83,12 +83,7 @@ func TestChatMessagePaginationDefaultSinglePageUnchanged(t *testing.T) { args: []string{"message", "list-all", "--start", "2026-08-01 00:00:00", "--end", "2026-08-02 00:00:00"}, server: "", tool: "search_messages_by_time_range", - want: map[string]any{ - "startTime": formatChatMessageListAllTime(1785513600000), - "endTime": formatChatMessageListAllTime(1785600000000), - "limit": 50, - "cursor": "0", - }, + want: map[string]any{"startTime": "2026-08-01 00:00:00", "endTime": "2026-08-02 00:00:00", "limit": 50, "cursor": "0"}, }, { name: "list-by-sender", @@ -281,8 +276,8 @@ func TestChatMessagePaginationDefaultsStartFromExplicitEnd(t *testing.T) { t.Fatalf("startTime = %d, want %d", startMs, wantStartMs) } if tt.wantTool == "search_messages_by_time_range" { - assertStringArg(t, got.args["startTime"], formatChatMessageListAllTime(wantStartMs)) - assertStringArg(t, got.args["endTime"], formatChatMessageListAllTime(endMs)) + assertStringArg(t, got.args["startTime"], time.UnixMilli(wantStartMs).Format(time.RFC3339)) + assertStringArg(t, got.args["endTime"], endRaw) } }) } @@ -348,28 +343,31 @@ func TestChatMessagePaginationDefaultsEndFromNowWhenOnlyStartProvided(t *testing t.Fatalf("endTime = %d, want between %d and %d", endMs, wantEndMin, wantEndMax) } if tt.wantTool == "search_messages_by_time_range" { - assertStringArg(t, got.args["startTime"], formatChatMessageListAllTime(startMs)) + assertStringArg(t, got.args["startTime"], startRaw) parseChatMessageListAllTimeArg(t, got.args["endTime"]) } }) } } -func TestChatMessageListAllRejectsInvalidTimeRanges(t *testing.T) { +func TestChatMessageListAllPassesExplicitTimeBoundsThrough(t *testing.T) { tests := []struct { - name string - args []string - wantErr string + name string + args []string + wantStart string + wantEnd string }{ { - name: "invalid start", - args: []string{"message", "list-all", "--start", "not-a-time", "--end", "2020-01-01T00:00:00+08:00"}, - wantErr: "cannot parse time for --start", + name: "invalid start", + args: []string{"message", "list-all", "--start", "not-a-time", "--end", "2020-01-01T00:00:00+08:00"}, + wantStart: "not-a-time", + wantEnd: "2020-01-01T00:00:00+08:00", }, { - name: "end before start", - args: []string{"message", "list-all", "--start", "2021-01-01T00:00:00+08:00", "--end", "2020-01-01T00:00:00+08:00"}, - wantErr: "--end must be after --start", + name: "end before start", + args: []string{"message", "list-all", "--start", "2021-01-01T00:00:00+08:00", "--end", "2020-01-01T00:00:00+08:00"}, + wantStart: "2021-01-01T00:00:00+08:00", + wantEnd: "2020-01-01T00:00:00+08:00", }, } @@ -377,15 +375,18 @@ func TestChatMessageListAllRejectsInvalidTimeRanges(t *testing.T) { t.Run(tt.name, func(t *testing.T) { caller := &chatMessagePaginationCaller{} _, err := executeChatMessagePaginationCommand(t, caller, tt.args...) - if err == nil { - t.Fatal("command succeeded, want validation error") + if err != nil { + t.Fatal(err) } - if !strings.Contains(err.Error(), tt.wantErr) { - t.Fatalf("error = %v, want containing %q", err, tt.wantErr) + if len(caller.calls) != 1 { + t.Fatalf("calls = %#v, want one MCP call", caller.calls) } - if len(caller.calls) != 0 { - t.Fatalf("calls = %#v, want no MCP call", caller.calls) + got := caller.calls[0] + if got.tool != "search_messages_by_time_range" { + t.Fatalf("tool = %q, want search_messages_by_time_range", got.tool) } + assertStringArg(t, got.args["startTime"], tt.wantStart) + assertStringArg(t, got.args["endTime"], tt.wantEnd) }) } } @@ -423,10 +424,14 @@ func parseChatMessageListAllTimeArg(t *testing.T, value any) time.Time { t.Helper() raw, ok := value.(string) if !ok { - t.Fatalf("time arg = %#v, want yyyy-MM-dd HH:mm:ss string", value) + t.Fatalf("time arg = %#v, want time string", value) } if strings.Contains(raw, "T") { - t.Fatalf("time arg = %q, want yyyy-MM-dd HH:mm:ss without RFC3339 separator", raw) + parsedMs, err := parseISOTimeToMillis("time", raw) + if err != nil { + t.Fatalf("time arg = %q, parse err = %v", raw, err) + } + return time.UnixMilli(parsedMs) } parsed, err := time.ParseInLocation("2006-01-02 15:04:05", raw, time.Local) if err != nil {