Make sure all prompts are static

This commit is contained in:
dazedanon 2026-03-16 01:39:04 -05:00
parent e1c903ee42
commit 7292a6c3c7
21 changed files with 203 additions and 199 deletions

View file

@ -55,13 +55,5 @@ output_cost= 0.002
# Batch size - adjust according to your API's limitations
batchsize="10"
# Estimate Prompt Cache Rate.
estimate_cache_rate='0.7'
# Frequency penalty - adjust according to your needs
frequency_penalty= 0.2
# Assumed prompt-cache hit rate for Claude/Sonnet/Haiku/Opus cost estimates.
# 0.9 = 90% of input tokens billed at 10% (cache read rate), giving a much
# lower estimate than the full input rate. Set to 0 to disable the discount.
ESTIMATE_CACHE_RATE=0.9
frequency_penalty= 0.2

View file

@ -145,7 +145,7 @@ def translateSimpleKeyValueJSON(data, filename, stringList, keyList):
PBAR.total = len(preparedStringList)
PBAR.refresh()
response = translateAI(preparedStringList, "Reply with the English Translation", True)
response = translateAI(preparedStringList, "Reply with the English Translation")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
translatedList = response[0]
@ -200,14 +200,13 @@ def getResultString(translatedData, translationTime, filename):
errorString = str(translatedData[2]) + Fore.RED
return f"{filename}: {totalTokenstring}{timeString}" + Fore.RED + " \u2717 " + errorString + Fore.RESET
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history, history_ctx=None):
"""Legacy wrapper for the shared translation utility."""
global PBAR, MISMATCH, FILENAME
TRANSLATION_CONFIG.estimateMode = bool(ESTIMATE)
return sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=FILENAME,
pbar=PBAR,

View file

@ -361,7 +361,7 @@ def translateCSV(data, pbar, writeFile, writer, filename, translatedList):
pbar.refresh()
# Translate
response = translateAI(stringList, "", True)
response = translateAI(stringList, "")
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
translatedList = response[0]
@ -436,7 +436,7 @@ def getSpeaker(speaker):
return response
return [speaker, [0, 0]]
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history, history_ctx=None):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
@ -450,7 +450,6 @@ def translateAI(text, history, fullPromptFlag):
return sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=FILENAME,
pbar=PBAR,

View file

@ -373,7 +373,7 @@ def translateImages(imageList):
totalTokens = [0, 0]
# Translate GPT
response = translateAI(imageList[0], "Keep the Translation as brief as possible", True)
response = translateAI(imageList[0], "Keep the Translation as brief as possible")
translatedList = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -417,7 +417,7 @@ def getSpeaker(speaker):
NAMESLIST.append(speakerList)
return response
return [speaker, [0, 0]]
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history, history_ctx=None):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
@ -431,7 +431,6 @@ def translateAI(text, history, fullPromptFlag):
return sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=FILENAME,
pbar=PBAR,

View file

@ -226,7 +226,7 @@ def translateSimpleKeyValueJSON(data, filename):
PBAR.total = len(stringList)
PBAR.refresh()
response = translateAI(stringList, "Reply with the English Translation", True)
response = translateAI(stringList, "Reply with the English Translation")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
translatedList = response[0]
@ -269,7 +269,7 @@ def translatePSData(data, filename):
nonlocal tokens
if not stringList:
return []
response = translateAI(stringList, context, True)
response = translateAI(stringList, context)
tokens[0] += response[1][0]
tokens[1] += response[1][1]
if len(stringList) != len(response[0]):
@ -491,7 +491,7 @@ def translateRdData(data, filename):
nonlocal tokens
if not stringList:
return []
response = translateAI(stringList, context, True)
response = translateAI(stringList, context)
tokens[0] += response[1][0]
tokens[1] += response[1][1]
if len(stringList) != len(response[0]):
@ -743,7 +743,7 @@ def translateGameSetting(data, filename):
nonlocal tokens
if not stringList:
return []
response = translateAI(stringList, context, True)
response = translateAI(stringList, context)
tokens[0] += response[1][0]
tokens[1] += response[1][1]
if len(stringList) != len(response[0]):
@ -1092,7 +1092,7 @@ def translateJSON(data, filename, translatedList):
# Event Title
if eventList[0]:
response = translateAI(eventList[0], "Event Title", True)
response = translateAI(eventList[0], "Event Title")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
eventListTL[0] = response[0]
@ -1104,7 +1104,7 @@ def translateJSON(data, filename, translatedList):
# Event Process
if eventList[1]:
response = translateAI(eventList[1], "Event Process", True)
response = translateAI(eventList[1], "Event Process")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
eventListTL[1] = response[0]
@ -1116,7 +1116,7 @@ def translateJSON(data, filename, translatedList):
# Event Text
if eventList[2]:
response = translateAI(eventList[2], "Event Description", True)
response = translateAI(eventList[2], "Event Description")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
eventListTL[2] = response[0]
@ -1128,7 +1128,7 @@ def translateJSON(data, filename, translatedList):
# Event Key
if eventList[3]:
response = translateAI(eventList[3], "Event Key", True)
response = translateAI(eventList[3], "Event Key")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
eventListTL[3] = response[0]
@ -1140,7 +1140,7 @@ def translateJSON(data, filename, translatedList):
# Event Target
if eventList[4]:
response = translateAI(eventList[4], "Character Name", True)
response = translateAI(eventList[4], "Character Name")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
eventListTL[4] = response[0]
@ -1152,7 +1152,7 @@ def translateJSON(data, filename, translatedList):
# Event Job
if eventList[5]:
response = translateAI(eventList[5], "Job/Occupation", True)
response = translateAI(eventList[5], "Job/Occupation")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
eventListTL[5] = response[0]
@ -1164,7 +1164,7 @@ def translateJSON(data, filename, translatedList):
# Event Place
if eventList[6]:
response = translateAI(eventList[6], "Location Name", True)
response = translateAI(eventList[6], "Location Name")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
eventListTL[6] = response[0]
@ -1178,7 +1178,7 @@ def translateJSON(data, filename, translatedList):
if stringList:
PBAR.total = len(stringList)
PBAR.refresh()
response = translateAI(stringList, "Reply with the English Translation", True)
response = translateAI(stringList, "Reply with the English Translation")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
stringListTL = response[0]
@ -1232,7 +1232,7 @@ def getSpeaker(speaker):
return response
return [speaker, [0, 0]]
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history, history_ctx=None):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
@ -1246,7 +1246,6 @@ def translateAI(text, history, fullPromptFlag):
return sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=FILENAME,
pbar=PBAR,

