haixunMaster/lib/ai/optimize-post.ts

75 lines
2.5 KiB
TypeScript
Raw Normal View History

2026-06-21 12:50:31 +00:00
import { z } from "zod";
import type { ProviderApiKeys } from "./keys";
import { generateStructuredObject } from "./generate-structured";
import { getModel } from "./provider";
import { HASHTAG_WRITING_RULES } from "./hashtag-rules";
import { buildSystemPrompt } from "./prompts";
import { THREADS_MAX_CHARS } from "@/lib/utils";
export type OptimizeMode = "polish" | "hook" | "shorter" | "engaging" | "custom";
const MODE_INSTRUCTIONS: Record<Exclude<OptimizeMode, "custom">, string> = {
polish: "整體潤飾:改善語氣流暢度、可讀性與說服力,保留核心觀點。",
hook: "強化開頭 hook讓前 12 句更有吸引力,讓人想停下來看。",
shorter: "精簡篇幅:刪除贅字,保留重點,盡量壓到更短但不失完整。",
engaging: "提升互動感:加入引發留言的問句、觀點或行動呼籲,但不過度推銷。",
};
const optimizeSchema = z.object({
text: z.string().max(THREADS_MAX_CHARS),
summary: z.string(),
});
export interface OptimizeInput {
text: string;
mode?: OptimizeMode;
instruction?: string | null;
persona?: string | null;
angle?: string | null;
aiProvider: string;
aiModel: string;
apiKeys?: ProviderApiKeys;
}
export async function optimizePost(input: OptimizeInput) {
const mode = input.mode ?? "polish";
const modeInstruction =
mode === "custom"
? input.instruction?.trim() || "依照使用者指示優化貼文。"
: MODE_INSTRUCTIONS[mode];
const model = getModel(input.aiProvider, input.aiModel, input.apiKeys ?? {});
const object = await generateStructuredObject({
model,
provider: input.aiProvider,
modelId: input.aiModel,
schema: optimizeSchema,
system: `${buildSystemPrompt(input.persona)}
Threads 稿
-
-
- 13 #
${HASHTAG_WRITING_RULES}
-
- ${THREADS_MAX_CHARS}
- summary 12 調`,
prompt: `請優化以下 Threads 貼文草稿。
${modeInstruction}
${input.angle ? `切入角度:${input.angle}` : ""}
"""
${input.text}
"""
text調summary`,
});
return {
text: object.text.slice(0, THREADS_MAX_CHARS),
summary: object.summary,
};
}