
































@@ -984,6 +984,105 @@ describe("thread binding lifecycle", () => {
984984expect(usedTokenNew).toBe(true);
985985});
986986987+it("normalizes prefixed parentConversationId before creating child thread bindings", async () => {
988+createThreadBindingManager({
989+accountId: "default",
990+persist: false,
991+enableSweeper: false,
992+idleTimeoutMs: 24 * 60 * 60 * 1000,
993+maxAgeMs: 0,
994+});
995+996+hoisted.restGet.mockClear();
997+hoisted.createThreadDiscord.mockClear();
998+hoisted.createThreadDiscord.mockResolvedValueOnce({ id: "thread-created-parent-normalized" });
999+1000+const bound = await getSessionBindingService().bind({
1001+targetSessionKey: "agent:codex:acp:test-parent-normalized",
1002+targetKind: "session",
1003+conversation: {
1004+channel: "discord",
1005+accountId: "default",
1006+conversationId: "channel:1491611525914558668",
1007+parentConversationId: "channel:1491611525914558667",
1008+},
1009+placement: "child",
1010+metadata: {
1011+agentId: "codex",
1012+label: "Codex ACP bind test",
1013+threadName: "Codex ACP bind test",
1014+},
1015+});
1016+1017+expect(bound).toMatchObject({
1018+conversation: {
1019+channel: "discord",
1020+accountId: "default",
1021+conversationId: "thread-created-parent-normalized",
1022+},
1023+});
1024+expect(hoisted.createThreadDiscord).toHaveBeenCalledWith(
1025+"1491611525914558667",
1026+expect.objectContaining({ autoArchiveMinutes: 60 }),
1027+expect.objectContaining({ accountId: "default" }),
1028+);
1029+expect(hoisted.restGet).not.toHaveBeenCalled();
1030+});
1031+1032+it("preserves prefixed current channel conversation ids as binding keys", async () => {
1033+createThreadBindingManager({
1034+accountId: "default",
1035+persist: false,
1036+enableSweeper: false,
1037+idleTimeoutMs: 24 * 60 * 60 * 1000,
1038+maxAgeMs: 0,
1039+});
1040+1041+hoisted.restGet.mockClear();
1042+hoisted.restPost.mockClear();
1043+1044+const service = getSessionBindingService();
1045+const bound = await service.bind({
1046+targetSessionKey: "agent:codex:acp:current-channel",
1047+targetKind: "session",
1048+conversation: {
1049+channel: "discord",
1050+accountId: "default",
1051+conversationId: "channel:1491611525914558667",
1052+},
1053+placement: "current",
1054+metadata: {
1055+agentId: "codex",
1056+},
1057+});
1058+1059+expect(bound).toMatchObject({
1060+conversation: {
1061+channel: "discord",
1062+accountId: "default",
1063+conversationId: "channel:1491611525914558667",
1064+},
1065+});
1066+expect(
1067+service.resolveByConversation({
1068+channel: "discord",
1069+accountId: "default",
1070+conversationId: "channel:1491611525914558667",
1071+}),
1072+).toMatchObject({
1073+targetSessionKey: "agent:codex:acp:current-channel",
1074+});
1075+expect(
1076+service.resolveByConversation({
1077+channel: "discord",
1078+accountId: "default",
1079+conversationId: "1491611525914558667",
1080+}),
1081+).toBeNull();
1082+expect(hoisted.restGet).not.toHaveBeenCalled();
1083+expect(hoisted.restPost).not.toHaveBeenCalled();
1084+});
1085+9871086it("binds current Discord DMs as direct conversation bindings", async () => {
9881087createThreadBindingManager({
9891088accountId: "default",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。