feat(chat): add support action cards and live entitlements

This commit is contained in:
Codex
2026-07-24 17:59:57 +08:00
parent d746d04503
commit ff2759cf0f
52 changed files with 1151 additions and 40 deletions
@@ -96,6 +96,33 @@ describe("sendResponseToUiMessage", () => {
});
});
it("prefers the new chat action over the legacy commercial action", () => {
const message = sendResponseToUiMessage(
makeResponse({
chatAction: {
actionId: "chat-action-1",
kind: "support",
type: "openFeedback",
copy: "Share the screenshot here.",
ctaLabel: "Open Feedback",
ruleId: null,
orderId: null,
},
commercialAction: {
actionId: "legacy-action-1",
type: "giftOffer",
copy: "View gifts.",
ctaLabel: "View gifts",
target: "giftCatalog",
ruleId: "legacy-rule",
},
}),
);
expect(message.chatAction?.actionId).toBe("chat-action-1");
expect(message.commercialAction).toBeUndefined();
});
it("maps locked voice messages without treating them as private text", () => {
const message = sendResponseToUiMessage(
makeResponse({
+5 -3
View File
@@ -74,9 +74,11 @@ export function sendResponseToUiMessage(response: ChatSendResponse): UiMessage {
...(response.audioUrl && !response.lockDetail.locked
? { audioUrl: response.audioUrl }
: {}),
...(response.commercialAction
? { commercialAction: response.commercialAction }
: {}),
...(response.chatAction
? { chatAction: response.chatAction }
: response.commercialAction
? { commercialAction: response.commercialAction }
: {}),
...deriveUiLockFields(response.lockDetail, response.image.url),
};
}
+2 -1
View File
@@ -1,5 +1,5 @@
import { z } from "zod";
import { CommercialActionSchema } from "@/data/schemas/chat";
import { ChatActionSchema, CommercialActionSchema } from "@/data/schemas/chat";
export const UiMessageSchema = z.object({
displayId: z.string().min(1),
@@ -18,6 +18,7 @@ export const UiMessageSchema = z.object({
lockedPrivate: z.boolean().nullable().optional(),
privateMessageHint: z.string().nullable().optional(),
commercialAction: CommercialActionSchema.nullable().optional(),
chatAction: ChatActionSchema.nullable().optional(),
});
export type UiMessage = z.infer<typeof UiMessageSchema>;