View file

@ -509,7 +509,7 @@ def getSpeaker(speaker):
return response
return [speaker, [0, 0]]
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history, history_ctx=None):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
@ -523,7 +523,6 @@ def translateAI(text, history, fullPromptFlag):
return sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=FILENAME,
pbar=PBAR,

View file

@ -236,7 +236,7 @@ def translateJSON(data, pbar):
# Translate Batch if Full
if len(batch) == BATCHSIZE:
# Translate
response = translateAI(batch, textHistory, True)
response = translateAI(batch, textHistory)
tokens[0] += response[1][0]
tokens[1] += response[1][1]
translatedBatch = response[0]
@ -289,7 +289,7 @@ def translateJSON(data, pbar):
# Translate Batch if not empty and EOF
if len(batch) != 0 and i >= len(data):
# Translate
response = translateAI(batch, textHistory, True)
response = translateAI(batch, textHistory)
tokens[0] += response[1][0]
tokens[1] += response[1][1]
translatedBatch = response[0]
@ -350,7 +350,7 @@ def getSpeaker(speaker):
return response
return [speaker, [0, 0]]
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
@ -364,7 +364,6 @@ def translateAI(text, history, fullPromptFlag):
return sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=FILENAME,
pbar=PBAR,

View file

@ -296,7 +296,7 @@ def translateOnscripter(data, pbar, filename, translatedList):
choiceList = re.findall(r"\"(.*?)\"", jaString)
if len(choiceList) > 0:
# Translate
response = translateAI(choiceList, "This will be a dialogue option", True)
response = translateAI(choiceList, "This will be a dialogue option")
translatedTextList = response[0]
tokens[0] += response[1][0]
tokens[1] += response[1][1]
@ -323,7 +323,7 @@ def translateOnscripter(data, pbar, filename, translatedList):
pbar.refresh()
# Translate
response = translateAI(stringList, "", True)
response = translateAI(stringList, "")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
translatedList = response[0]
@ -410,9 +410,17 @@ def getSpeaker(speaker):
return [speaker, [0, 0]]
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history):
"""
Translate text using the shared translation utility.
This function maintains compatibility with existing code while using the new shared implementation.
"""
return sharedtranslateAI(TRANSLATION_CONFIG, text, history, fullPromptFlag)
return sharedtranslateAI(
text=text,
history=history,
config=TRANSLATION_CONFIG,
filename=FILENAME,
pbar=PBAR,
lock=LOCK,
mismatchList=MISMATCH
)

View file

@ -440,7 +440,7 @@ def translateRegex(data, filename, translatedList):
# String List
if stringList:
response = translateAI(stringList, "Reply with the English Translation", True)
response = translateAI(stringList, "Reply with the English Translation")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
stringListTL = response[0]
@ -453,7 +453,7 @@ def translateRegex(data, filename, translatedList):
# Choice List
if choiceList:
response = translateAI(choiceList, "Reply with the English TL of the Dialogue Choice", True)
response = translateAI(choiceList, "Reply with the English TL of the Dialogue Choice")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
choiceListTL = response[0]
@ -506,7 +506,7 @@ def getSpeaker(speaker):
return response
return [speaker, [0, 0]]
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
@ -520,7 +520,6 @@ def translateAI(text, history, fullPromptFlag):
return sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=FILENAME,
pbar=PBAR,

View file

@ -275,7 +275,7 @@ def translateRenpy(data, filename, translatedList):
PBAR.refresh()
# Translate
response = translateAI(stringList, "Reply with the English TL of the NPC Name", True)
response = translateAI(stringList, "Reply with the English TL of the NPC Name")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
translatedList = response[0]
@ -329,7 +329,7 @@ def getSpeaker(speaker):
return response
return [speaker, [0, 0]]
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history, history_ctx=None):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
@ -343,7 +343,6 @@ def translateAI(text, history, fullPromptFlag):
return sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=FILENAME,
pbar=PBAR,

View file

