























@@ -52,6 +52,27 @@ describe("normalizeReplyPayloadsForDelivery", () => {
5252]);
5353});
545455+it("strips unsupported citation control markers from reply payload text", () => {
56+const payloads: ReplyPayload[] = [{ text: "v2026.5.20 release note citeturn2view0" }];
57+58+expect(normalizeReplyPayloadsForDelivery(payloads)).toMatchObject([
59+{ text: "v2026.5.20 release note" },
60+]);
61+expect(resolveMirrorProjection(payloads).text).toBe("v2026.5.20 release note");
62+expect(normalizeOutboundPayloadsForJson(payloads)).toMatchObject([
63+{ text: "v2026.5.20 release note" },
64+]);
65+});
66+67+it("suppresses silent replies after removing citation control markers", () => {
68+expect(
69+normalizeReplyPayloadsForDelivery([
70+{ text: "NO_REPLY citeturn2view0" },
71+{ text: '{"action":"NO_REPLY"} citeturn2view0' },
72+]),
73+).toStrictEqual([]);
74+});
75+5576it("drops silent payloads without media and suppresses reasoning payloads", () => {
5677expect(
5778normalizeReplyPayloadsForDelivery([
@@ -602,6 +623,14 @@ describe("summarizeOutboundPayloadForTransport", () => {
602623expect(summary.hookContent).toBeUndefined();
603624});
604625626+it("strips unsupported citation control markers from transport text", () => {
627+const summary = summarizeOutboundPayloadForTransport({
628+text: "v2026.5.20 release note citeturn2view0",
629+});
630+631+expect(summary.text).toBe("v2026.5.20 release note");
632+});
633+605634it("surfaces spokenText only as hook content for audio-only payloads", () => {
606635const summary = summarizeOutboundPayloadForTransport({
607636mediaUrl: "/tmp/reply.opus",
@@ -615,6 +644,17 @@ describe("summarizeOutboundPayloadForTransport", () => {
615644expect(summary.audioAsVoice).toBe(true);
616645});
617646647+it("strips unsupported citation control markers from hook-only spoken text", () => {
648+const summary = summarizeOutboundPayloadForTransport({
649+mediaUrl: "/tmp/reply.opus",
650+audioAsVoice: true,
651+spokenText: "Hi Ivy citeturn2view0",
652+});
653+654+expect(summary.text).toBe("");
655+expect(summary.hookContent).toBe("Hi Ivy");
656+});
657+618658it("ignores blank spokenText", () => {
619659const summary = summarizeOutboundPayloadForTransport({
620660mediaUrl: "/tmp/reply.opus",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。