47 lines
2.5 KiB
TypeScript
47 lines
2.5 KiB
TypeScript
import { z } from "zod";
|
||
import type { ReplyTheme } from "./agent-reply.ts";
|
||
|
||
export const consultationReplyMetadataSchema = z.object({
|
||
title: z.string().trim().min(1).max(64),
|
||
suggestions: z.tuple([
|
||
z.string().trim().min(1).max(80),
|
||
z.string().trim().min(1).max(80),
|
||
z.string().trim().min(1).max(80),
|
||
]),
|
||
}).strict();
|
||
|
||
export type ConsultationReplyMetadata = z.infer<typeof consultationReplyMetadataSchema>;
|
||
|
||
const fallbackSuggestions: Record<ReplyTheme, readonly [string, string, string]> = {
|
||
career: ["我更适合怎样的职业路径?", "未来一年事业上要避开什么?", "我该如何发挥自己的优势?"],
|
||
marriage: ["我在关系里容易重复什么模式?", "怎样的伴侣更适合我?", "未来一年关系上要注意什么?"],
|
||
wealth: ["我的财富增长方式是什么?", "接下来财务上要避开什么?", "我该如何稳定提升收入?"],
|
||
health: ["近期压力主要来自哪里?", "怎样安排休息与恢复?", "哪些信号值得持续观察?"],
|
||
education: ["我更适合怎样的学习路径?", "现在该补哪项能力?", "什么阶段适合考试或进修?"],
|
||
migration: ["迁居方向该优先考虑什么?", "置业与流动之间如何取舍?", "海外发展要注意哪些条件?"],
|
||
family: ["家庭关系中该建立什么边界?", "我承担的责任是否失衡?", "接下来适合如何沟通?"],
|
||
annual: ["未来一年最重要的主题是什么?", "哪些阶段适合主动推进?", "哪些阶段更适合调整?"],
|
||
timing: ["接下来最值得把握的阶段是什么?", "哪些时期更适合主动行动?", "我现在应该优先准备什么?"],
|
||
general: ["未来一年,事业和收入该关注什么?", "我的关系模式是什么?", "未来哪些阶段值得把握?"],
|
||
};
|
||
|
||
function safeQuestionTitle(question: string) {
|
||
const normalized = question
|
||
.replace(/\s+/g, " ")
|
||
.trim()
|
||
.replace(/[??!!。.,,;;::]+$/u, "")
|
||
.replace(/[\p{P}\p{S}]/gu, "")
|
||
.trim();
|
||
if (!normalized) return "一般占星咨询";
|
||
const characters = Array.from(normalized);
|
||
if (characters.length >= 6) return characters.slice(0, 14).join("");
|
||
return `${characters.join("")}主题咨询`.slice(0, 14);
|
||
}
|
||
|
||
export function createConsultationReplyMetadata(input: { theme: ReplyTheme; question: string }): ConsultationReplyMetadata {
|
||
return consultationReplyMetadataSchema.parse({
|
||
title: safeQuestionTitle(input.question),
|
||
suggestions: [...fallbackSuggestions[input.theme]],
|
||
});
|
||
}
|