@ -1211,7 +1211,7 @@ def searchNames(data, pbar, context, filename):
# --- Batch translate all notes ---
translatedNotesBatch = []
if notesBatch:
response = translateAI(notesBatch, f"Reply with only the {LANGUAGE} translation of the note text.", True)
response = translateAI(notesBatch, f"Reply with only the {LANGUAGE} translation of the note text.")
translatedNotesBatch = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -1329,7 +1329,7 @@ def searchNames(data, pbar, context, filename):
# Track tokens for this batch
batchTokens = [0, 0]
# Name
response = translateAI(nameList, newContext, True)
response = translateAI(nameList, newContext)
translatedNameBatch = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -1340,7 +1340,7 @@ def searchNames(data, pbar, context, filename):
# Nickname
if nicknameList:
response = translateAI(nicknameList, newContext, True)
response = translateAI(nicknameList, newContext)
translatedNicknameBatch = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -1351,7 +1351,7 @@ def searchNames(data, pbar, context, filename):
# Profile
if profileList:
response = translateAI(profileList, "", True)
response = translateAI(profileList, "")
translatedProfileBatch = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -1400,7 +1400,7 @@ def searchNames(data, pbar, context, filename):
# Track tokens for this batch
batchTokens = [0, 0]
# Name
response = translateAI(nameList, newContext, True)
response = translateAI(nameList, newContext)
translatedNameBatch = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -1462,7 +1462,7 @@ def searchNames(data, pbar, context, filename):
if context in ["Enemies", "Classes", "MapInfos"]:
# Track tokens for this batch
batchTokens = [0, 0]
response = translateAI(nameList, newContext, True)
response = translateAI(nameList, newContext)
translatedNameBatch = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -2190,7 +2190,7 @@ def searchCodes(page, pbar, jobList, filename):
# Remove any textwrap & TL
jaString = re.sub(r"\n", " ", jaString)
response = translateAI(jaString, "", False)
response = translateAI(jaString, "")
translatedText = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -2257,7 +2257,7 @@ def searchCodes(page, pbar, jobList, filename):
jaString = re.sub(r"\n", " ", jaString)
# Translate
response = translateAI(jaString, "", True)
response = translateAI(jaString, "")
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
translatedText = response[0]
@ -2805,7 +2805,7 @@ def searchCodes(page, pbar, jobList, filename):
if len(matchList) > 0:
# Translate
text = matchList[0]
response = translateAI(text, "Reply with the " + LANGUAGE + " Translation", False)
response = translateAI(text, "Reply with the " + LANGUAGE + " Translation")
translatedText = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -2844,7 +2844,7 @@ def searchCodes(page, pbar, jobList, filename):
if len(matchList) > 0:
# Translate
text = matchList[0]
response = translateAI(text, "Reply with the " + LANGUAGE + " Translation", False)
response = translateAI(text, "Reply with the " + LANGUAGE + " Translation")
translatedText = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -2863,7 +2863,7 @@ def searchCodes(page, pbar, jobList, filename):
# Remove any textwrap & TL
jaString = re.sub(r"\n", " ", jaString)
response = translateAI(jaString, "", False)
response = translateAI(jaString, "")
translatedText = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -2940,7 +2940,7 @@ def searchCodes(page, pbar, jobList, filename):
True,
)
else:
response = translateAI(choiceList, "Reply with the English translation of the dialogue choice.", True)
response = translateAI(choiceList, "Reply with the English translation of the dialogue choice.")
translatedTextList = response[0]
totalTokens[0] += response[1][0]
@ -2984,7 +2984,7 @@ def searchCodes(page, pbar, jobList, filename):
matchList = re.findall(r"'(.*?)'", jaString)
for match in matchList:
response = translateAI(match, "", False)
response = translateAI(match, "")
translatedText = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3114,7 +3114,7 @@ def searchCodes(page, pbar, jobList, filename):
# 401
if len(list401) > 0:
response = translateAI(list401, "", True)
response = translateAI(list401, "")
list401TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3125,7 +3125,7 @@ def searchCodes(page, pbar, jobList, filename):
# 122
if len(list122) > 0:
response = translateAI(list122, "Keep your translation as brief as possible", True)
response = translateAI(list122, "Keep your translation as brief as possible")
list122TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3136,7 +3136,7 @@ def searchCodes(page, pbar, jobList, filename):
# 355/655
if len(list355655) > 0:
response = translateAI(list355655, textHistory, True)
response = translateAI(list355655, textHistory)
list355655TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3147,7 +3147,7 @@ def searchCodes(page, pbar, jobList, filename):
# 108
if len(list108) > 0:
response = translateAI(list108, "This text is a label. Use title capitalization and keep it brief.", True)
response = translateAI(list108, "This text is a label. Use title capitalization and keep it brief.")
list108TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3158,7 +3158,7 @@ def searchCodes(page, pbar, jobList, filename):
# 356
if len(list356) > 0:
response = translateAI(list356, textHistory, True)
response = translateAI(list356, textHistory)
list356TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3169,7 +3169,7 @@ def searchCodes(page, pbar, jobList, filename):
# 357
if len(list357) > 0:
response = translateAI(list357, textHistory, True)
response = translateAI(list357, textHistory)
list357TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3180,7 +3180,7 @@ def searchCodes(page, pbar, jobList, filename):
# 408
if len(list408) > 0:
response = translateAI(list408, "", True)
response = translateAI(list408, "")
list408TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3192,7 +3192,7 @@ def searchCodes(page, pbar, jobList, filename):
# 324
if len(list324) > 0:
# Generic short-text translation for parameter index 1
response = translateAI(list324, "Reply with only the " + LANGUAGE + " translation of the text.", True)
response = translateAI(list324, "Reply with only the " + LANGUAGE + " translation of the text.")
list324TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3204,7 +3204,7 @@ def searchCodes(page, pbar, jobList, filename):
# 325
if len(list325) > 0:
# Use same short-text speaker-style translation as other name fields
response = translateAI(list325, "Reply with the " + LANGUAGE + " translation of the NPC name.", True)
response = translateAI(list325, "Reply with the " + LANGUAGE + " translation of the NPC name.")
list325TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3341,7 +3341,7 @@ def searchSS(state, pbar):
# --- Batch translate all notes ---
translatedNotesBatch = []
if notesBatch:
response = translateAI(notesBatch, f"Reply with only the {LANGUAGE} translation of the note text.", True)
response = translateAI(notesBatch, f"Reply with only the {LANGUAGE} translation of the note text.")
translatedNotesBatch = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3423,7 +3423,7 @@ def searchSystem(data, pbar):
term_indices.append(i)
if term_values:
response = translateAI(term_values, context, False)
response = translateAI(term_values, context)
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
tl_list = response[0]
@ -3683,7 +3683,7 @@ def getSpeaker(speaker: str):
NAMESLIST.append([speaker, translated])
return [translated, response[1]]
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
@ -3723,7 +3723,6 @@ def translateAI(text, history, fullPromptFlag):
return sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=tl_filename,
pbar=PBAR,

View file

