增加pdf中划句或段ai伴读功能
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import { parseJsonLoose } from "../../../llm/jsonParse";
|
||||
import { LlmError } from "../../../llm/types";
|
||||
import type { SummaryJson } from "../../domain/types";
|
||||
import { requestStructuredOutput } from "./structuredOutput";
|
||||
|
||||
const SENTENCE_SYSTEM = `你是 ChatPapers 论文伴读助手。用户选中论文中的一句原文,需要你解释并用于语音朗读。
|
||||
必须只输出一个 JSON 对象,不要 markdown 代码块。
|
||||
格式:{"translation":"...","syntaxNote":"...","contextRole":"..."}
|
||||
|
||||
要求:
|
||||
- translation:准确中文翻译,并用 30–80 字口语解释该句含义(不要念 LaTeX,公式转述为口语)。
|
||||
- syntaxNote:1–2 句,拆解句法结构或关键术语(英文句为主;中文句可简述逻辑)。
|
||||
- contextRole:1 句,说明该句在段落或全文论证中的作用。
|
||||
- 术语翻译与全文保持一致。`;
|
||||
|
||||
export interface SentenceLlmResult {
|
||||
translation: string;
|
||||
syntaxNote: string;
|
||||
contextRole: string;
|
||||
}
|
||||
|
||||
function parseSentenceJson(raw: string): SentenceLlmResult {
|
||||
const parsed = parseJsonLoose<Record<string, unknown>>(raw);
|
||||
const translation = String(parsed.translation || parsed.zh || "").trim();
|
||||
if (!translation) {
|
||||
throw new LlmError("provider", "单句讲解 JSON 缺少 translation 字段。");
|
||||
}
|
||||
return {
|
||||
translation,
|
||||
syntaxNote: String(parsed.syntaxNote || parsed.syntax || "").trim(),
|
||||
contextRole: String(parsed.contextRole || parsed.role || parsed.context || "").trim(),
|
||||
};
|
||||
}
|
||||
|
||||
function fallbackSentence(selectedText: string): SentenceLlmResult {
|
||||
return {
|
||||
translation: selectedText.slice(0, 200),
|
||||
syntaxNote: "",
|
||||
contextRole: "(模型未能生成上下文说明,请重试或更换模型。)",
|
||||
};
|
||||
}
|
||||
|
||||
function formatSummaryBlock(summary?: SummaryJson): string {
|
||||
if (!summary) return "(暂无全文摘要)";
|
||||
return [
|
||||
`问题:${summary.problem}`,
|
||||
`方法:${summary.method}`,
|
||||
`结果:${summary.result}`,
|
||||
`局限:${summary.limitation}`,
|
||||
].join("\n");
|
||||
}
|
||||
|
||||
export async function generateSentenceExplanation(options: {
|
||||
paperTitle: string;
|
||||
summary?: SummaryJson;
|
||||
selectedText: string;
|
||||
surroundingContext?: string;
|
||||
}): Promise<SentenceLlmResult> {
|
||||
const user = `【论文标题】${options.paperTitle}
|
||||
|
||||
【全文摘要】
|
||||
${formatSummaryBlock(options.summary)}
|
||||
|
||||
【选区附近上下文(可能为空)】
|
||||
${options.surroundingContext?.trim() || "(无)"}
|
||||
|
||||
【用户选中的句子】
|
||||
${options.selectedText.trim()}
|
||||
|
||||
请输出 JSON。`;
|
||||
|
||||
return requestStructuredOutput({
|
||||
system: SENTENCE_SYSTEM,
|
||||
user,
|
||||
parse: parseSentenceJson,
|
||||
jsonMode: true,
|
||||
fallback: () => fallbackSentence(options.selectedText),
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user