Skip to content

Commit 52a6b67

Browse files
committed
fix(reply): require trusted route thread sources
1 parent 5af3d51 commit 52a6b67

2 files changed

Lines changed: 37 additions & 1 deletion

File tree

src/auto-reply/reply/effective-reply-route.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,40 @@ describe("resolveEffectiveReplyRoute", () => {
163163
});
164164
});
165165

166+
it("drops inherited thread ids from unmarked normalized route metadata", () => {
167+
expect(
168+
resolveEffectiveReplyRoute({
169+
ctx: ctx({
170+
Provider: "webchat",
171+
Surface: "webchat",
172+
InputProvenance: {
173+
kind: "inter_session",
174+
sourceTool: "sessions_send",
175+
},
176+
}),
177+
entry: entry({
178+
route: {
179+
channel: "feishu",
180+
accountId: "work",
181+
target: { to: "user:ou_123" },
182+
thread: { id: "thread:stale" },
183+
},
184+
deliveryContext: {
185+
channel: "feishu",
186+
to: "user:ou_123",
187+
accountId: "work",
188+
threadId: "thread:stale",
189+
},
190+
}),
191+
}),
192+
).toEqual({
193+
channel: "feishu",
194+
to: "user:ou_123",
195+
accountId: "work",
196+
inheritedExternalRoute: true,
197+
});
198+
});
199+
166200
it("keeps plugin-owned external routes for runtime routability checks", () => {
167201
expect(
168202
resolveEffectiveReplyRoute({

src/auto-reply/reply/effective-reply-route.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ function resolveTrustedInheritedThreadId(
4343
const routeThread = entry?.route?.thread;
4444
if (
4545
routeThread?.id != null &&
46-
routeThread.source !== "session" &&
46+
(routeThread.source === "explicit" ||
47+
routeThread.source === "target" ||
48+
routeThread.source === "turn") &&
4749
stringifyRouteThreadId(routeThread.id) === stringifyRouteThreadId(deliveryThreadId)
4850
) {
4951
return deliveryThreadId;

0 commit comments

Comments
 (0)