@ -1385,7 +1385,7 @@ def searchNames(data, pbar, context, filename):
# --- Batch translate all notes ---
translatedNotesBatch = []
if notesBatch:
response = translateAI(notesBatch, f"Reply with only the {LANGUAGE} translation of the note text.", True)
response = translateAI(notesBatch, f"Reply with only the {LANGUAGE} translation of the note text.")
translatedNotesBatch = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -1525,7 +1525,7 @@ def searchNames(data, pbar, context, filename):
# Track tokens for this batch
batchTokens = [0, 0]
# Name
response = translateAI(nameList, newContext, True)
response = translateAI(nameList, newContext)
translatedNameBatch = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -1536,7 +1536,7 @@ def searchNames(data, pbar, context, filename):
# Nickname
if nicknameList:
response = translateAI(nicknameList, newContext, True)
response = translateAI(nicknameList, newContext)
translatedNicknameBatch = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -1547,7 +1547,7 @@ def searchNames(data, pbar, context, filename):
# Profile
if profileList:
response = translateAI(profileList, "", True)
response = translateAI(profileList, "")
translatedProfileBatch = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -1596,7 +1596,7 @@ def searchNames(data, pbar, context, filename):
# Track tokens for this batch
batchTokens = [0, 0]
# Name
response = translateAI(nameList, newContext, True)
response = translateAI(nameList, newContext)
translatedNameBatch = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -1658,7 +1658,7 @@ def searchNames(data, pbar, context, filename):
if context in ["Enemies", "Classes", "MapInfos"]:
# Track tokens for this batch
batchTokens = [0, 0]
response = translateAI(nameList, newContext, True)
response = translateAI(nameList, newContext)
translatedNameBatch = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -2506,7 +2506,7 @@ def searchCodes(page, pbar, jobList, filename):
# Remove any textwrap & TL
jaString = re.sub(r"\n", " ", jaString)
response = translateAI(jaString, "", False)
response = translateAI(jaString, "")
translatedText = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3343,7 +3343,7 @@ def searchCodes(page, pbar, jobList, filename):
if len(matchList) > 0:
# Translate
text = matchList[0]
response = translateAI(text, "Reply with the " + LANGUAGE + " Translation", False)
response = translateAI(text, "Reply with the " + LANGUAGE + " Translation")
translatedText = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3382,7 +3382,7 @@ def searchCodes(page, pbar, jobList, filename):
if len(matchList) > 0:
# Translate
text = matchList[0]
response = translateAI(text, "Reply with the " + LANGUAGE + " Translation", False)
response = translateAI(text, "Reply with the " + LANGUAGE + " Translation")
translatedText = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3401,7 +3401,7 @@ def searchCodes(page, pbar, jobList, filename):
# Remove any textwrap & TL
jaString = re.sub(r"\n", " ", jaString)
response = translateAI(jaString, "", False)
response = translateAI(jaString, "")
translatedText = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3482,7 +3482,7 @@ def searchCodes(page, pbar, jobList, filename):
True,
)
else:
response = translateAI(choiceList, "Reply with the English translation of the dialogue choice.", True)
response = translateAI(choiceList, "Reply with the English translation of the dialogue choice.")
translatedTextList = response[0]
totalTokens[0] += response[1][0]
@ -3660,7 +3660,7 @@ def searchCodes(page, pbar, jobList, filename):
# 401
if len(list401) > 0:
response = translateAI(list401, "", True)
response = translateAI(list401, "")
list401TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3671,7 +3671,7 @@ def searchCodes(page, pbar, jobList, filename):
# 122
if len(list122) > 0:
response = translateAI(list122, "Keep your translation as brief as possible", True)
response = translateAI(list122, "Keep your translation as brief as possible")
list122TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3685,7 +3685,7 @@ def searchCodes(page, pbar, jobList, filename):
# 355/655
if len(list355655) > 0:
response = translateAI(list355655, textHistory, True)
response = translateAI(list355655, textHistory)
list355655TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3696,7 +3696,7 @@ def searchCodes(page, pbar, jobList, filename):
# 108
if len(list108) > 0:
response = translateAI(list108, "This text is a label. Use title capitalization and keep it brief.", True)
response = translateAI(list108, "This text is a label. Use title capitalization and keep it brief.")
list108TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3707,7 +3707,7 @@ def searchCodes(page, pbar, jobList, filename):
# 356
if len(list356) > 0:
response = translateAI(list356, textHistory, True)
response = translateAI(list356, textHistory)
list356TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3718,7 +3718,7 @@ def searchCodes(page, pbar, jobList, filename):
# 357
if len(list357) > 0:
response = translateAI(list357, textHistory, True)
response = translateAI(list357, textHistory)
list357TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3729,7 +3729,7 @@ def searchCodes(page, pbar, jobList, filename):
# 657
if len(list657) > 0:
response = translateAI(list657, textHistory, True)
response = translateAI(list657, textHistory)
list657TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3740,7 +3740,7 @@ def searchCodes(page, pbar, jobList, filename):
# 408
if len(list408) > 0:
response = translateAI(list408, "", True)
response = translateAI(list408, "")
list408TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3752,7 +3752,7 @@ def searchCodes(page, pbar, jobList, filename):
# 324
if len(list324) > 0:
# Generic short-text translation for parameter index 1
response = translateAI(list324, "Reply with only the " + LANGUAGE + " translation of the text.", True)
response = translateAI(list324, "Reply with only the " + LANGUAGE + " translation of the text.")
list324TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3764,7 +3764,7 @@ def searchCodes(page, pbar, jobList, filename):
# 325
if len(list325) > 0:
# Use same short-text speaker-style translation as other name fields
response = translateAI(list325, "Reply with the " + LANGUAGE + " translation of the NPC name.", True)
response = translateAI(list325, "Reply with the " + LANGUAGE + " translation of the NPC name.")
list325TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3911,7 +3911,7 @@ def searchSS(state, pbar):
# --- Batch translate all notes ---
translatedNotesBatch = []
if notesBatch:
response = translateAI(notesBatch, f"Reply with only the {LANGUAGE} translation of the note text.", True)
response = translateAI(notesBatch, f"Reply with only the {LANGUAGE} translation of the note text.")
translatedNotesBatch = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -3998,7 +3998,7 @@ def searchSystem(data, pbar):
term_indices.append(i)
if term_values:
response = translateAI(term_values, context, False)
response = translateAI(term_values, context)
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
tl_list = response[0]
@ -4327,7 +4327,7 @@ def resetActorMapCache():
_ACTOR_MAP_CACHE = None
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history, history_ctx=None):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
@ -4391,7 +4391,6 @@ def translateAI(text, history, fullPromptFlag):
result = sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=tl_filename,
pbar=PBAR,

