Skip to content

Commit 4e0ca4c

Browse files
fix(reply): normalize Windows media paths for dedupe
1 parent b77b748 commit 4e0ca4c

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

src/auto-reply/reply/reply-payloads.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@ describe("filterMessagingToolMediaDuplicates", () => {
7777
});
7878
expect(result).toEqual([{ text: "hello", mediaUrl: undefined, mediaUrls: undefined }]);
7979
});
80+
81+
it("dedupes Windows drive-letter file URLs against local paths", () => {
82+
const result = filterMessagingToolMediaDuplicates({
83+
payloads: [{ text: "hello", mediaUrl: "file:///C:/tmp/photo one.jpg" }],
84+
sentMediaUrls: ["C:\\tmp\\photo one.jpg", "C:/tmp/photo one.jpg"],
85+
});
86+
expect(result).toEqual([{ text: "hello", mediaUrl: undefined, mediaUrls: undefined }]);
87+
});
8088
});
8189

8290
describe("shouldSuppressMessagingToolReplies", () => {

src/auto-reply/reply/reply-payloads.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import type { ReplyPayload } from "../types.js";
1010
import { extractReplyToTag } from "./reply-tags.js";
1111
import { createReplyToModeFilterForChannel } from "./reply-threading.js";
1212

13+
const WINDOWS_ABSOLUTE_PATH_RE = /^[a-zA-Z]:[\\/]/;
14+
1315
function resolveReplyThreadingForPayload(params: {
1416
payload: ReplyPayload;
1517
implicitReplyToId?: string;
@@ -112,12 +114,16 @@ export function filterMessagingToolMediaDuplicates(params: {
112114
return "";
113115
}
114116
if (!trimmed.toLowerCase().startsWith("file://")) {
115-
return trimmed;
117+
return WINDOWS_ABSOLUTE_PATH_RE.test(trimmed) ? trimmed.replaceAll("/", "\\") : trimmed;
116118
}
117119
try {
118120
const parsed = new URL(trimmed);
119121
if (parsed.protocol === "file:") {
120-
return decodeURIComponent(parsed.pathname || "");
122+
const decodedPath = decodeURIComponent(parsed.pathname || "");
123+
if (/^\/[a-zA-Z]:\//.test(decodedPath)) {
124+
return decodedPath.slice(1).replaceAll("/", "\\");
125+
}
126+
return decodedPath;
121127
}
122128
} catch {
123129
// Keep fallback below for non-URL-like inputs.

0 commit comments

Comments
 (0)