
























@@ -769,42 +769,59 @@ describe("createTypingSignaler", () => {
769769expect(typing.startTypingOnText).not.toHaveBeenCalled();
770770});
771771772-it("handles tool-start typing before and after active text mode", async () => {
772+it("suppresses tool-start typing in message mode until renderable text arrives", async () => {
773773const typing = createMockTypingController();
774774const signaler = createTypingSignaler({
775775 typing,
776776mode: "message",
777777isHeartbeat: false,
778778});
779779780+// Tool fires before any text — suppressed in message mode.
780781await signaler.signalToolStart();
782+expect(typing.startTypingLoop).not.toHaveBeenCalled();
783+expect(typing.refreshTypingTtl).not.toHaveBeenCalled();
781784782-expect(typing.startTypingLoop).toHaveBeenCalledTimes(1);
783-expect(typing.refreshTypingTtl).toHaveBeenCalledTimes(1);
784-expect(typing.startTypingOnText).not.toHaveBeenCalled();
785+// Renderable text arrives — typing starts via startTypingOnText.
786+await signaler.signalTextDelta("hello");
787+expect(typing.startTypingOnText).toHaveBeenCalledTimes(1);
788+789+// Typing now active; subsequent tool calls keep TTL alive.
785790(typing.isActive as ReturnType<typeof vi.fn>).mockReturnValue(true);
786-(typing.startTypingLoop as ReturnType<typeof vi.fn>).mockClear();
787791(typing.refreshTypingTtl as ReturnType<typeof vi.fn>).mockClear();
788792await signaler.signalToolStart();
789-790793expect(typing.refreshTypingTtl).toHaveBeenCalledTimes(1);
791794expect(typing.startTypingLoop).not.toHaveBeenCalled();
792795});
793796797+it("starts typing on tool-start for instant and thinking modes", async () => {
798+for (const mode of ["instant", "thinking"] as const) {
799+const typing = createMockTypingController();
800+const signaler = createTypingSignaler({ typing, mode, isHeartbeat: false });
801+802+await signaler.signalToolStart();
803+804+expect(typing.startTypingLoop).toHaveBeenCalledTimes(1);
805+expect(typing.refreshTypingTtl).toHaveBeenCalledTimes(1);
806+}
807+});
808+794809it("suppresses typing when disabled", async () => {
795-const typing = createMockTypingController();
796-const signaler = createTypingSignaler({
797- typing,
798-mode: "instant",
799-isHeartbeat: true,
800-});
810+const disabledCases = [
811+{ mode: "instant" as const, isHeartbeat: true },
812+{ mode: "never" as const, isHeartbeat: false },
813+];
814+for (const params of disabledCases) {
815+const typing = createMockTypingController();
816+const signaler = createTypingSignaler({ typing, ...params });
801817802-await signaler.signalRunStart();
803-await signaler.signalTextDelta("hi");
804-await signaler.signalReasoningDelta();
818+ await signaler.signalRunStart();
819+ await signaler.signalTextDelta("hi");
820+ await signaler.signalReasoningDelta();
805821806-expect(typing.startTypingLoop).not.toHaveBeenCalled();
807-expect(typing.startTypingOnText).not.toHaveBeenCalled();
822+expect(typing.startTypingLoop, `mode=${params.mode}`).not.toHaveBeenCalled();
823+expect(typing.startTypingOnText, `mode=${params.mode}`).not.toHaveBeenCalled();
824+}
808825});
809826});
810827此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。