View file

@ -876,37 +876,37 @@ def translatePlugin(data, pbar, filename, translatedList):
# Quest
if len(questList) > 0:
# Quest Name
response = translateAI(questList[0], "Quest Name", True)
response = translateAI(questList[0], "Quest Name")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
questName = response[0]
# Quest Client
response = translateAI(questList[1], "Quest Client", True)
response = translateAI(questList[1], "Quest Client")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
questClient = response[0]
# Quest Location
response = translateAI(questList[2], "Quest Location", True)
response = translateAI(questList[2], "Quest Location")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
questLocation = response[0]
# Quest Target
response = translateAI(questList[3], "Quest Location", True)
response = translateAI(questList[3], "Quest Location")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
questTarget = response[0]
# Quest Summary
response = translateAI(questList[4], "Quest Summary", True)
response = translateAI(questList[4], "Quest Summary")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
questSummary = response[0]
# Quest Goal 1
response = translateAI(questList[5], "Quest Goal", True)
response = translateAI(questList[5], "Quest Goal")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
questGoal1 = response[0]
@ -933,7 +933,7 @@ def translatePlugin(data, pbar, filename, translatedList):
# Custom
if custom:
# TL
response = translateAI(custom, "Relic Name", True)
response = translateAI(custom, "Relic Name")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
customResponse = response[0]
@ -959,7 +959,7 @@ def translatePlugin(data, pbar, filename, translatedList):
if sceneMenuText:
# TL
response = translateAI(sceneMenuText, "Menu Item", True)
response = translateAI(sceneMenuText, "Menu Item")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
sceneMenuTextResponse = response[0]
@ -978,7 +978,7 @@ def translatePlugin(data, pbar, filename, translatedList):
# SceneCustomMenu CommonHelpText
if sceneMenuCommonHelpText:
# TL
response = translateAI(sceneMenuCommonHelpText, "Menu Help Text", True)
response = translateAI(sceneMenuCommonHelpText, "Menu Help Text")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
sceneMenuCommonHelpTextResponse = response[0]
@ -997,7 +997,7 @@ def translatePlugin(data, pbar, filename, translatedList):
# SceneCustomMenu HelpText
if sceneMenuHelpText:
# TL
response = translateAI(sceneMenuHelpText, "Menu Help Text", True)
response = translateAI(sceneMenuHelpText, "Menu Help Text")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
sceneMenuHelpTextResponse = response[0]
@ -1016,7 +1016,7 @@ def translatePlugin(data, pbar, filename, translatedList):
# DrawTextEx - Brace-delimited labels (tracker section headers and field labels)
if sceneMenuDrawText:
# TL
response = translateAI(sceneMenuDrawText, "Status Tracker Label", True)
response = translateAI(sceneMenuDrawText, "Status Tracker Label")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
sceneMenuDrawTextResponse = response[0]
@ -1035,7 +1035,7 @@ def translatePlugin(data, pbar, filename, translatedList):
# DrawTextEx - Stat labels (e.g., 攻撃力, 魔力, etc.)
if sceneMenuStatLabel:
# TL
response = translateAI(sceneMenuStatLabel, "Character Stat Name", True)
response = translateAI(sceneMenuStatLabel, "Character Stat Name")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
sceneMenuStatLabelResponse = response[0]
@ -1054,7 +1054,7 @@ def translatePlugin(data, pbar, filename, translatedList):
# NUUN_SaveScreen ParamName
if saveParamName:
# TL
response = translateAI(saveParamName, "Save Screen Label", True)
response = translateAI(saveParamName, "Save Screen Label")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
saveParamNameResponse = response[0]
@ -1113,7 +1113,7 @@ def getSpeaker(speaker):
return response
return [speaker, [0, 0]]
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
@ -1127,7 +1127,6 @@ def translateAI(text, history, fullPromptFlag):
return sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=FILENAME,
pbar=PBAR,

View file

