fix 5
This commit is contained in:
@@ -18,6 +18,12 @@ import { useLogsStore } from '../stores/logs';
|
||||
import { cn } from '../lib/utils';
|
||||
import { listen } from '@tauri-apps/api/event';
|
||||
import { useClipboard } from '../composables/useClipboard';
|
||||
import {
|
||||
buildConversationEvaluationUserPrompt,
|
||||
buildConversationRefinementUserPrompt,
|
||||
buildConversationSystemPrompt,
|
||||
buildConversationTranslationUserPrompt,
|
||||
} from '../lib/prompt-builders';
|
||||
import {
|
||||
executeTranslationRequest,
|
||||
extractAssistantContent,
|
||||
@@ -196,24 +202,21 @@ const translateMessage = async (sender: 'me' | 'partner', retranslateId?: string
|
||||
: 'Auto-detect';
|
||||
const senderName = sender === 'me' ? activeSession.value.me.name : activeSession.value.partner.name;
|
||||
|
||||
const systemPrompt = settings.chatSystemPromptTemplate
|
||||
.replace(/{ME_NAME}/g, activeSession.value.me.name)
|
||||
.replace(/{ME_GENDER}/g, activeSession.value.me.gender)
|
||||
.replace(/{ME_LANG}/g, activeSession.value.me.language.englishName)
|
||||
.replace(/{PART_NAME}/g, activeSession.value.partner.name)
|
||||
.replace(/{PART_GENDER}/g, activeSession.value.partner.gender)
|
||||
.replace(/{PART_LANG}/g, activeSession.value.partner.language.englishName)
|
||||
.replace(/{HISTORY_BLOCK}/g, historyBlock || 'None (This is the start of conversation)')
|
||||
.replace(/{SENDER_NAME}/g, senderName)
|
||||
.replace(/{FROM_LANG}/g, fromLang.englishName)
|
||||
.replace(/{TO_LANG}/g, toLang.englishName)
|
||||
.replace(/{TARGET_TONE}/g, targetTone);
|
||||
const systemPrompt = buildConversationSystemPrompt(settings.chatSystemPromptTemplate, {
|
||||
me: activeSession.value.me,
|
||||
partner: activeSession.value.partner,
|
||||
historyBlock,
|
||||
senderName,
|
||||
fromLang,
|
||||
toLang,
|
||||
targetTone,
|
||||
}, 'None (This is the start of conversation)');
|
||||
|
||||
const requestBody: TranslationPayload = {
|
||||
model: settings.modelName,
|
||||
messages: [
|
||||
{ role: "system", content: systemPrompt },
|
||||
{ role: "user", content: `[Text to Translate]\n${text}` }
|
||||
{ role: "user", content: buildConversationTranslationUserPrompt(text) }
|
||||
],
|
||||
stream: settings.enableStreaming
|
||||
};
|
||||
@@ -285,22 +288,17 @@ const evaluateMessage = async (messageId: string, force = false) => {
|
||||
? (TONE_REGISTER_OPTIONS.find(o => o.value === activeSession.value!.me.tone)?.value || 'Polite & Conversational')
|
||||
: 'Auto-detect';
|
||||
|
||||
const systemPrompt = settings.chatEvaluationPromptTemplate
|
||||
.replace(/{ME_NAME}/g, activeSession.value.me.name)
|
||||
.replace(/{ME_GENDER}/g, activeSession.value.me.gender)
|
||||
.replace(/{ME_LANG}/g, activeSession.value.me.language.englishName)
|
||||
.replace(/{PART_NAME}/g, activeSession.value.partner.name)
|
||||
.replace(/{PART_GENDER}/g, activeSession.value.partner.gender)
|
||||
.replace(/{PART_LANG}/g, activeSession.value.partner.language.englishName)
|
||||
.replace(/{HISTORY_BLOCK}/g, historyBlock || 'None')
|
||||
.replace(/{TARGET_TONE}/g, targetTone)
|
||||
.replace(/{SENDER_NAME}/g, senderName)
|
||||
.replace(/{FROM_LANG}/g, fromLang.englishName)
|
||||
.replace(/{TO_LANG}/g, toLang.englishName);
|
||||
// .replace(/{ORIGINAL_TEXT}/g, msg.original)
|
||||
// .replace(/{CURRENT_TRANSLATION}/g, msg.translated);
|
||||
const systemPrompt = buildConversationSystemPrompt(settings.chatEvaluationPromptTemplate, {
|
||||
me: activeSession.value.me,
|
||||
partner: activeSession.value.partner,
|
||||
historyBlock,
|
||||
senderName,
|
||||
fromLang,
|
||||
toLang,
|
||||
targetTone,
|
||||
}, 'None');
|
||||
|
||||
const userPrompt = `[Source Text]\n${msg.original}\n\n[Current Translation]\n${msg.translated}`;
|
||||
const userPrompt = buildConversationEvaluationUserPrompt(msg.original, msg.translated);
|
||||
|
||||
const modelConfig = resolveModelConfig({
|
||||
apiBaseUrl: settings.apiBaseUrl,
|
||||
@@ -350,7 +348,6 @@ const refineMessage = async (messageId: string) => {
|
||||
const selectedSuggestions = evalData.suggestions.filter((s: any) => selectedSuggestionIds.value.includes(s.id));
|
||||
if (selectedSuggestions.length === 0) return;
|
||||
|
||||
const suggestionsText = selectedSuggestions.map((s: any) => `- ${s.text}`).join('\n');
|
||||
const currentTranslation = msg.translated;
|
||||
|
||||
isAuditModalOpen.value = false; // 关闭弹窗开始润色
|
||||
@@ -375,21 +372,15 @@ const refineMessage = async (messageId: string) => {
|
||||
const toLang = msg.sender === 'me' ? activeSession.value.partner.language : activeSession.value.me.language;
|
||||
const senderName = msg.sender === 'me' ? activeSession.value.me.name : activeSession.value.partner.name;
|
||||
|
||||
const systemPrompt = settings.chatRefinementPromptTemplate
|
||||
.replace(/{ME_NAME}/g, activeSession.value.me.name)
|
||||
.replace(/{ME_GENDER}/g, activeSession.value.me.gender)
|
||||
.replace(/{ME_LANG}/g, activeSession.value.me.language.englishName)
|
||||
.replace(/{PART_NAME}/g, activeSession.value.partner.name)
|
||||
.replace(/{PART_GENDER}/g, activeSession.value.partner.gender)
|
||||
.replace(/{PART_LANG}/g, activeSession.value.partner.language.englishName)
|
||||
.replace(/{HISTORY_BLOCK}/g, historyBlock || 'None')
|
||||
// .replace(/{ORIGINAL_TEXT}/g, msg.original)
|
||||
// .replace(/{CURRENT_TRANSLATION}/g, msg.translated)
|
||||
// .replace(/{SUGGESTIONS}/g, suggestionsText)
|
||||
.replace(/{TARGET_TONE}/g, targetTone)
|
||||
.replace(/{SENDER_NAME}/g, senderName)
|
||||
.replace(/{FROM_LANG}/g, fromLang.englishName)
|
||||
.replace(/{TO_LANG}/g, toLang.englishName);
|
||||
const systemPrompt = buildConversationSystemPrompt(settings.chatRefinementPromptTemplate, {
|
||||
me: activeSession.value.me,
|
||||
partner: activeSession.value.partner,
|
||||
historyBlock,
|
||||
senderName,
|
||||
fromLang,
|
||||
toLang,
|
||||
targetTone,
|
||||
}, 'None');
|
||||
|
||||
const modelConfig = resolveModelConfig({
|
||||
apiBaseUrl: settings.apiBaseUrl,
|
||||
@@ -401,7 +392,7 @@ const refineMessage = async (messageId: string) => {
|
||||
model: modelConfig.modelName,
|
||||
messages: [
|
||||
{ role: "system", content: systemPrompt },
|
||||
{ role: "user", content: `[Source Text]\n${msg.original}\n\n[Current Translation]\n${currentTranslation}\n\n[Suggestions]\n${suggestionsText}` }
|
||||
{ role: "user", content: buildConversationRefinementUserPrompt(msg.original, currentTranslation, selectedSuggestions.map((s: any) => s.text)) }
|
||||
],
|
||||
stream: settings.enableStreaming
|
||||
};
|
||||
|
||||
@@ -9,6 +9,14 @@ import { useLogsStore } from '../stores/logs';
|
||||
import { useTranslationWorkspaceStore } from '../stores/translation-workspace';
|
||||
import { cn } from '../lib/utils';
|
||||
import { useClipboard } from '../composables/useClipboard';
|
||||
import {
|
||||
buildSingleEvaluationSystemPrompt,
|
||||
buildSingleEvaluationUserPrompt,
|
||||
buildSingleRefinementSystemPrompt,
|
||||
buildSingleRefinementUserPrompt,
|
||||
buildSingleTranslationSystemPrompt,
|
||||
buildSingleTranslationUserPrompt,
|
||||
} from '../lib/prompt-builders';
|
||||
import {
|
||||
executeTranslationRequest,
|
||||
extractAssistantContent,
|
||||
@@ -123,14 +131,15 @@ const evaluateTranslation = async () => {
|
||||
modelName: settings.modelName,
|
||||
}, settings.profiles, settings.evaluationProfileId);
|
||||
|
||||
const evaluationSystemPrompt = settings.evaluationPromptTemplate
|
||||
.replace(/{SOURCE_LANG}/g, sourceLang.value.englishName)
|
||||
.replace(/{TARGET_LANG}/g, targetLang.value.englishName)
|
||||
.replace(/{SPEAKER_IDENTITY}/g, settings.speakerIdentity)
|
||||
.replace(/{TONE_REGISTER}/g, settings.toneRegister)
|
||||
.replace(/{CONTEXT}/g, context.value || 'None');
|
||||
const evaluationSystemPrompt = buildSingleEvaluationSystemPrompt(settings.evaluationPromptTemplate, {
|
||||
sourceLang: sourceLang.value,
|
||||
targetLang: targetLang.value,
|
||||
speakerIdentity: settings.speakerIdentity,
|
||||
toneRegister: settings.toneRegister,
|
||||
context: context.value,
|
||||
});
|
||||
|
||||
const evaluationUserPrompt = `[Source Text]\n${sourceText.value}\n\n[Translated Text]\n${targetText.value}`;
|
||||
const evaluationUserPrompt = buildSingleEvaluationUserPrompt(sourceText.value, targetText.value);
|
||||
|
||||
const requestBody: TranslationPayload = {
|
||||
model: modelConfig.modelName,
|
||||
@@ -173,15 +182,15 @@ const refineTranslation = async () => {
|
||||
modelName: settings.modelName,
|
||||
}, settings.profiles, settings.evaluationProfileId);
|
||||
|
||||
const refinementSystemPrompt = settings.refinementPromptTemplate
|
||||
.replace(/{SOURCE_LANG}/g, sourceLang.value.englishName)
|
||||
.replace(/{TARGET_LANG}/g, targetLang.value.englishName)
|
||||
.replace(/{SPEAKER_IDENTITY}/g, settings.speakerIdentity)
|
||||
.replace(/{TONE_REGISTER}/g, settings.toneRegister)
|
||||
.replace(/{CONTEXT}/g, context.value || 'None');
|
||||
const refinementSystemPrompt = buildSingleRefinementSystemPrompt(settings.refinementPromptTemplate, {
|
||||
sourceLang: sourceLang.value,
|
||||
targetLang: targetLang.value,
|
||||
speakerIdentity: settings.speakerIdentity,
|
||||
toneRegister: settings.toneRegister,
|
||||
context: context.value,
|
||||
});
|
||||
|
||||
const formattedSuggestions = selectedTexts.map((text, i) => `${i + 1}. ${text}`).join('\n');
|
||||
const refinementUserPrompt = `[Source Text]\n${sourceText.value}\n\n[Current Translation]\n${originalTranslation}\n\n[User Feedback]\n${formattedSuggestions}`;
|
||||
const refinementUserPrompt = buildSingleRefinementUserPrompt(sourceText.value, originalTranslation, selectedTexts);
|
||||
|
||||
const requestBody: TranslationPayload = {
|
||||
model: modelConfig.modelName,
|
||||
@@ -229,17 +238,14 @@ const translate = async () => {
|
||||
targetText.value = '';
|
||||
evaluationResult.value = null;
|
||||
|
||||
const systemMessage = settings.systemPromptTemplate
|
||||
.replace(/{SOURCE_LANG}/g, sourceLang.value.englishName)
|
||||
.replace(/{SOURCE_CODE}/g, sourceLang.value.code)
|
||||
.replace(/{TARGET_LANG}/g, targetLang.value.englishName)
|
||||
.replace(/{TARGET_CODE}/g, targetLang.value.code)
|
||||
.replace(/{SPEAKER_IDENTITY}/g, settings.speakerIdentity)
|
||||
.replace(/{TONE_REGISTER}/g, settings.toneRegister);
|
||||
const systemMessage = buildSingleTranslationSystemPrompt(settings.systemPromptTemplate, {
|
||||
sourceLang: sourceLang.value,
|
||||
targetLang: targetLang.value,
|
||||
speakerIdentity: settings.speakerIdentity,
|
||||
toneRegister: settings.toneRegister,
|
||||
});
|
||||
|
||||
const userMessage = context.value
|
||||
? `[Context]\n${context.value}\n\n[Text to Translate]\n${sourceText.value}`
|
||||
: `[Text to Translate]\n${sourceText.value}`;
|
||||
const userMessage = buildSingleTranslationUserPrompt(sourceText.value, context.value);
|
||||
|
||||
const requestBody: TranslationPayload = {
|
||||
model: settings.modelName,
|
||||
|
||||
103
src/lib/prompt-builders.ts
Normal file
103
src/lib/prompt-builders.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import type { Language, Participant } from '../stores/settings';
|
||||
|
||||
interface SingleTranslationPromptContext {
|
||||
sourceLang: Language;
|
||||
targetLang: Language;
|
||||
speakerIdentity: string;
|
||||
toneRegister: string;
|
||||
context: string;
|
||||
}
|
||||
|
||||
interface ConversationPromptContext {
|
||||
me: Participant;
|
||||
partner: Participant;
|
||||
historyBlock: string;
|
||||
senderName: string;
|
||||
fromLang: Language;
|
||||
toLang: Language;
|
||||
targetTone: string;
|
||||
}
|
||||
|
||||
function replaceTokens(template: string, values: Record<string, string>) {
|
||||
return Object.entries(values).reduce(
|
||||
(result, [key, value]) => result.replace(new RegExp(`\\{${key}\\}`, 'g'), value),
|
||||
template,
|
||||
);
|
||||
}
|
||||
|
||||
export function buildSingleTranslationSystemPrompt(
|
||||
template: string,
|
||||
context: Omit<SingleTranslationPromptContext, 'context'>,
|
||||
) {
|
||||
return replaceTokens(template, {
|
||||
SOURCE_LANG: context.sourceLang.englishName,
|
||||
SOURCE_CODE: context.sourceLang.code,
|
||||
TARGET_LANG: context.targetLang.englishName,
|
||||
TARGET_CODE: context.targetLang.code,
|
||||
SPEAKER_IDENTITY: context.speakerIdentity,
|
||||
TONE_REGISTER: context.toneRegister,
|
||||
});
|
||||
}
|
||||
|
||||
export function buildSingleEvaluationSystemPrompt(
|
||||
template: string,
|
||||
context: SingleTranslationPromptContext,
|
||||
) {
|
||||
return replaceTokens(template, {
|
||||
SOURCE_LANG: context.sourceLang.englishName,
|
||||
TARGET_LANG: context.targetLang.englishName,
|
||||
SPEAKER_IDENTITY: context.speakerIdentity,
|
||||
TONE_REGISTER: context.toneRegister,
|
||||
CONTEXT: context.context || 'None',
|
||||
});
|
||||
}
|
||||
|
||||
export function buildSingleRefinementSystemPrompt(
|
||||
template: string,
|
||||
context: SingleTranslationPromptContext,
|
||||
) {
|
||||
return buildSingleEvaluationSystemPrompt(template, context);
|
||||
}
|
||||
|
||||
export function buildSingleTranslationUserPrompt(sourceText: string, context: string) {
|
||||
return context
|
||||
? `[Context]\n${context}\n\n[Text to Translate]\n${sourceText}`
|
||||
: `[Text to Translate]\n${sourceText}`;
|
||||
}
|
||||
|
||||
export function buildSingleEvaluationUserPrompt(sourceText: string, targetText: string) {
|
||||
return `[Source Text]\n${sourceText}\n\n[Translated Text]\n${targetText}`;
|
||||
}
|
||||
|
||||
export function buildSingleRefinementUserPrompt(sourceText: string, currentTranslation: string, suggestions: string[]) {
|
||||
const formattedSuggestions = suggestions.map((text, index) => `${index + 1}. ${text}`).join('\n');
|
||||
return `[Source Text]\n${sourceText}\n\n[Current Translation]\n${currentTranslation}\n\n[User Feedback]\n${formattedSuggestions}`;
|
||||
}
|
||||
|
||||
export function buildConversationSystemPrompt(template: string, context: ConversationPromptContext, emptyHistoryFallback: string) {
|
||||
return replaceTokens(template, {
|
||||
ME_NAME: context.me.name,
|
||||
ME_GENDER: context.me.gender,
|
||||
ME_LANG: context.me.language.englishName,
|
||||
PART_NAME: context.partner.name,
|
||||
PART_GENDER: context.partner.gender,
|
||||
PART_LANG: context.partner.language.englishName,
|
||||
HISTORY_BLOCK: context.historyBlock || emptyHistoryFallback,
|
||||
SENDER_NAME: context.senderName,
|
||||
FROM_LANG: context.fromLang.englishName,
|
||||
TO_LANG: context.toLang.englishName,
|
||||
TARGET_TONE: context.targetTone,
|
||||
});
|
||||
}
|
||||
|
||||
export function buildConversationTranslationUserPrompt(text: string) {
|
||||
return `[Text to Translate]\n${text}`;
|
||||
}
|
||||
|
||||
export function buildConversationEvaluationUserPrompt(sourceText: string, currentTranslation: string) {
|
||||
return `[Source Text]\n${sourceText}\n\n[Current Translation]\n${currentTranslation}`;
|
||||
}
|
||||
|
||||
export function buildConversationRefinementUserPrompt(sourceText: string, currentTranslation: string, suggestions: string[]) {
|
||||
return `[Source Text]\n${sourceText}\n\n[Current Translation]\n${currentTranslation}\n\n[Suggestions]\n${suggestions.map((text) => `- ${text}`).join('\n')}`;
|
||||
}
|
||||
Reference in New Issue
Block a user