create separate translation functions for full pages vs fragments
This commit is contained in:
parent
e975e97ea3
commit
b7563d0f2b
1 changed files with 91 additions and 1 deletions
|
|
@ -398,6 +398,70 @@ ${preservedText}`;
|
|||
}
|
||||
}
|
||||
|
||||
// Internal function to translate HTML fragments (for chunked translations)
|
||||
async function translateFragmentRaw(text, targetLanguage) {
|
||||
// Ensure models are loaded before translation
|
||||
const { fetchModelsFromEndpoints } = await import("./models.js");
|
||||
await fetchModelsFromEndpoints();
|
||||
|
||||
// Skip preservation - assume text is already preserved
|
||||
const preservedText = text;
|
||||
|
||||
// Build fragment-specific prompt
|
||||
const prompt = `Translate the following HTML fragment into ${SUPPORTED_LANGUAGES[targetLanguage]}. This is a partial section of a webpage, not a complete document. Preserve the exact HTML structure and only translate the text content. Do not add any additional HTML elements, headers, navigation, or wrapper tags. Do not translate or modify placeholders like __CODE_0__, __URI_0__, __HTML_0__, etc., as they represent code blocks, URLs, or HTML elements that should remain unchanged. Only translate the text within the provided HTML structure. Here is the HTML fragment to translate:
|
||||
|
||||
${preservedText}`;
|
||||
|
||||
// Get accurate token count and timing estimate using upstream tokenizer
|
||||
const tokenInfo = await countTokensWithUpstream(prompt, getSelectedModel());
|
||||
const estimatedSeconds = estimateProcessingTime(tokenInfo.totalTokens);
|
||||
|
||||
console.log("=== FRAGMENT TRANSLATION ANALYSIS ===");
|
||||
console.log(`Input tokens: ${tokenInfo.totalTokens}`);
|
||||
console.log(`Text length: ${tokenInfo.textLength} characters`);
|
||||
console.log(`Estimated processing time: ${estimatedSeconds} seconds`);
|
||||
|
||||
// Fragment-specific system message
|
||||
const translationHistory = [
|
||||
{
|
||||
role: "system",
|
||||
content:
|
||||
"You are a translation assistant specializing in HTML fragments. Translate only the text content while preserving the exact HTML structure. Never add wrapper elements or complete partial documents. Return only the translated fragment as provided.",
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: prompt,
|
||||
},
|
||||
];
|
||||
|
||||
let translatedText = "";
|
||||
|
||||
try {
|
||||
for await (const chunk of sendMessageWithHistory(translationHistory)) {
|
||||
translatedText += chunk;
|
||||
}
|
||||
|
||||
// Clean up the response
|
||||
translatedText = translatedText.trim();
|
||||
console.log("Fragment AI response length:", translatedText.length);
|
||||
|
||||
// Validate response
|
||||
if (!translatedText || translatedText.length === 0) {
|
||||
throw new Error(
|
||||
"Fragment translation API returned empty response. Please try again.",
|
||||
);
|
||||
}
|
||||
|
||||
console.log("=== FRAGMENT TRANSLATION RESULT ===");
|
||||
console.log(`Fragment translated length: ${translatedText.length} characters`);
|
||||
|
||||
return translatedText;
|
||||
} catch (error) {
|
||||
console.error("Fragment translation error:", error);
|
||||
throw new Error("Fragment translation failed. Please try again.");
|
||||
}
|
||||
}
|
||||
|
||||
// Translate text using Hermes AI with minimal system context
|
||||
export async function translateText(text, targetLanguage) {
|
||||
const { preservedText, preservations } = preserveSpecialContent(text);
|
||||
|
|
@ -434,6 +498,32 @@ export async function translateText(text, targetLanguage) {
|
|||
return restored;
|
||||
}
|
||||
|
||||
// Translate HTML fragment with preservation (for chunked content)
|
||||
async function translateFragment(text, targetLanguage) {
|
||||
const { preservedText, preservations } = preserveSpecialContent(text);
|
||||
|
||||
// Use fragment-specific translation function
|
||||
const translatedText = await translateFragmentRaw(preservedText, targetLanguage);
|
||||
|
||||
// Check if placeholders are still in the response
|
||||
preservations.forEach((item, _index) => {
|
||||
const found = translatedText.includes(item.placeholder);
|
||||
console.log(
|
||||
` Fragment placeholder ${item.placeholder} found in response: ${found}`,
|
||||
);
|
||||
});
|
||||
|
||||
// Restore preserved content
|
||||
const restored = restoreSpecialContent(translatedText, preservations);
|
||||
console.log("Fragment restored text length:", restored.length);
|
||||
|
||||
// Final validation
|
||||
if (!restored || restored.length === 0) {
|
||||
throw new Error("Fragment translation processing failed. Please try again.");
|
||||
}
|
||||
|
||||
return restored;
|
||||
}
|
||||
|
||||
// Extract page content for translation
|
||||
export function extractPageContent() {
|
||||
|
|
@ -568,7 +658,7 @@ export async function translateHTML(htmlContent, targetLanguage, sourceUrl = nul
|
|||
const batchPromises = batch.map((chunk, batchIndex) => {
|
||||
const chunkIndex = i + batchIndex + 1;
|
||||
console.log(`Translating chunk ${chunkIndex}/${chunks.length}`);
|
||||
return translateText(chunk, targetLanguage);
|
||||
return translateFragment(chunk, targetLanguage);
|
||||
});
|
||||
|
||||
try {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue