Make sure all prompts are static
This commit is contained in:
parent
e1c903ee42
commit
7292a6c3c7
21 changed files with 203 additions and 199 deletions
10
.env.example
10
.env.example
|
|
@ -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
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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}")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue