





















@@ -3050,6 +3050,88 @@ describe("dispatchTelegramMessage draft streaming", () => {
30503050expect(deliveredTexts).toContain("fresh request answer");
30513051});
305230523053+it("keeps newer DM requests from aborting active same-session dispatch", async () => {
3054+let firstStarted: (() => void) | undefined;
3055+const firstStartGate = new Promise<void>((resolve) => {
3056+firstStarted = resolve;
3057+});
3058+let releaseFirst: (() => void) | undefined;
3059+const firstGate = new Promise<void>((resolve) => {
3060+releaseFirst = resolve;
3061+});
3062+let secondStarted: (() => void) | undefined;
3063+const secondStartGate = new Promise<void>((resolve) => {
3064+secondStarted = resolve;
3065+});
3066+let firstAbortSignal: AbortSignal | undefined;
3067+dispatchReplyWithBufferedBlockDispatcher
3068+.mockImplementationOnce(async ({ dispatcherOptions, replyOptions }) => {
3069+firstAbortSignal = replyOptions?.abortSignal;
3070+firstStarted?.();
3071+await firstGate;
3072+await dispatcherOptions.deliver({ text: "earlier DM answer" }, { kind: "final" });
3073+return {
3074+queuedFinal: true,
3075+counts: { block: 0, final: 1, tool: 0 },
3076+};
3077+})
3078+.mockImplementationOnce(async ({ dispatcherOptions }) => {
3079+secondStarted?.();
3080+await dispatcherOptions.deliver({ text: "fresh DM answer" }, { kind: "final" });
3081+return {
3082+queuedFinal: true,
3083+counts: { block: 0, final: 1, tool: 0 },
3084+};
3085+});
3086+deliverReplies.mockResolvedValue({ delivered: true });
3087+3088+const createDirectContext = (messageId: number, body: string) =>
3089+createContext({
3090+ctxPayload: {
3091+SessionKey: "agent:main:main",
3092+ChatType: "direct",
3093+MessageSid: String(messageId),
3094+RawBody: body,
3095+BodyForAgent: body,
3096+CommandBody: body,
3097+CommandAuthorized: true,
3098+} as unknown as TelegramMessageContext["ctxPayload"],
3099+msg: {
3100+chat: { id: 123, type: "private" },
3101+message_id: messageId,
3102+} as unknown as TelegramMessageContext["msg"],
3103+chatId: 123,
3104+isGroup: false,
3105+historyKey: "telegram:123",
3106+historyLimit: 10,
3107+groupHistories: new Map(),
3108+threadSpec: { id: undefined, scope: "none" },
3109+});
3110+3111+const firstPromise = dispatchWithContext({
3112+context: createDirectContext(99, "first request"),
3113+streamMode: "off",
3114+});
3115+await firstStartGate;
3116+const secondPromise = dispatchWithContext({
3117+context: createDirectContext(100, "second request"),
3118+streamMode: "off",
3119+});
3120+await secondStartGate;
3121+3122+expect(firstAbortSignal?.aborted).toBe(false);
3123+releaseFirst?.();
3124+await Promise.all([firstPromise, secondPromise]);
3125+3126+const deliveredTexts = deliverReplies.mock.calls.flatMap((call) =>
3127+((call[0] as { replies?: Array<{ text?: string }> }).replies ?? []).map(
3128+(reply) => reply.text,
3129+),
3130+);
3131+expect(deliveredTexts).toContain("fresh DM answer");
3132+expect(deliveredTexts).toContain("earlier DM answer");
3133+});
3134+30533135it("keeps /btw side questions from aborting an active same-session dispatch", async () => {
30543136const historyKey = "telegram:group:-100123";
30553137const groupHistories = new Map([[historyKey, []]]);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。