@ -2231,7 +2231,7 @@ def getSpeaker(speaker):
return response
def translateAI(text, history, fullPromptFlag, filename_param=None, pbar_param=None):
def translateAI(text, history):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
@ -2239,7 +2239,6 @@ def translateAI(text, history, fullPromptFlag, filename_param=None, pbar_param=N
Args:
text: Text to translate (can be string or list)
history: History/context for the translation
fullPromptFlag: Whether to use the full prompt with vocab
Returns:
List containing [translated text, [input tokens, output tokens]]
@ -2253,10 +2252,9 @@ def translateAI(text, history, fullPromptFlag, filename_param=None, pbar_param=N
return sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=(filename_param if filename_param is not None else FILENAME),
pbar=(pbar_param if pbar_param is not None else PBAR),
filename=FILENAME,
pbar=PBAR,
lock=LOCK,
mismatchList=MISMATCH
)

View file

@ -275,7 +275,7 @@ def translateTxt(data, filename, translatedList):
if stringList:
PBAR.total = len(stringList)
PBAR.refresh()
response = translateAI(stringList, "Reply with the English Translation", True)
response = translateAI(stringList, "Reply with the English Translation")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
stringListTL = response[0]
@ -288,7 +288,7 @@ def translateTxt(data, filename, translatedList):
# Choice List
if choiceList:
response = translateAI(choiceList, "Reply with the English TL of the Dialogue Choice", True)
response = translateAI(choiceList, "Reply with the English TL of the Dialogue Choice")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
choiceListTL = response[0]
@ -341,7 +341,7 @@ def getSpeaker(speaker):
return response
return [speaker, [0, 0]]
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
@ -355,7 +355,6 @@ def translateAI(text, history, fullPromptFlag):
return sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=FILENAME,
pbar=PBAR,

View file

@ -366,7 +366,7 @@ def translateTyrano(data, filename, translatedList):
if stringList:
PBAR.total = len(stringList)
PBAR.refresh()
response = translateAI(stringList, "Reply with the English Translation", True)
response = translateAI(stringList, "Reply with the English Translation")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
stringListTL = response[0]
@ -379,7 +379,7 @@ def translateTyrano(data, filename, translatedList):
# Choice List
if choiceList:
response = translateAI(choiceList, "Reply with the English TL of the Dialogue Choice", True)
response = translateAI(choiceList, "Reply with the English TL of the Dialogue Choice")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
choiceListTL = response[0]
@ -435,7 +435,7 @@ def getSpeaker(speaker):
return response
return [speaker, [0, 0]]
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
@ -449,7 +449,6 @@ def translateAI(text, history, fullPromptFlag):
return sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=FILENAME,
pbar=PBAR,

View file

@ -277,7 +277,7 @@ def translateUnity(data, pbar, filename, translatedList):
pbar.refresh()
# Translate
response = translateAI(stringList, "", True)
response = translateAI(stringList, "")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
translatedList = response[0]
@ -331,7 +331,7 @@ def getSpeaker(speaker):
return response
return [speaker, [0, 0]]
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
@ -345,7 +345,6 @@ def translateAI(text, history, fullPromptFlag):
return sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=FILENAME,
pbar=PBAR,

View file

@ -571,7 +571,7 @@ def searchCodes(events, pbar, jobList, filename):
# Translate Question
question = codeList[i]['stringArgs'][2]
response = translateAI(question, "Reply with the {LANGUAGE} translation", False)
response = translateAI(question, "Reply with the {LANGUAGE} translation")
translatedText = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -582,9 +582,9 @@ def searchCodes(events, pbar, jobList, filename):
# Translate Choices
if 'jaString' in locals() and jaString:
response = translateAI(choiceList, jaString, True)
response = translateAI(choiceList, jaString)
else:
response = translateAI(choiceList, f"Reply with the {LANGUAGE} translation of the dialogue choice", True)
response = translateAI(choiceList, f"Reply with the {LANGUAGE} translation of the dialogue choice")
choiceListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -735,7 +735,7 @@ def searchCodes(events, pbar, jobList, filename):
if len(stringList) > 0:
pbar.total = len(stringList)
pbar.refresh()
response = translateAI(stringList, textHistory, True)
response = translateAI(stringList, textHistory)
stringListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -750,7 +750,7 @@ def searchCodes(events, pbar, jobList, filename):
if len(list210) > 0:
pbar.total = len(list210)
pbar.refresh()
response = translateAI(list210, textHistory, True)
response = translateAI(list210, textHistory)
list210TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -765,7 +765,7 @@ def searchCodes(events, pbar, jobList, filename):
if len(list250) > 0:
pbar.total = len(list250)
pbar.refresh()
response = translateAI(list250, textHistory, True)
response = translateAI(list250, textHistory)
list250TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -780,7 +780,7 @@ def searchCodes(events, pbar, jobList, filename):
if len(list300) > 0:
pbar.total = len(list300)
pbar.refresh()
response = translateAI(list300, textHistory, True)
response = translateAI(list300, textHistory)
list300TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -820,7 +820,7 @@ def searchCodes(events, pbar, jobList, filename):
if len(list122) > 0:
pbar.total = len(list122)
pbar.refresh()
response = translateAI(list122, textHistory, True)
response = translateAI(list122, textHistory)
list122TL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -2096,17 +2096,17 @@ def searchDB(events, pbar, jobList, filename):
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 1
response = translateAI(npcList[1], "Reply with only the " + LANGUAGE + " translation", True)
response = translateAI(npcList[1], "Reply with only the " + LANGUAGE + " translation")
descListTL1 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 2
response = translateAI(npcList[2], "Reply with only the " + LANGUAGE + " translation", True)
response = translateAI(npcList[2], "Reply with only the " + LANGUAGE + " translation")
descListTL2 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 3
response = translateAI(npcList[3], "Reply with only the " + LANGUAGE + " translation", True)
response = translateAI(npcList[3], "Reply with only the " + LANGUAGE + " translation")
descListTL3 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -2227,22 +2227,22 @@ def searchDB(events, pbar, jobList, filename):
pbar.refresh()
# Name
response = translateAI(itemList[0], "Reply with only the " + LANGUAGE + " translation", True)
response = translateAI(itemList[0], "Reply with only the " + LANGUAGE + " translation")
nameListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 1
response = translateAI(itemList[1], "Reply with only the " + LANGUAGE + " translation", True)
response = translateAI(itemList[1], "Reply with only the " + LANGUAGE + " translation")
descListTL1 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 2
response = translateAI(itemList[2], "Reply with only the " + LANGUAGE + " translation", True)
response = translateAI(itemList[2], "Reply with only the " + LANGUAGE + " translation")
descListTL2 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 3
response = translateAI(itemList[3], "Reply with only the " + LANGUAGE + " translation", True)
response = translateAI(itemList[3], "Reply with only the " + LANGUAGE + " translation")
descListTL3 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -2280,7 +2280,7 @@ def searchDB(events, pbar, jobList, filename):
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 1
response = translateAI(armorList[1], "Reply with only the " + LANGUAGE + " translation", True)
response = translateAI(armorList[1], "Reply with only the " + LANGUAGE + " translation")
descListTL1 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -2313,7 +2313,7 @@ def searchDB(events, pbar, jobList, filename):
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 1
response = translateAI(enemyList[1], "Reply with only the " + LANGUAGE + " translation", True)
response = translateAI(enemyList[1], "Reply with only the " + LANGUAGE + " translation")
descListTL1 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -2346,12 +2346,12 @@ def searchDB(events, pbar, jobList, filename):
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 1
response = translateAI(weaponsList[1], "", True)
response = translateAI(weaponsList[1], "")
descListTL1 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
# Desc 2
response = translateAI(weaponsList[2], "", True)
response = translateAI(weaponsList[2], "")
descListTL2 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -2466,7 +2466,7 @@ def searchDB(events, pbar, jobList, filename):
totalTokens[1] += response[1][1]
# Desc 1
response = translateAI(stateList[1], "", True)
response = translateAI(stateList[1], "")
descListTL1 = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -2577,7 +2577,7 @@ def searchDB(events, pbar, jobList, filename):
pbar.refresh()
# Name
response = translateAI(dbNameList[0], "Reply with only the " + LANGUAGE + " translation", True)
response = translateAI(dbNameList[0], "Reply with only the " + LANGUAGE + " translation")
nameListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -2601,7 +2601,7 @@ def searchDB(events, pbar, jobList, filename):
pbar.refresh()
# Name
response = translateAI(dbValueList[0], "Reply with only the " + LANGUAGE + " translation", True)
response = translateAI(dbValueList[0], "Reply with only the " + LANGUAGE + " translation")
valueListTL = response[0]
totalTokens[0] += response[1][0]
totalTokens[1] += response[1][1]
@ -2677,7 +2677,7 @@ def getSpeaker(speaker):
return response
return [speaker, [0, 0]]
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history, history_ctx=None):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
@ -2691,7 +2691,6 @@ def translateAI(text, history, fullPromptFlag):
return sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=FILENAME,
pbar=PBAR,

View file

@ -258,7 +258,7 @@ def translateWOLF(data, translatedList, pbar, filename):
i += 1
# Translate
response = translateAI(choiceList, "This will be a dialogue option", True)
response = translateAI(choiceList, "This will be a dialogue option")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
choiceListTL = response[0]
@ -344,7 +344,7 @@ def translateWOLF(data, translatedList, pbar, filename):
pbar.refresh()
# Translate
response = translateAI(stringList, "", True)
response = translateAI(stringList, "")
tokens[0] += response[1][0]
tokens[1] += response[1][1]
translatedList = response[0]
@ -398,7 +398,7 @@ def getSpeaker(speaker):
return response
return [speaker, [0, 0]]
def translateAI(text, history, fullPromptFlag):
def translateAI(text, history, history_ctx=None):
"""
Legacy wrapper function for the new shared translation utility.
This maintains compatibility with existing code while using the new shared implementation.
@ -412,7 +412,6 @@ def translateAI(text, history, fullPromptFlag):
return sharedtranslateAI(
text=text,
history=history,
fullPromptFlag=fullPromptFlag,
config=TRANSLATION_CONFIG,
filename=FILENAME,
pbar=PBAR,

View file

@ -2,7 +2,7 @@ You are an expert Eroge game translator and localizer who translates Japanese te
You will be translating erotic and sexual content. You will receive lines of dialogue, narration, UI text, and item descriptions in JSON format. Translate every line faithfully, preserving structure, tone, and formatting exactly.
---
--
## Core Rules

View file

@ -702,7 +702,7 @@ def buildMatchedVocabText(vocabPairs, subbedText, history=None):
_BASE_VOCAB_SEPARATOR = "# ── Base Vocabulary" # Prefix of the separator line written by _save_vocab
def createContext(config, fullPromptFlag, subbedText, formatType, history=None):
def createContext(config, subbedText, formatType, history=None):
"""Create system and user messages for translation.
Returns (static_system, vocab_text, user) so that callers can keep the
@ -743,19 +743,7 @@ def createContext(config, fullPromptFlag, subbedText, formatType, history=None):
matchedVocabText = buildMatchedVocabText(non_char_pairs, subbedText, history)
if fullPromptFlag:
static_system = config.prompt.replace("English", config.language)
else:
static_system = f"""\
You are an expert Eroge Game translator who translates Japanese text to {config.language}.
Output ONLY the {config.language} translation in the following format: `Translation: <{config.language.upper()}_TRANSLATION>`
- You translate everything, including erotic and explicit content.
- '# Game Characters' - Character entries listing name, gender, role, and speech register notes. Use ALL fields: apply the correct English name, resolve gendered pronouns, and match each character's stated speech register and personality in their dialogue.
- All text in your response must be in {config.language} even if it is hard to translate.
- Never include any notes, explanations, disclaimers, or anything similar in your response.
- Maintain any spacing in the translation.
- `...` can be a part of the dialogue. Translate it as it is.
"""
static_system = config.prompt.replace("English", config.language)
# Append character glossary to the stable system prompt so it is cached
if char_lines:
@ -1252,19 +1240,23 @@ def calculateCost(inputTokens, outputTokens, model):
return accurate
# Non-Claude, estimate mode, or no accurate data: naive calculation.
# For Claude models in estimate mode, apply an assumed cache hit rate so the
# estimate reflects the real-world prompt-caching discount.
# The rate defaults to 0.9 (90 % cache reads) and can be overridden with the
# For Claude models, use the accumulated static_system token count (the portion
# that is always cache-written at the 1hr TTL rate = 2x input rate).
# Remaining tokens are billed at the regular input rate.
pricing = getPricingConfig(model)
_is_claude_naive = model and any(x in model.lower() for x in ("claude", "sonnet", "haiku", "opus"))
if _is_claude_naive:
try:
cache_rate = float(os.getenv("estimate_cache_rate", "0.7"))
cache_rate = max(0.0, min(1.0, cache_rate))
except (TypeError, ValueError):
cache_rate = 0.9
effective_input_multiplier = cache_rate * 0.10 + (1.0 - cache_rate)
inputCost = (inputTokens / 1_000_000) * pricing["inputAPICost"] * effective_input_multiplier
static_tok = getattr(_thread_local, 'estimate_static_tokens', 0)
regular_tok = getattr(_thread_local, 'estimate_regular_tokens', 0)
batch_count = max(1, getattr(_thread_local, 'estimate_batch_count', 1))
_thread_local.estimate_static_tokens = 0
_thread_local.estimate_regular_tokens = 0
_thread_local.estimate_batch_count = 0
# Exact model: 1 cache write (2x) + (N-1) cache reads (0.10x) + regular at 1x
write_cost = (static_tok / 1_000_000) * pricing["inputAPICost"] * 2.0
read_cost = ((batch_count - 1) * static_tok / 1_000_000) * pricing["inputAPICost"] * 0.10
regular_cost = (regular_tok / 1_000_000) * pricing["inputAPICost"]
inputCost = write_cost + read_cost + regular_cost
else:
inputCost = (inputTokens / 1_000_000) * pricing["inputAPICost"]
outputCost = (outputTokens / 1_000_000) * pricing["outputAPICost"]
@ -1293,7 +1285,7 @@ def countTokens(system, user, history):
@retry(exceptions=Exception, tries=5, delay=5)
def translateAI(text, history, fullPromptFlag, config, filename=None, pbar=None, lock=None, mismatchList=None):
def translateAI(text, history, config, filename=None, pbar=None, lock=None, mismatchList=None):
"""
Main translation entry point used by all modules.
@ -1464,13 +1456,39 @@ def translateAI(text, history, fullPromptFlag, config, filename=None, pbar=None,
# Create context — static_system is the stable prompt.txt content;
# vocab_text is the per-batch matched vocabulary (dynamic).
static_system, vocab_text, user = createContext(config, fullPromptFlag, subbedT, formatType, history)
static_system, vocab_text, user = createContext(config, subbedT, formatType, history)
# Calculate estimate if in estimate mode
if config.estimateMode:
estimate = countTokens(static_system + vocab_text, user, history)
totalTokens[0] += estimate[0]
totalTokens[1] += estimate[1]
# Track exact cache write size (static_system, constant across batches)
# and accumulate non-cached (vocab + user + history) tokens per batch.
_is_claude_est = config.model and any(x in config.model.lower() for x in ("claude", "sonnet", "haiku", "opus"))
if _is_claude_est:
# Use Anthropic's count_tokens API once to get the exact cached token count.
# Only called on the first batch; result reused for all subsequent batches.
if not getattr(_thread_local, 'estimate_static_tokens', 0):
try:
_ant_count_client = anthropic.Anthropic(api_key=openai.api_key)
backtick = chr(96) * 3
_sys_block = [{"type": "text", "text": backtick + "\n" + static_system + "\n" + backtick, "cache_control": {"type": "ephemeral", "ttl": "1h"}}]
_count_resp = _ant_count_client.beta.messages.count_tokens(
betas=["token-counting-2024-11-01"],
model=config.model,
system=_sys_block,
messages=[{"role": "user", "content": "x"}]
)
_thread_local.estimate_static_tokens = _count_resp.input_tokens
except Exception:
# Fallback to tiktoken if count_tokens fails
enc = tiktoken.encoding_for_model("gpt-4")
_thread_local.estimate_static_tokens = len(enc.encode(static_system))
regular_tok = max(0, estimate[0] - getattr(_thread_local, 'estimate_static_tokens', 0))
_thread_local.estimate_regular_tokens = getattr(_thread_local, 'estimate_regular_tokens', 0) + regular_tok
_thread_local.estimate_batch_count = getattr(_thread_local, 'estimate_batch_count', 0) + 1
# Cache the payload with original text as placeholder for future estimates
if isinstance(tItem, list):
@ -1488,24 +1506,28 @@ def translateAI(text, history, fullPromptFlag, config, filename=None, pbar=None,
for attempt in range(max_retries + 1):
is_valid = True
# On retries, add a note to the system prompt
current_system = static_system
# On retries, prepend the correction note to the USER message so the
# cached static_system block is never modified (avoids cache busting).
current_user = user
if attempt > 0:
current_system += f"\n\nIMPORTANT: Your previous attempt was incorrect or incomplete. Please ensure:\n"
current_system += f"1. The entire output is translated to {config.language} with no untranslated characters\n"
current_system += f"2. The JSON structure is correct with NO EMPTY or near-empty translations\n"
current_system += f" - Every line with Japanese text MUST be fully translated\n"
current_system += f" - Do NOT leave translations empty (\"\") or as single punctuation marks (\":\")\n"
current_system += f"3. ALL placeholders (like __PROTECTED_0__, __PROTECTED_1__, etc.) are preserved EXACTLY as they appear in the input\n"
current_system += f" - Do not modify, translate, or remove any __PROTECTED_N__ placeholders\n"
current_system += f" - Keep them in the exact same position in your translation"
retry_note = (
f"IMPORTANT: Your previous attempt was incorrect or incomplete. Please ensure:\n"
f"1. The entire output is translated to {config.language} with no untranslated characters\n"
f"2. The JSON structure is correct with NO EMPTY or near-empty translations\n"
f" - Every line with Japanese text MUST be fully translated\n"
f" - Do NOT leave translations empty (\"\") or as single punctuation marks (\":\")\n"
f"3. ALL placeholders (like __PROTECTED_0__, __PROTECTED_1__, etc.) are preserved EXACTLY as they appear in the input\n"
f" - Do not modify, translate, or remove any __PROTECTED_N__ placeholders\n"
f" - Keep them in the exact same position in your translation\n\n"
)
current_user = retry_note + user
if pbar:
pbar.write(f"Retrying translation... (Attempt {attempt + 1}/{max_retries + 1})")
# Translate
try:
response = translateText(current_system, user, history, 0.05, formatType, config.model, numLines, vocab_text=vocab_text)
response = translateText(static_system, current_user, history, 0.05, formatType, config.model, numLines, vocab_text=vocab_text)
except Exception as api_err:
err_msg = f"[API_ERROR] {api_err}"
# Print to stdout so the GUI captures it immediately
@ -1593,7 +1615,7 @@ def translateAI(text, history, fullPromptFlag, config, filename=None, pbar=None,
# --- Debug Token Logging ---
if DEBUG_LOGGING:
print(f"\nInput ({response.usage.prompt_tokens} tokens):")
print(f"{current_system}\n{user}")
print(f"{static_system}\n{current_user}")
print(f"\nOutput ({response.usage.completion_tokens} tokens):")
print(f"{translatedText}")