{"version":3,"sources":["../node_modules/tsup/assets/cjs_shims.js","../src/services/ai/openai.ts","../src/services/ai/anthropic.ts","../src/config/pricing.ts","../src/services/ai/index.ts","../src/utils/logger.ts","../src/utils/xml.ts","../src/utils/continuation.ts","../src/utils/filesystem.ts","../src/utils/formatters.ts","../src/utils/metrics.ts","../src/utils/constants.ts","../src/utils/index.ts","../src/prompts/translation.ts","../src/core/TranslationWorkflow.ts","../src/index.ts"],"names":["OpenAiProvider","constructor","apiKey","client","OpenAI","process","env","OPENAI_API_KEY","getProviderName","isAvailable","generateResponse","messages","options","modelName","isReasoningModel","startsWith","performance","now","callResponsesApi","callChatCompletionsApi","combinedPrompt","role","content","slice","map","m","join","startTime","response","responses","create","model","input","reasoning","effort","reasoningEffort","max_output_tokens","maxOutputTokens","endTime","output_text","inputTokens","usage","input_tokens","outputTokens","output_tokens","duration","completion","chat","completions","temperature","max_tokens","choices","message","prompt_tokens","completion_tokens","AnthropicProvider","Anthropic","ANTHROPIC_API_KEY","error","console","warn","Error","formattedMessages","systemMessage","startIndex","i","length","msg","push","system","text","status","type","pricingData","Map","inputCostPerMillion","outputCostPerMillion","AiService","openAiApiKey","anthropicApiKey","openAiProvider","anthropicProvider","getAvailableProviders","openai","anthropic","supportedOpenAiModels","supportedAnthropicModels","isAnthropicModel","includes","isSupported","some","calculateCost","pricing","get","baseModelMatch","match","baseModel","inputCost","outputCost","totalCost","Logger","verbose","spinner","ora","log","logHeader","title","chalk","bgBlue","white","info","blue","success","green","yellow","red","startSpinner","start","succeedSpinner","succeed","warnSpinner","failSpinner","fail","logMetrics","label","metrics","cyan","Object","entries","forEach","key","value","XmlProcessor","parser","builder","XMLParser","ignoreAttributes","preserveOrder","XMLBuilder","format","extractTagContent","tagName","regex","RegExp","exec","trim","openTagRegex","openTagMatch","extractAllTags","pattern","matches","contentMatch","parseXml","xmlString","parse","buildXml","obj","build","wrapInTags","checkTranslationCompletion","sourceText","translationText","response_format","result","JSON","continue","targetLastLine","sourceLine","backupPartialTranslation","filePath","backupDir","existsSync","backupDirectory","dirname","fs","mkdirSync","recursive","filename","basename","timestamp","Date","toISOString","replace","backupPath","copyFileSync","combineTranslation","partialTranslation","continuationText","continued","cleanContinuationText","cleanedPartialTranslation","removeUnpairedXmlTags","removeContinuationMarkers","matchResult","findBestMatchPoint","matchedText","matchIndex","textBefore","substring","continuationAfterMatch","matchStartInContinuation","indexOf","combinedText","endsWith","cleaned","continuedMatch","openingTags","tagsToRemove","openTag","closeTag","pop","tag","tagMatch","markers","marker","continuation","exactMatch","lastIndexOf","minMatchLength","Math","min","bestMatch","bestMatchIndex","endChunk","max","startChunk","endPart","paragraphs","split","lastParagraph","paragraphIndex","createSimpleContinuationPrompt","ensureDirectoryExists","dirPath","saveJson","data","writeFileSync","stringify","loadJson","defaultValue","readFileSync","saveText","loadText","findLatestFile","directory","fileNames","fileName","findFilesInDirectory","files","readdirSync","filter","file","test","formatTime","timeInMinutes","round","minutes","floor","seconds","formatDuration","remainingSeconds","hours","createProgressBar","ratio","validSource","width","filled","empty","bar","repeat","calculateMetrics","isSourceText","sourceMetrics","sourceWordCount","targetWordCount","sourceCharCount","targetCharCount","estimatedReadingTime","charCount","wordCount","word","readingTime","sourceW","sourceC","calculateMetricsForLanguage","language","effectiveLanguage","toLowerCase","MODEL_CONTEXT_LIMITS","default","prompts","targetLanguage","sourceLanguage","customInstructions","currentStep","systemPrompt","initialAnalysis","expressionExploration","toneAndCulturalDiscussion","titleAndInspirationExploration","firstTranslationAttempt","selfCritiqueAndRefinement","previousTranslation","furtherRefinement","finalTranslation","externalReviewSystem","externalReviewUser","translation","applyExternalFeedback","externalReview","continuationTranslation","continuationPoint","TranslationWorkflow","config","conversation","intermediatesDir","totalTokens","totalInputTokens","totalOutputTokens","estimatedCost","xmlProcessor","translationSteps","outputFiles","stepCounter","conversationJsonPath","conversationTextPath","metricsPath","translationMetrics","finalOutputPath","aiService","logger","spinnerStartTime","spinnerInterval","continuationAttempts","previousTranslationLength","minimumMeaningfulProgress","previousSourceLine","outputDir","originalFilename","originalExtension","tryResume","initializeNewConversation","historyData","metadata","step","lastLabel","stepKey","l","toUpperCase","stepNames","keys","sort","a","b","numA","parseInt","numB","stepNum","metricsData","source","set","saveConversationHistory","execute","inputPath","displaySourceMetrics","latestTranslationContent","startSpinnerWithTimer","initialAnalysisPrompt","analysisResponse","callAiService","analysisContent","analysisPath","expressionExplorationPrompt","expressionResponse","expressionContent","expressionPath","culturalAdaptationPrompt","culturalResponse","culturalContent","culturalPath","titleInspirationPrompt","titleResponse","titleContent","titlePath","firstTranslationPrompt","translationResponse","translationPath","translationContent","extractAndContinueTagContent","prevTranslationPath","prevTranslation","selfCritiquePrompt","critiqueResponse","improvedPath","improvedTranslation","secondRefinementPrompt","secondRefineResponse","furtherImprovedPath","furtherImprovedTranslation","estimatedSourceTokens","ceil","estimatedTranslationTokens","modelContextLimit","currentConversationTokens","reduce","total","resetThreshold","wouldExceedLimit","toLocaleString","finalTranslationPrompt","finalResponse","finalPath","externalReviewContent","skipExternalReview","finalTranslationPath","externalReviewPrompt","externalResponse","reviewPath","estimatedReviewTokens","refinedFinalTranslation","refinedPath","finalRefinementPrompt","refinedResponse","saveTranslationMetrics","toFixed","stopSpinner","saveLatestTranslationOnError","conversationWithMetadata","readableHistory","index","metricsObject","prompt","retryCount","isExternalReview","currentStepLabel","currentStepKey","stepName","unshift","manageConversationContext","updateCost","tps","dim","maxRetries","isContextLengthError","code","firstUserMessage","find","latestUserMessage","retryDelay","Promise","resolve","setTimeout","costResult","displayComparisonWithSource","wordCountRatio","charCountRatio","magenta","ratioValue","wordBar","translationFileOrder","latestFileFound","saveError","clearSpinnerInterval","setInterval","elapsedSeconds","clearInterval","stop","totalEstimatedTokens","prefixMap","prefix","limit","warningThreshold","tokenThreshold","usagePercentage","recentMessages","newEstimate","handleTranslationContinuation","forceCheck","completionCheck","needsContinuation","sourceLines","midpoint","simpleContinuationPrompt","continuationResponse","combinedTranslation","secondCheck","outputPath","closeTagRegex","hasOpenTag","hasCloseTag","debugPath","extractedContent","openTagIndex","possibleStart","possibleEnd","cleanTranslationContent","continuedContent","cleanedContent","completedContent","finalCleanedContent","contentWithoutTags","getFinalOutputPath","displayTokenEstimation","tokens","translate","cwd","undefined","workflow"],"mappings":"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","file":"index.cjs","sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () =>\n  typeof document === 'undefined'\n    ? new URL(`file:${__filename}`).href\n    : (document.currentScript && document.currentScript.src) ||\n      new URL('main.js', document.baseURI).href\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import { OpenAI } from \"openai\";\nimport { AiProvider, AiRequestOptions, AiResponse } from \".\";\nimport { ConversationMessage } from \"../../types\";\n\n/**\n * OpenAI service provider implementation\n */\nexport class OpenAiProvider implements AiProvider {\n  private client: OpenAI;\n\n  constructor(apiKey?: string) {\n    this.client = new OpenAI({\n      apiKey: apiKey || process.env.OPENAI_API_KEY,\n    });\n  }\n\n  getProviderName(): string {\n    return \"OpenAI\";\n  }\n\n  isAvailable(): boolean {\n    return !!process.env.OPENAI_API_KEY;\n  }\n\n  async generateResponse(\n    messages: ConversationMessage[],\n    options: AiRequestOptions\n  ): Promise<AiResponse> {\n    const modelName = options.modelName;\n    const isReasoningModel =\n      modelName.startsWith(\"o1\") || modelName.startsWith(\"o3\");\n\n    // Record start time for duration calculation\n    const startTime = performance.now();\n\n    if (isReasoningModel) {\n      return await this.callResponsesApi(messages, options);\n    } else {\n      return await this.callChatCompletionsApi(messages, options);\n    }\n  }\n\n  /**\n   * Call the OpenAI Responses API (for o1/o3 models)\n   */\n  private async callResponsesApi(\n    messages: ConversationMessage[],\n    options: AiRequestOptions\n  ): Promise<AiResponse> {\n    // Format input for Responses API (combine system + user prompt)\n    let combinedPrompt = \"\";\n    if (messages[0]?.role === \"system\") {\n      combinedPrompt = messages[0].content + \"\\n\\n---\\n\\n\";\n      combinedPrompt += messages\n        .slice(1)\n        .map((m) => `${m.role}: ${m.content}`)\n        .join(\"\\n\\n\");\n    } else {\n      combinedPrompt = messages\n        .map((m) => `${m.role}: ${m.content}`)\n        .join(\"\\n\\n\");\n    }\n\n    const startTime = performance.now();\n\n    const response = await this.client.responses.create({\n      model: options.modelName,\n      input: [{ role: \"user\", content: combinedPrompt }],\n      reasoning: { effort: options.reasoningEffort || \"medium\" },\n      max_output_tokens: options.maxOutputTokens,\n    });\n\n    const endTime = performance.now();\n\n    return {\n      content: response.output_text || \"\",\n      inputTokens: response.usage?.input_tokens || 0,\n      outputTokens: response.usage?.output_tokens || 0,\n      modelName: options.modelName,\n      duration: (endTime - startTime) / 1000, // convert to seconds\n    };\n  }\n\n  /**\n   * Call the OpenAI Chat Completions API (for GPT models)\n   */\n  private async callChatCompletionsApi(\n    messages: ConversationMessage[],\n    options: AiRequestOptions\n  ): Promise<AiResponse> {\n    const startTime = performance.now();\n\n    const completion = await this.client.chat.completions.create({\n      model: options.modelName,\n      messages: messages,\n      temperature: options.temperature || 0.7,\n      max_tokens: options.maxOutputTokens,\n    });\n\n    const endTime = performance.now();\n\n    return {\n      content: completion.choices[0].message.content || \"\",\n      inputTokens: completion.usage?.prompt_tokens || 0,\n      outputTokens: completion.usage?.completion_tokens || 0,\n      modelName: options.modelName,\n      duration: (endTime - startTime) / 1000, // convert to seconds\n    };\n  }\n}\n","import Anthropic from \"@anthropic-ai/sdk\";\nimport { AiProvider, AiRequestOptions, AiResponse } from \".\";\nimport { ConversationMessage } from \"../../types\";\n\n/**\n * Anthropic (Claude) service provider implementation\n */\nexport class AnthropicProvider implements AiProvider {\n  private client: Anthropic | null = null;\n\n  constructor(apiKey?: string) {\n    try {\n      this.client = new Anthropic({\n        apiKey: apiKey || process.env.ANTHROPIC_API_KEY || \"\",\n      });\n    } catch (error) {\n      console.warn(\"Failed to initialize Anthropic client:\", error);\n      this.client = null;\n    }\n  }\n\n  getProviderName(): string {\n    return \"Anthropic Claude\";\n  }\n\n  isAvailable(): boolean {\n    return !!this.client && !!process.env.ANTHROPIC_API_KEY;\n  }\n\n  async generateResponse(\n    messages: ConversationMessage[],\n    options: AiRequestOptions\n  ): Promise<AiResponse> {\n    if (!this.client) {\n      throw new Error(\"Anthropic client not initialized\");\n    }\n\n    // Format messages for Anthropic API\n    const formattedMessages: Array<{\n      role: \"user\" | \"assistant\";\n      content: string;\n    }> = [];\n\n    // Extract system message if present\n    let systemMessage: string | undefined;\n    let startIndex = 0;\n\n    if (messages[0]?.role === \"system\") {\n      systemMessage = messages[0].content;\n      startIndex = 1;\n    }\n\n    // Format remaining messages\n    for (let i = startIndex; i < messages.length; i++) {\n      const msg = messages[i];\n      formattedMessages.push({\n        role: msg.role === \"assistant\" ? \"assistant\" : \"user\",\n        content: msg.content,\n      });\n    }\n\n    const startTime = performance.now();\n\n    try {\n      // Use the standard messages.create method\n      const response = await this.client.messages.create({\n        model: options.modelName || \"claude-3-7-sonnet-latest\",\n        max_tokens: options.maxOutputTokens || 100000,\n        temperature: options.temperature || 0.7,\n        system: systemMessage,\n        messages: formattedMessages,\n      });\n\n      const endTime = performance.now();\n\n      let content = \"\";\n      if (\n        response.content &&\n        response.content.length > 0 &&\n        \"text\" in response.content[0]\n      ) {\n        content = response.content[0].text;\n      }\n\n      return {\n        content,\n        inputTokens: response.usage?.input_tokens || 0,\n        outputTokens: response.usage?.output_tokens || 0,\n        modelName: options.modelName || \"claude-3-7-sonnet-latest\",\n        duration: (endTime - startTime) / 1000,\n      };\n    } catch (error: any) {\n      console.error(\"Anthropic API error:\", error?.message || error);\n\n      // Log more detailed error information to help with debugging\n      if (error?.status) {\n        console.error(\n          `Status: ${error.status}, Type: ${error?.error?.type || \"unknown\"}`\n        );\n      }\n\n      throw error;\n    }\n  }\n}\n","import { ModelPricing } from \"../types\";\n\n/**\n * Pricing data for various AI models (cost per million tokens)\n * Note: Prices may change, verify with official documentation\n */\nexport const pricingData: Map<string, ModelPricing> = new Map([\n  // OpenAI Models\n  [\"gpt-4o\", { inputCostPerMillion: 2.5, outputCostPerMillion: 10.0 }],\n  [\"gpt-4o-mini\", { inputCostPerMillion: 0.15, outputCostPerMillion: 0.6 }],\n  [\"o1\", { inputCostPerMillion: 15.0, outputCostPerMillion: 60.0 }],\n  [\"o3-mini\", { inputCostPerMillion: 1.1, outputCostPerMillion: 4.4 }],\n  [\n    \"gpt-4.5-preview\",\n    { inputCostPerMillion: 75.0, outputCostPerMillion: 150.0 },\n  ],\n\n  // Anthropic Models\n  [\n    \"claude-3-7-sonnet-latest\",\n    { inputCostPerMillion: 3.0, outputCostPerMillion: 15.0 },\n  ],\n]);\n","import { OpenAiProvider } from \"./openai\";\nimport { AnthropicProvider } from \"./anthropic\";\nimport { ConversationMessage } from \"../../types\";\nimport { pricingData } from \"../../config/pricing\";\nimport { AiResponse, AiRequestOptions, AiProvider } from \"./interfaces\";\n\n// Re-export the interfaces\nexport type { AiResponse, AiRequestOptions, AiProvider };\n\n/**\n * Cost calculation result\n */\nexport interface CostResult {\n  inputCost: number;\n  outputCost: number;\n  totalCost: number;\n}\n\n/**\n * Main AI service that orchestrates different providers\n */\nexport class AiService {\n  private openAiProvider: OpenAiProvider;\n  private anthropicProvider: AnthropicProvider;\n\n  constructor(openAiApiKey?: string, anthropicApiKey?: string) {\n    this.openAiProvider = new OpenAiProvider(openAiApiKey);\n    this.anthropicProvider = new AnthropicProvider(anthropicApiKey);\n  }\n\n  /**\n   * Check which providers are available\n   */\n  getAvailableProviders(): { openai: boolean; anthropic: boolean } {\n    return {\n      openai: this.openAiProvider.isAvailable(),\n      anthropic: this.anthropicProvider.isAvailable(),\n    };\n  }\n\n  /**\n   * Generate a response from a conversation history using the appropriate provider\n   */\n  async generateResponse(\n    messages: ConversationMessage[],\n    options: AiRequestOptions\n  ): Promise<AiResponse> {\n    const modelName = options.modelName;\n\n    // Define supported models\n    const supportedOpenAiModels = [\n      \"gpt-4o\",\n      \"gpt-4o-mini\",\n      \"o1\",\n      \"o3-mini\",\n      \"gpt-4.5-preview\",\n    ];\n\n    const supportedAnthropicModels = [\n      \"claude-3-7-sonnet-latest\",\n      \"claude-3-7-sonnet\",\n      \"claude-3-sonnet\",\n      \"claude-3-5-sonnet\",\n    ];\n\n    const isAnthropicModel =\n      modelName.startsWith(\"claude\") ||\n      modelName.includes(\"claude-\") ||\n      modelName.includes(\"anthropic\");\n\n    // Validate model name\n    if (isAnthropicModel) {\n      // Check if it's one of our supported Claude models (or starts with one)\n      const isSupported = supportedAnthropicModels.some(\n        (model) => modelName === model || modelName.startsWith(model)\n      );\n\n      if (!isSupported) {\n        throw new Error(\n          `Unsupported Anthropic model: ${modelName}. Supported models are: ${supportedAnthropicModels.join(\n            \", \"\n          )}.`\n        );\n      }\n\n      if (!this.anthropicProvider.isAvailable()) {\n        throw new Error(\n          \"Anthropic provider not available. Please set ANTHROPIC_API_KEY environment variable.\"\n        );\n      }\n      return this.anthropicProvider.generateResponse(messages, options);\n    } else {\n      // Check if it's one of our supported OpenAI models (or starts with one)\n      const isSupported = supportedOpenAiModels.some(\n        (model) => modelName === model || modelName.startsWith(model)\n      );\n\n      if (!isSupported) {\n        throw new Error(\n          `Unsupported OpenAI model: ${modelName}. Supported models are: ${supportedOpenAiModels.join(\n            \", \"\n          )}.`\n        );\n      }\n\n      if (!this.openAiProvider.isAvailable()) {\n        throw new Error(\n          \"OpenAI provider not available. Please set OPENAI_API_KEY environment variable.\"\n        );\n      }\n      return this.openAiProvider.generateResponse(messages, options);\n    }\n  }\n\n  /**\n   * Calculate cost based on token usage\n   */\n  calculateCost(\n    model: string,\n    inputTokens: number,\n    outputTokens: number\n  ): CostResult {\n    // Attempt to find exact match first, then base model\n    let pricing = pricingData.get(model);\n\n    if (!pricing) {\n      // Try matching base model name\n      const baseModelMatch = model.match(\n        /^(gpt-4o|gpt-4o-mini|o1|o3-mini|claude-3-opus|claude-3-sonnet|claude-3-haiku|claude-3-5-sonnet|claude-3-7-sonnet)/\n      );\n      const baseModel = baseModelMatch ? baseModelMatch[0] : model;\n\n      if (baseModel !== model) {\n        pricing = pricingData.get(baseModel);\n      }\n\n      // Special handling for claude-3-7-sonnet-latest\n      if (!pricing && model.includes(\"claude-3-7-sonnet\")) {\n        pricing = pricingData.get(\"claude-3-7-sonnet-latest\");\n      }\n    }\n\n    if (!pricing) {\n      console.warn(`No pricing data found for model: ${model}`);\n      return { inputCost: 0, outputCost: 0, totalCost: 0 };\n    }\n\n    const inputCost = (inputTokens / 1_000_000) * pricing.inputCostPerMillion;\n    const outputCost =\n      (outputTokens / 1_000_000) * pricing.outputCostPerMillion;\n    const totalCost = inputCost + outputCost;\n\n    return { inputCost, outputCost, totalCost };\n  }\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\n\n/**\n * Logger utility for consistent output formatting\n */\nexport class Logger {\n  private verbose: boolean;\n  private spinner = ora();\n\n  constructor(verbose: boolean = true) {\n    this.verbose = verbose;\n  }\n\n  /**\n   * Log a message if verbose mode is enabled\n   */\n  log(message: string): void {\n    if (this.verbose) {\n      console.log(message);\n    }\n  }\n\n  /**\n   * Log a section header\n   */\n  logHeader(title: string): void {\n    if (this.verbose) {\n      console.log(\"\\n\" + chalk.bgBlue.white(` ${title} `) + \"\\n\");\n    }\n  }\n\n  /**\n   * Log an info message with blue color\n   */\n  info(message: string): void {\n    this.log(chalk.blue(message));\n  }\n\n  /**\n   * Log a success message with green color\n   */\n  success(message: string): void {\n    this.log(chalk.green(message));\n  }\n\n  /**\n   * Log a warning message with yellow color\n   */\n  warn(message: string): void {\n    this.log(chalk.yellow(message));\n  }\n\n  /**\n   * Log an error message with red color\n   */\n  error(message: string): void {\n    console.error(chalk.red(message));\n  }\n\n  /**\n   * Start a spinner with a message\n   */\n  startSpinner(message: string): void {\n    if (this.verbose) {\n      this.spinner.start(message);\n    }\n  }\n\n  /**\n   * Stop the spinner with a success message\n   */\n  succeedSpinner(message: string): void {\n    if (this.verbose) {\n      this.spinner.succeed(message);\n    }\n  }\n\n  /**\n   * Stop the spinner with a warning message\n   */\n  warnSpinner(message: string): void {\n    if (this.verbose) {\n      this.spinner.warn(message);\n    }\n  }\n\n  /**\n   * Stop the spinner with an error message\n   */\n  failSpinner(message: string): void {\n    if (this.verbose) {\n      this.spinner.fail(message);\n    }\n  }\n\n  /**\n   * Log data metrics in a formatted way\n   */\n  logMetrics(label: string, metrics: Record<string, any>): void {\n    this.log(chalk.cyan(`📏 ${label} metrics:`));\n    Object.entries(metrics).forEach(([key, value]) => {\n      this.log(chalk.cyan(`   ${key}: ${value}`));\n    });\n  }\n}\n","import { XMLParser, XMLBuilder } from \"fast-xml-parser\";\n\n/**\n * Utility for working with XML tags in translation outputs\n */\nexport class XmlProcessor {\n  private parser: XMLParser;\n  private builder: XMLBuilder;\n\n  constructor() {\n    this.parser = new XMLParser({\n      ignoreAttributes: false,\n      preserveOrder: true,\n    });\n\n    this.builder = new XMLBuilder({\n      ignoreAttributes: false,\n      format: true,\n      preserveOrder: true,\n    });\n  }\n\n  /**\n   * Extract content from XML tags\n   * @param text Text containing XML tags\n   * @param tagName Name of the tag to extract (without angle brackets)\n   * @returns The content of the tag, or empty string if tag not found\n   */\n  extractTagContent(text: string, tagName: string): string {\n    // First try with regular expression that matches complete tags\n    const regex = new RegExp(`<${tagName}>(.*?)<\\/${tagName}>`, \"s\");\n    const match = regex.exec(text);\n\n    if (match && match[1]) {\n      return match[1].trim();\n    }\n\n    // If no complete tag is found, check if there's just an opening tag (truncation case)\n    const openTagRegex = new RegExp(`<${tagName}>(.*)$`, \"s\");\n    const openTagMatch = openTagRegex.exec(text);\n\n    if (openTagMatch && openTagMatch[1]) {\n      console.warn(\n        `Warning: Found opening <${tagName}> tag but no closing tag. The response might be truncated.`\n      );\n      return openTagMatch[1].trim();\n    }\n\n    // If tag not found, return empty string\n    console.warn(`Warning: Tag <${tagName}> not found in the text.`);\n    return \"\";\n  }\n\n  /**\n   * Extract all matching tags from a text\n   * @param text Text containing XML tags\n   * @param pattern Regular expression pattern to match\n   * @returns Array of tag contents\n   */\n  extractAllTags(text: string, pattern: RegExp): string[] {\n    const matches = text.match(pattern);\n    if (!matches) return [];\n\n    // Extract the content from each tag match using capture groups\n    return matches.map((match) => {\n      // Extract just the content between tags\n      const contentMatch = match.match(/>(.*?)</);\n      if (contentMatch && contentMatch[1]) {\n        return contentMatch[1].trim();\n      }\n      return match.trim();\n    });\n  }\n\n  /**\n   * Parse XML string to object\n   */\n  parseXml(xmlString: string): any {\n    try {\n      return this.parser.parse(`<root>${xmlString}</root>`);\n    } catch (error) {\n      console.error(\"Error parsing XML:\", error);\n      return null;\n    }\n  }\n\n  /**\n   * Build XML string from object\n   */\n  buildXml(obj: any): string {\n    try {\n      return this.builder.build(obj);\n    } catch (error) {\n      console.error(\"Error building XML:\", error);\n      return \"\";\n    }\n  }\n\n  /**\n   * Wrap content in XML tags\n   */\n  wrapInTags(content: string, tagName: string): string {\n    return `<${tagName}>${content}</${tagName}>`;\n  }\n}\n","/**\n * Translation Continuation Utilities\n * Functions for detecting incomplete translations and handling continuation\n */\n\nimport { OpenAI } from \"openai\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport chalk from \"chalk\";\n\n// Type for the continuation check response from OpenAI\ninterface ContinuationCheckResponse {\n  continue: boolean;\n  targetLastLine?: string;\n  sourceLine?: string;\n}\n\n/**\n * Check if a translation is complete by using GPT-4o-mini in JSON mode\n * @param sourceText The original source text\n * @param translationText The current (potentially incomplete) translation\n * @param apiKey OpenAI API key (optional, will use env var if not provided)\n * @returns Object with continuation info or null if check failed\n */\nexport async function checkTranslationCompletion(\n  sourceText: string,\n  translationText: string,\n  verbose = false,\n  apiKey?: string\n): Promise<ContinuationCheckResponse | null> {\n  try {\n    // Initialize OpenAI client\n    const openai = new OpenAI({\n      apiKey: apiKey || process.env.OPENAI_API_KEY,\n    });\n\n    if (verbose) {\n      console.log(chalk.cyan(\"🔍 Checking if translation is complete...\"));\n    }\n\n    // Call GPT-4o-mini to check if translation is complete\n    const response = await openai.chat.completions.create({\n      model: \"gpt-4o-mini\",\n      response_format: { type: \"json_object\" },\n      messages: [\n        {\n          role: \"system\",\n          content: `You are a translation verification assistant. You'll be given a source text and its translation. Your job is to determine if the translation is complete or if it got cut off. If incomplete, identify the last line in the translation and the corresponding source line to continue from.\n\nOutput JSON with these fields:\n- continue: boolean indicating if translation needs to continue (true = incomplete)\n- targetLastLine: the last line of the translation (required if continue=true)\n- sourceLine: the corresponding source line (required if continue=true)\n\nRequirements:\n1. Match the last meaningful line in the translation and the corresponding source line\n2. Ignore differences in formatting (newlines, spaces) when determining completeness\n3. Verify that all major content sections exist in both source and translation`,\n        },\n        {\n          role: \"user\",\n          content: `Check if this translation is complete:\n\n<source_text>\n${sourceText}\n</source_text>\n\n<translation>\n${translationText}\n</translation>`,\n        },\n      ],\n      temperature: 0,\n      max_tokens: 1024,\n    });\n\n    // Parse the response\n    const content = response.choices[0]?.message?.content;\n    if (!content) {\n      throw new Error(\"No content in response from OpenAI\");\n    }\n\n    // Parse the JSON response\n    const result = JSON.parse(content) as ContinuationCheckResponse;\n\n    if (verbose) {\n      if (result.continue) {\n        console.log(chalk.yellow(\"⚠️ Translation is incomplete\"));\n        console.log(\n          chalk.yellow(`  Last translated line: \"${result.targetLastLine}\"`)\n        );\n        console.log(\n          chalk.yellow(`  Corresponding source line: \"${result.sourceLine}\"`)\n        );\n      } else {\n        console.log(chalk.green(\"✅ Translation is complete\"));\n      }\n    }\n\n    return result;\n  } catch (error) {\n    console.error(\n      chalk.red(\"❌ Error checking translation completion:\"),\n      error\n    );\n    return null;\n  }\n}\n\n/**\n * Creates a continuation prompt to ask the model to continue from a specific line\n * @param sourceText The full source text\n * @param partialTranslation The partial translation so far\n * @param targetLastLine The last line of the translation to continue from\n * @param sourceLine The corresponding source line\n * @returns A prompt for the model to continue the translation\n */\nexport function createContinuationPrompt(\n  sourceText: string,\n  partialTranslation: string,\n  targetLastLine: string,\n  sourceLine: string\n): string {\n  // Take up to 5 sentences or 500 characters from the end of the partial translation for context\n  const lastFewSentences = extractLastSentences(partialTranslation, 5, 500);\n\n  // Ensure we have at least 5 words for matching (or take the full last line if it's shorter)\n  let matchLine = targetLastLine;\n  if (\n    countWords(matchLine) < 5 &&\n    partialTranslation.length > targetLastLine.length\n  ) {\n    // Try to get more context - grab more text from the end if available\n    const lines = partialTranslation.split(\"\\n\");\n    const lastLineIndex = lines.findIndex((line) =>\n      line.includes(targetLastLine)\n    );\n\n    if (lastLineIndex > 0 && lastLineIndex < lines.length - 1) {\n      // Use this line plus the next one if available\n      matchLine = lines[lastLineIndex] + \"\\n\" + lines[lastLineIndex + 1];\n    } else if (partialTranslation.lastIndexOf(targetLastLine) !== -1) {\n      // Get more context around the target line\n      const position = partialTranslation.lastIndexOf(targetLastLine);\n      const start = Math.max(0, position - 50);\n      const end = Math.min(\n        partialTranslation.length,\n        position + targetLastLine.length + 50\n      );\n      matchLine = partialTranslation.substring(start, end);\n    }\n  }\n\n  return `I need you to continue a translation that was cut off. The full source text and the partial translation are provided.\n\n<source_text>\n${sourceText}\n</source_text>\n\n<partial_translation>\n${lastFewSentences}\n</partial_translation>\n\nThis is not the full translation. Please continue from where it left off. Your continuation should start with this text (including it for matching purposes): \"${matchLine}\"\n\nIMPORTANT:\n1. Do not include XML tags like \"<continued_translation>\" in your response.\n2. Start your response exactly with the text provided for matching.\n3. Continue the translation in the same style, tone, formatting, and language as the existing translation.\n4. Do not add notes like \"(to be continued)\" or similar markers.\n5. If there is nothing more to translate, please indicate this clearly.\n\nYour continuation will be automatically combined with the existing translation.`;\n}\n\n/**\n * Count the number of words in a string\n */\nfunction countWords(text: string): number {\n  return text.trim().split(/\\s+/).filter(Boolean).length;\n}\n\n/**\n * Extract the last N sentences from a text, up to maxChars\n */\nfunction extractLastSentences(\n  text: string,\n  sentenceCount: number,\n  maxChars: number\n): string {\n  // Handle empty text\n  if (!text || text.trim().length === 0) return \"\";\n\n  // Define sentence-ending punctuation\n  const sentenceEndingRegex = /[.!?。？！…]+/g;\n\n  // Get the last chunk of text, not exceeding maxChars\n  const lastChunk =\n    text.length <= maxChars ? text : text.substring(text.length - maxChars);\n\n  // Split the last chunk into sentences\n  const sentences = lastChunk.split(sentenceEndingRegex);\n\n  // Get the last N sentences (or fewer if there aren't that many)\n  const lastSentences = sentences.slice(\n    Math.max(0, sentences.length - sentenceCount)\n  );\n\n  // If we got a clean break at a sentence, prepend an ellipsis\n  const result = lastSentences.join(\". \").trim();\n\n  // Add ellipsis if we're not starting from the beginning of the text\n  const needsEllipsis = text.length > maxChars && !text.startsWith(result);\n\n  return needsEllipsis ? \"...\" + result : result;\n}\n\n/**\n * Saves a backup of the current partial translation before attempting to continue\n * @param filePath Path to the current translation file\n * @param backupDir Directory to store backups\n * @returns Path to the backup file or null if backup failed\n */\nexport function backupPartialTranslation(\n  filePath: string,\n  backupDir?: string\n): string | null {\n  try {\n    if (!fs.existsSync(filePath)) {\n      console.error(chalk.red(`❌ File not found: ${filePath}`));\n      return null;\n    }\n\n    // Create backup directory if it doesn't exist\n    const backupDirectory =\n      backupDir || path.join(path.dirname(filePath), \".backups\");\n    if (!fs.existsSync(backupDirectory)) {\n      fs.mkdirSync(backupDirectory, { recursive: true });\n    }\n\n    // Generate backup filename with timestamp\n    const filename = path.basename(filePath);\n    const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n    const backupPath = path.join(\n      backupDirectory,\n      `${filename}.${timestamp}.bak`\n    );\n\n    // Copy the file\n    fs.copyFileSync(filePath, backupPath);\n\n    return backupPath;\n  } catch (error) {\n    console.error(chalk.red(\"❌ Error creating backup:\"), error);\n    return null;\n  }\n}\n\n/**\n * Combines the partial translation with the continuation\n * @param partialTranslation The partial translation text\n * @param continuationText The continuation text from the model\n * @param targetLastLine The last line to match for replacement\n * @returns The combined translation or null if match failed\n */\nexport function combineTranslation(\n  partialTranslation: string,\n  continuationText: string,\n  targetLastLine: string\n): string | null {\n  try {\n    // Clean up continuation text first - remove XML tags if present\n    let continued = cleanContinuationText(continuationText);\n\n    // If no usable content after cleanup, return original\n    if (!continued || continued.trim().length === 0) {\n      console.log(\n        chalk.yellow(\"⚠️ No usable continuation content found after cleanup\")\n      );\n      return partialTranslation;\n    }\n\n    // Clean up the partial translation - remove any dangling XML tags at the end\n    let cleanedPartialTranslation = removeUnpairedXmlTags(partialTranslation);\n\n    // Also remove common \"to be continued\" markers from the end of the partial translation\n    cleanedPartialTranslation = removeContinuationMarkers(\n      cleanedPartialTranslation\n    );\n\n    // Find the best match point for continuing\n    const matchResult = findBestMatchPoint(\n      cleanedPartialTranslation,\n      continued,\n      targetLastLine\n    );\n\n    if (!matchResult) {\n      console.error(\n        chalk.red(\n          `❌ Could not find a good match point in the partial translation using: \"${targetLastLine}\"`\n        )\n      );\n      // As a fallback, just append the continuation to the end with a separator\n      console.log(chalk.yellow(\"⚠️ Falling back to simple append method\"));\n      return cleanedPartialTranslation + \"\\n\\n\" + continued;\n    }\n\n    const { matchedText, matchIndex } = matchResult;\n\n    // Get the text before the match, keeping the matched text in the original\n    const textBefore = cleanedPartialTranslation.substring(\n      0,\n      matchIndex + matchedText.length\n    );\n\n    // Extract the continuation after the matched part\n    let continuationAfterMatch = continued;\n    if (continued.includes(matchedText)) {\n      const matchStartInContinuation = continued.indexOf(matchedText);\n      continuationAfterMatch = continued.substring(\n        matchStartInContinuation + matchedText.length\n      );\n    }\n\n    // Build combined text\n    let combinedText = textBefore;\n\n    // Add a separator if needed\n    if (\n      !combinedText.endsWith(\"\\n\") &&\n      !continuationAfterMatch.startsWith(\"\\n\")\n    ) {\n      continuationAfterMatch = \"\\n\" + continuationAfterMatch;\n    }\n\n    // Append the continuation\n    combinedText += continuationAfterMatch;\n\n    console.log(\n      chalk.green(\n        `✅ Successfully combined translation (${textBefore.length} chars + ${continuationAfterMatch.length} chars)`\n      )\n    );\n\n    return combinedText;\n  } catch (error) {\n    console.error(chalk.red(\"❌ Error combining translation:\"), error);\n    return null;\n  }\n}\n\n/**\n * Clean up continuation text by removing XML tags and other artifacts\n */\nfunction cleanContinuationText(text: string): string {\n  if (!text) return \"\";\n\n  let cleaned = text;\n\n  // Extract content from <continued_translation> tags if present\n  const continuedMatch = text.match(\n    /<continued_translation>([\\s\\S]*?)<\\/continued_translation>/\n  );\n\n  if (continuedMatch && continuedMatch[1]?.trim()) {\n    cleaned = continuedMatch[1].trim();\n  } else {\n    // If no tags found, use the raw text but remove any single open/close tags\n    cleaned = text\n      .trim()\n      .replace(/<continued_translation>/g, \"\")\n      .replace(/<\\/continued_translation>/g, \"\");\n  }\n\n  // Remove any other XML-like tags that might be artifacts\n  cleaned = removeUnpairedXmlTags(cleaned);\n\n  // Remove \"to be continued\" markers\n  cleaned = removeContinuationMarkers(cleaned);\n\n  return cleaned;\n}\n\n/**\n * Remove unpaired XML tags from text (tags that are opened but not closed, or closed but not opened)\n */\nexport function removeUnpairedXmlTags(text: string): string {\n  if (!text) return \"\";\n\n  // Find all opening and closing tags\n  const openingTags: string[] = [];\n  const regex = /<([^\\/\\s>]+)[^>]*>|<\\/([^>]+)>/g;\n  let match;\n  let result = text;\n\n  // This will capture tag pairs to preserve and single tags to remove\n  const tagsToRemove: string[] = [];\n\n  // First pass - identify unpaired tags\n  while ((match = regex.exec(text)) !== null) {\n    const openTag = match[1];\n    const closeTag = match[2];\n\n    if (openTag) {\n      // This is an opening tag\n      openingTags.push(openTag);\n    } else if (closeTag) {\n      // This is a closing tag\n      if (\n        openingTags.length > 0 &&\n        openingTags[openingTags.length - 1] === closeTag\n      ) {\n        // Matched pair, pop the opening tag\n        openingTags.pop();\n      } else {\n        // Unpaired closing tag, mark for removal\n        tagsToRemove.push(`</${closeTag}>`);\n      }\n    }\n  }\n\n  // Any tags left in the openingTags array are unpaired\n  for (const tag of openingTags) {\n    // Find the actual tag with attributes in the original text\n    const openTagRegex = new RegExp(`<${tag}[^>]*>`, \"g\");\n    let tagMatch;\n    while ((tagMatch = openTagRegex.exec(text)) !== null) {\n      if (!tagsToRemove.includes(tagMatch[0])) {\n        tagsToRemove.push(tagMatch[0]);\n      }\n    }\n  }\n\n  // Remove the unpaired tags\n  for (const tag of tagsToRemove) {\n    result = result.replace(tag, \"\");\n  }\n\n  return result;\n}\n\n/**\n * Remove common \"to be continued\" markers from the end of text\n */\nexport function removeContinuationMarkers(text: string): string {\n  if (!text) return \"\";\n\n  // Common continuation markers in various languages\n  const markers = [\n    /\\(to be continued\\.?\\.?\\.?\\)$/i,\n    /\\(continued\\.?\\.?\\.?\\)$/i,\n    /\\.\\.\\.$/, // Just trailing ellipsis at the end\n    /\\(계속\\.?\\.?\\.?\\)$/i, // Korean\n    /\\(다음 편에 계속\\.?\\.?\\.?\\)$/i, // Korean\n    /\\(fortsetzung folgt\\.?\\.?\\.?\\)$/i, // German\n    /\\(continuará\\.?\\.?\\.?\\)$/i, // Spanish\n    /\\(à suivre\\.?\\.?\\.?\\)$/i, // French\n    /\\(続く\\.?\\.?\\.?\\)$/i, // Japanese\n    /\\(未完成\\.?\\.?\\.?\\)$/i, // Chinese\n    /\\(未完待续\\.?\\.?\\.?\\)$/i, // Chinese\n  ];\n\n  let cleaned = text;\n\n  // Check for and remove continuation markers at the end\n  for (const marker of markers) {\n    cleaned = cleaned.replace(marker, \"\");\n  }\n\n  return cleaned.trim();\n}\n\n/**\n * Find the best match point between a partial translation and its continuation\n * @returns Object with matched text and index, or null if no match found\n */\nfunction findBestMatchPoint(\n  partialTranslation: string,\n  continuation: string,\n  targetLastLine: string\n): { matchedText: string; matchIndex: number } | null {\n  if (!partialTranslation || !continuation) return null;\n\n  // First try to match the exact target line\n  const exactMatch = partialTranslation.lastIndexOf(targetLastLine);\n  if (exactMatch !== -1 && targetLastLine.trim().length > 0) {\n    return {\n      matchedText: targetLastLine,\n      matchIndex: exactMatch,\n    };\n  }\n\n  // If that fails, try to find the longest matching sequence between the end\n  // of the partial translation and the beginning of the continuation\n  const minMatchLength = Math.min(5, targetLastLine.length); // At least 5 chars or the entire targetLastLine\n  let bestMatch = \"\";\n  let bestMatchIndex = -1;\n\n  // Get the last 200 characters of the partial translation for matching\n  const endChunk = partialTranslation.substring(\n    Math.max(0, partialTranslation.length - 200)\n  );\n\n  // Get the first 200 characters of the continuation for matching\n  const startChunk = continuation.substring(\n    0,\n    Math.min(continuation.length, 200)\n  );\n\n  // Try finding increasingly smaller parts of the end chunk in the start chunk\n  for (let length = endChunk.length; length >= minMatchLength; length--) {\n    const endPart = endChunk.substring(endChunk.length - length);\n    if (startChunk.includes(endPart)) {\n      bestMatch = endPart;\n      bestMatchIndex = partialTranslation.lastIndexOf(endPart);\n      break;\n    }\n  }\n\n  // If we found a good match\n  if (bestMatchIndex !== -1 && bestMatch.length >= minMatchLength) {\n    return {\n      matchedText: bestMatch,\n      matchIndex: bestMatchIndex,\n    };\n  }\n\n  // Last resort - try to match the last paragraph\n  const paragraphs = partialTranslation.split(/\\n\\n+/);\n  if (paragraphs.length > 0) {\n    const lastParagraph = paragraphs[paragraphs.length - 1].trim();\n    const paragraphIndex = partialTranslation.lastIndexOf(lastParagraph);\n\n    if (paragraphIndex !== -1 && lastParagraph.length >= minMatchLength) {\n      return {\n        matchedText: lastParagraph,\n        matchIndex: paragraphIndex,\n      };\n    }\n  }\n\n  // No good match found\n  return null;\n}\n\n/**\n * Creates a simple \"please continue\" prompt that preserves the existing conversation context\n * @param targetLastLine The last line of the truncated response to continue from\n * @returns A prompt asking the model to continue from where it left off\n */\nexport function createSimpleContinuationPrompt(targetLastLine: string): string {\n  return `Your response appeared to be cut off. Please continue your translation from where you left off, starting at this point:\n\n\"${targetLastLine.trim()}\"\n\nPlease continue in the same style, tone, and approach as you were using before. Don't repeat what you've already translated - just continue from exactly where you left off.`;\n}\n","import * as fs from \"fs\";\nimport * as path from \"path\";\n\n/**\n * Utilities for file system operations\n */\n\n/**\n * Ensure a directory exists, create it if it doesn't\n */\nexport function ensureDirectoryExists(dirPath: string): void {\n  if (!fs.existsSync(dirPath)) {\n    fs.mkdirSync(dirPath, { recursive: true });\n  }\n}\n\n/**\n * Save data to a JSON file\n */\nexport function saveJson(filePath: string, data: any): void {\n  try {\n    fs.writeFileSync(filePath, JSON.stringify(data, null, 2));\n  } catch (error) {\n    console.error(`Error saving JSON to ${filePath}:`, error);\n    throw error;\n  }\n}\n\n/**\n * Load data from a JSON file\n */\nexport function loadJson<T>(filePath: string, defaultValue: T): T {\n  try {\n    if (fs.existsSync(filePath)) {\n      const data = fs.readFileSync(filePath, \"utf-8\");\n      return JSON.parse(data) as T;\n    }\n    return defaultValue;\n  } catch (error) {\n    console.error(`Error loading JSON from ${filePath}:`, error);\n    return defaultValue;\n  }\n}\n\n/**\n * Save text to a file\n */\nexport function saveText(filePath: string, text: string): void {\n  try {\n    ensureDirectoryExists(path.dirname(filePath));\n    fs.writeFileSync(filePath, text);\n  } catch (error) {\n    console.error(`Error saving text to ${filePath}:`, error);\n    throw error;\n  }\n}\n\n/**\n * Load text from a file\n */\nexport function loadText(filePath: string, defaultValue: string = \"\"): string {\n  try {\n    if (fs.existsSync(filePath)) {\n      return fs.readFileSync(filePath, \"utf-8\");\n    }\n    return defaultValue;\n  } catch (error) {\n    console.error(`Error loading text from ${filePath}:`, error);\n    return defaultValue;\n  }\n}\n\n/**\n * Find the latest file from a list of filenames in a directory\n */\nexport function findLatestFile(\n  directory: string,\n  fileNames: string[]\n): string | null {\n  for (const fileName of fileNames) {\n    const filePath = path.join(directory, fileName);\n    if (fs.existsSync(filePath)) {\n      return filePath;\n    }\n  }\n  return null;\n}\n\n/**\n * Get all files in a directory matching a pattern\n */\nexport function findFilesInDirectory(\n  directory: string,\n  pattern: RegExp\n): string[] {\n  try {\n    if (!fs.existsSync(directory)) {\n      return [];\n    }\n\n    const files = fs.readdirSync(directory);\n    return files\n      .filter((file) => pattern.test(file))\n      .map((file) => path.join(directory, file));\n  } catch (error) {\n    console.error(`Error finding files in ${directory}:`, error);\n    return [];\n  }\n}\n","/**\n * Formatting utilities for time, progress bars, and other display elements\n */\n\n/**\n * Format time in minutes and seconds\n */\nexport function formatTime(timeInMinutes: number): string {\n  if (timeInMinutes < 1) {\n    return `${Math.round(timeInMinutes * 60)} seconds`;\n  } else {\n    const minutes = Math.floor(timeInMinutes);\n    const seconds = Math.round((timeInMinutes - minutes) * 60);\n    return `${minutes} min ${seconds} sec`;\n  }\n}\n\n/**\n * Format duration in hours, minutes, and seconds\n */\nexport function formatDuration(seconds: number): string {\n  if (seconds < 60) {\n    return `${Math.round(seconds)} seconds`;\n  } else if (seconds < 3600) {\n    const minutes = Math.floor(seconds / 60);\n    const remainingSeconds = Math.round(seconds % 60);\n    return `${minutes} min ${remainingSeconds} sec`;\n  } else {\n    const hours = Math.floor(seconds / 3600);\n    const minutes = Math.floor((seconds % 3600) / 60);\n    const remainingSeconds = Math.round(seconds % 60);\n    return `${hours} hr ${minutes} min ${remainingSeconds} sec`;\n  }\n}\n\n/**\n * Create a visual progress bar\n */\nexport function createProgressBar(\n  ratio: number,\n  validSource: boolean = true\n): string {\n  if (!validSource) {\n    return \"N/A (source metrics unavailable)\";\n  }\n\n  const width = 20;\n  const filled = Math.round(ratio * width);\n  const empty = width - filled;\n\n  let bar = \"\";\n\n  if (ratio > 1) {\n    // More than 100%\n    bar = \"▓\".repeat(width) + \" +\" + Math.round((ratio - 1) * 100) + \"%\";\n  } else if (ratio >= 0) {\n    // Less than or equal to 100%\n    bar = \"▓\".repeat(filled) + \"░\".repeat(empty);\n  } else {\n    bar = \"Invalid ratio\";\n  }\n\n  return bar;\n}\n\n/**\n * Calculate percentage change between two numbers\n */\nexport function calculateChange(from: number, to: number): string {\n  const change = ((to - from) / from) * 100;\n  if (change > 0) {\n    return `+${change.toFixed(1)}%`;\n  } else if (change < 0) {\n    return `${change.toFixed(1)}%`;\n  } else {\n    return \"0%\";\n  }\n}\n","import { TranslationMetrics } from \"../types\";\n\n/**\n * Calculate metrics for a piece of text\n */\nexport function calculateMetrics(\n  text: string,\n  isSourceText: boolean = false,\n  sourceMetrics?: TranslationMetrics\n): TranslationMetrics {\n  // Handle null or empty texts\n  if (!text) {\n    return {\n      sourceWordCount: 0,\n      targetWordCount: 0,\n      sourceCharCount: 0,\n      targetCharCount: 0,\n      ratio: 0,\n      estimatedReadingTime: 0,\n    };\n  }\n\n  // Count characters (excluding whitespace)\n  const charCount = text.replace(/\\s/g, \"\").length;\n\n  // Count words - simple implementation for most languages\n  // For languages like Chinese/Japanese, use a different method\n  let wordCount = 0;\n\n  // Use generic word counting by default\n  wordCount = text.split(/\\s+/).filter((word) => word.length > 0).length;\n\n  // Calculate estimated reading time (words per minute)\n  // Average reading speed is about 200-250 words per minute\n  const readingTime = wordCount / 200;\n\n  // If calculating for source text, source and target are the same\n  // Otherwise, use the provided source metrics\n  const sourceW = isSourceText\n    ? wordCount\n    : sourceMetrics?.sourceWordCount ?? 0;\n  const sourceC = isSourceText\n    ? charCount\n    : sourceMetrics?.sourceCharCount ?? 0;\n\n  return {\n    sourceWordCount: sourceW,\n    targetWordCount: wordCount,\n    sourceCharCount: sourceC,\n    targetCharCount: charCount,\n    ratio: sourceW > 0 ? wordCount / sourceW : 0, // Avoid division by zero\n    estimatedReadingTime: readingTime,\n  };\n}\n\n/**\n * Enhanced metrics calculation that considers the target language\n */\nexport function calculateMetricsForLanguage(\n  text: string,\n  language: string | undefined,\n  isSourceText: boolean = false,\n  sourceMetrics?: TranslationMetrics\n): TranslationMetrics {\n  // Handle null or empty texts\n  if (!text) {\n    return {\n      sourceWordCount: 0,\n      targetWordCount: 0,\n      sourceCharCount: 0,\n      targetCharCount: 0,\n      ratio: 0,\n      estimatedReadingTime: 0,\n    };\n  }\n\n  // Count characters (excluding whitespace)\n  const charCount = text.replace(/\\s/g, \"\").length;\n\n  // Count words based on language properties\n  let wordCount = 0;\n\n  // Default to language from parameters, normalize to lowercase\n  const effectiveLanguage = language?.toLowerCase() || \"\";\n\n  if (\n    effectiveLanguage === \"korean\" ||\n    effectiveLanguage === \"japanese\" ||\n    effectiveLanguage === \"chinese\"\n  ) {\n    // For character-based languages, estimate based on characters\n    wordCount = Math.round(charCount / 2); // Very rough approximation\n  } else {\n    // For space-separated languages\n    wordCount = text.split(/\\s+/).filter((word) => word.length > 0).length;\n  }\n\n  // Calculate estimated reading time (words per minute)\n  // Average reading speed is about 200-250 words per minute\n  const readingTime = wordCount / 200;\n\n  // If calculating for source text, source and target are the same\n  const sourceW = isSourceText\n    ? wordCount\n    : sourceMetrics?.sourceWordCount ?? 0;\n  const sourceC = isSourceText\n    ? charCount\n    : sourceMetrics?.sourceCharCount ?? 0;\n\n  return {\n    sourceWordCount: sourceW,\n    targetWordCount: wordCount,\n    sourceCharCount: sourceC,\n    targetCharCount: charCount,\n    ratio: sourceW > 0 ? wordCount / sourceW : 0, // Avoid division by zero\n    estimatedReadingTime: readingTime,\n  };\n}\n","/**\n * Constants used throughout the application\n */\n\n/**\n * Context window limits (total input + output tokens) for different models\n * Note: These are the TOTAL context limits, not just output limits.\n * For example, GPT-4o has a 128K context window but may be limited to 16K output tokens.\n */\nexport const MODEL_CONTEXT_LIMITS: Record<string, number> = {\n  // OpenAI models\n  \"gpt-4.5-preview\": 128000,\n  \"gpt-4o\": 128000,\n  \"gpt-4-turbo\": 128000,\n  \"gpt-4-32k\": 32000,\n  \"gpt-4\": 8192,\n  \"gpt-3.5-turbo-16k\": 16384,\n  \"gpt-3.5-turbo\": 4096,\n\n  // Claude models\n  \"claude-3-opus-20240229\": 200000,\n  \"claude-3-sonnet-20240229\": 200000,\n  \"claude-3-haiku-20240307\": 200000,\n  \"claude-3-5-sonnet-20240620\": 200000,\n  \"claude-3-7-sonnet-latest\": 200000,\n\n  // Default fallback (conservative estimate)\n  default: 16384,\n};\n","export * from \"./continuation\";\nexport * from \"./filesystem\";\nexport * from \"./formatters\";\nexport * from \"./metrics\";\nexport * from \"./logger\";\nexport * from \"./xml\";\nexport * from \"./constants\";\n","/**\n * Translation workflow prompts\n * Contains all prompts used in the multi-step translation process\n */\n\n// Helper type for prompts that need dynamic values\ntype PromptTemplate = (\n  targetLanguage: string,\n  sourceLanguage: string | undefined,\n  sourceText?: string,\n  previousTranslation?: string,\n  externalReview?: string\n) => string;\n\nexport const prompts = {\n  system: (\n    targetLanguage: string,\n    sourceLanguage: string | undefined,\n    customInstructions?: string,\n    currentStep?: string\n  ): string => {\n    let systemPrompt = `You are an expert literary translator with deep fluency in ${targetLanguage}${\n      sourceLanguage ? ` and ${sourceLanguage}` : \"\"\n    }.\nYour goal is to create a high-quality translation that preserves the original's tone, style, literary devices,\ncultural nuances, and overall impact. You prioritize readability and naturalness in the target language while\nstaying faithful to the source text's meaning and intention${\n      sourceLanguage\n        ? \"\"\n        : \" (you may need to infer the source language from the text provided)\"\n    }.\n\nCRITICAL: You must ALWAYS translate the COMPLETE text without omitting any content. Ensure your translations include EVERY part of the source text from beginning to end. If the text is lengthy, you must still translate it in its entirety.\\n`;\n\n    // Only include the relevant XML tags based on the current step\n    if (currentStep) {\n      systemPrompt += `For this step, place your response inside the following XML tag(s) for easy extraction:\\n`;\n\n      switch (currentStep) {\n        case \"initial_analysis\":\n          systemPrompt += `- <analysis>your analysis here</analysis>\\n`;\n          break;\n        case \"expression_exploration\":\n          systemPrompt += `- <expression_exploration>your exploration here</expression_exploration>\\n`;\n          break;\n        case \"cultural_discussion\":\n          systemPrompt += `- <cultural_discussion>your discussion here</cultural_discussion>\\n`;\n          break;\n        case \"title_options\":\n          systemPrompt += `- <title_options>your title suggestions here</title_options>\\n`;\n          break;\n        case \"first_translation\":\n          systemPrompt += `- <first_translation>your COMPLETE translation here</first_translation>\\n`;\n          break;\n        case \"self_critique\":\n          systemPrompt += `- <critique>your critique here</critique>\\n`;\n          systemPrompt += `- <improved_translation>your COMPLETE improved translation here</improved_translation>\\n`;\n          break;\n        case \"further_refinement\":\n          systemPrompt += `- <second_critique>your second critique here</second_critique>\\n`;\n          systemPrompt += `- <further_improved_translation>your COMPLETE further improved translation here</further_improved_translation>\\n`;\n          break;\n        case \"final_translation\":\n          systemPrompt += `- <final_translation>your COMPLETE final translation here</final_translation>\\n`;\n          break;\n        case \"external_review\":\n          systemPrompt += `- <external_review>your external review here</external_review>\\n`;\n          break;\n        case \"apply_feedback\":\n          systemPrompt += `- <refined_final_translation>your COMPLETE refined final translation here</refined_final_translation>\\n`;\n          break;\n        case \"continue_translation\":\n          systemPrompt += `- <continued_translation>your continuation of the translation here</continued_translation>\\n`;\n          systemPrompt += `You are specifically tasked with continuing a translation that was cut off or incomplete. Follow the instructions carefully about where to continue from.\\n`;\n          break;\n        default:\n          // If step is not recognized, include all tags as before\n          systemPrompt += `Always place your translations inside appropriate XML tags for easy extraction:\n- Initial analysis: <analysis>your analysis here</analysis>\n- Expression exploration: <expression_exploration>your exploration here</expression_exploration>\n- Cultural discussion: <cultural_discussion>your discussion here</cultural_discussion>\n- Title options: <title_options>your title suggestions here</title_options>\n- First draft translation: <first_translation>your COMPLETE translation here</first_translation>\n- Critique: <critique>your critique here</critique>\n- Improved translation: <improved_translation>your COMPLETE improved translation here</improved_translation>\n- Second critique: <second_critique>your second critique here</second_critique>\n- Further improved translation: <further_improved_translation>your COMPLETE further improved translation here</further_improved_translation>\n- Comprehensive review: <review>your comprehensive review here</review>\n- Final translation: <final_translation>your COMPLETE final translation here</final_translation>\n- External review: <external_review>your external review here</external_review>\n- Refined final translation: <refined_final_translation>your COMPLETE refined final translation here</refined_final_translation>\n- Continuation: <continued_translation>your continuation of the translation here</continued_translation>\\n`;\n      }\n    } else {\n      // If no specific step is provided, include all tags as before\n      systemPrompt += `Always place your translations inside appropriate XML tags for easy extraction:\n- Initial analysis: <analysis>your analysis here</analysis>\n- Expression exploration: <expression_exploration>your exploration here</expression_exploration>\n- Cultural discussion: <cultural_discussion>your discussion here</cultural_discussion>\n- Title options: <title_options>your title suggestions here</title_options>\n- First draft translation: <first_translation>your COMPLETE translation here</first_translation>\n- Critique: <critique>your critique here</critique>\n- Improved translation: <improved_translation>your COMPLETE improved translation here</improved_translation>\n- Second critique: <second_critique>your second critique here</second_critique>\n- Further improved translation: <further_improved_translation>your COMPLETE further improved translation here</further_improved_translation>\n- Comprehensive review: <review>your comprehensive review here</review>\n- Final translation: <final_translation>your COMPLETE final translation here</final_translation>\n- External review: <external_review>your external review here</external_review>\n- Refined final translation: <refined_final_translation>your COMPLETE refined final translation here</refined_final_translation>\n- Continuation: <continued_translation>your continuation of the translation here</continued_translation>\\n`;\n    }\n\n    systemPrompt += `Your tone should be conversational and thoughtful, as if you're discussing the translation process with a colleague.\nThink deeply about cultural context, idiomatic expressions, and literary devices that would resonate with native\n${targetLanguage} speakers.\n\nWork through the translation step by step, maintaining the voice and essence of the original while making it\nfeel naturally written in ${targetLanguage}.\n\nYour output length is unlocked so you can produce at least 30K tokens in your output if needed - ensure you NEVER truncate or omit any part of the text.`;\n\n    if (customInstructions) {\n      systemPrompt += `\\n\\nAdditional instructions for this translation:\\n${customInstructions}`;\n    }\n    return systemPrompt;\n  },\n\n  initialAnalysis: ((\n    sourceText: string,\n    targetLanguage: string,\n    sourceLanguage?: string\n  ): string => `I'd like your help translating a text into ${targetLanguage}${\n    sourceLanguage ? ` from ${sourceLanguage}` : \"\"\n  }.\nBefore we start, could you analyze what we'll need to preserve in terms of tone, style, meaning, and cultural nuances?\n\nHere's the text to be translated:\n\n<source_text>\n${sourceText}\n</source_text>\n\nPlease analyze this text thoughtfully. What are the key elements that make this text distinctive? What tone, voice,\nargument structure, rhetorical devices, and cultural references should we be careful to preserve in translation?\n\nNOTE: Do not translate the text yet. This is just an analysis step to understand the text's distinctive elements.\n\nRemember to put your analysis in <analysis> tags.`) as PromptTemplate,\n\n  expressionExploration: ((\n    sourceText: string,\n    targetLanguage: string\n  ): string => `Now that we've analyzed the text, let's explore how we might express key elements in ${targetLanguage}.\n\nHere's the original text for reference:\n\n<source_text>\n${sourceText}\n</source_text>\n\nCould you identify 5-10 key phrases, idioms, cultural references, or stylistic elements from this text that might be challenging to translate?\n\nFor each one, could you suggest how you might express it in ${targetLanguage} to preserve the intended meaning, tone, and effect?\n\nNOTE: This is not a full translation yet - we're just exploring key expressions to understand how to approach them.\n\nPlease format your exploration within <expression_exploration> tags.`) as PromptTemplate,\n\n  toneAndCulturalDiscussion: ((\n    sourceText: string,\n    targetLanguage: string\n  ): string => `Let's discuss the cultural adaptation aspects of this translation.\n\nHere's the original text again for reference:\n\n<source_text>\n${sourceText}\n</source_text>\n\nWhat cultural adaptations might be necessary for ${targetLanguage} readers? Are there any references, analogies, or concepts\nthat would need special consideration for the target audience?\n\nHow should we handle the overall tone and voice to ensure it resonates with ${targetLanguage} readers while staying faithful\nto the original? Are there any cultural sensitivities to be aware of?\n\nRemember, we're still not translating the full text yet - just discussing how we'll approach cultural elements.\n\nPlease put your discussion within <cultural_discussion> tags.`) as PromptTemplate,\n\n  titleAndInspirationExploration: ((\n    sourceText: string,\n    targetLanguage: string\n  ): string => `Let's now consider how to translate the title and any literary inspirations we might draw from to create a compelling translation.\n\nHere's the original text for reference:\n\n<source_text>\n${sourceText}\n</source_text>\n\n1. How should we translate the title to capture its essence in ${targetLanguage}? Please provide a few options with your reasoning.\n\n2. Are there any well-known ${targetLanguage} literary works, authors, or stylistic traditions that might provide inspiration for our approach?\n   How might these influences help us create a translation that feels natural and resonant to native speakers?\n\nPlease share your thoughts within <title_options> tags.`) as PromptTemplate,\n\n  firstTranslationAttempt: ((\n    sourceText: string,\n    targetLanguage: string\n  ): string => `Now that we've analyzed the text and discussed key considerations, I'd like you to create a first draft translation into ${targetLanguage}.\n\nHere is the source text:\n\n<source_text>\n${sourceText}\n</source_text>\n\nBased on our previous discussions about tone, style, cultural nuances, and specific expressions, please translate the COMPLETE text.\nAim to preserve the original's meaning, impact, and feeling while making it sound natural in ${targetLanguage}.\n\nIMPORTANT: You must translate the ENTIRE text without omitting any paragraphs, sentences, or content. Ensure your translation is complete from beginning to end. If the text is lengthy, make sure you include everything.\n\nPlease place your complete translation within <first_translation> tags.`) as PromptTemplate,\n\n  selfCritiqueAndRefinement: ((\n    targetLanguage: string,\n    sourceLanguage: string | undefined,\n    sourceText?: string,\n    previousTranslation?: string\n  ): string => `Now that we have our first draft, I'd love for you to review it critically.\nWhat do you think are the strengths and weaknesses of this translation?\n\nHere is the original text for reference:\n\n<source_text>\n${sourceText}\n</source_text>\n\nAnd here is the first draft translation:\n\n<previous_translation>\n${previousTranslation}\n</previous_translation>\n\nCould you analyze aspects like:\n- Sentence structure and flow\n- Word choice and terminology\n- How well cultural elements were adapted\n- The preservation of the original's tone and voice\n- Poetic quality and literary devices\n- Overall readability and naturalness in ${targetLanguage}\n- COMPLETENESS: Check if any sentences or paragraphs were omitted from the original text\n\nAfter providing your critique, please offer an improved version of the translation that addresses\nthe issues you identified. Providing the complete improved translation allows for easier comparison and usability.\n\nIMPORTANT: Ensure your improved translation includes EVERY part of the source text with nothing omitted. Double-check that no content is missing.\n\nPlease put your critique in <critique> tags and your complete improved translation in <improved_translation> tags.`) as PromptTemplate,\n\n  furtherRefinement: ((\n    targetLanguage: string,\n    sourceLanguage: string | undefined,\n    sourceText?: string,\n    previousTranslation?: string\n  ): string => `Let's take a fresh look at our translation with new eyes.\n\nHere is the original text:\n\n<source_text>\n${sourceText}\n</source_text>\n\nAnd here is our current translation:\n\n<previous_translation>\n${previousTranslation}\n</previous_translation>\n\nI'd like you to review this translation again, but this time paying special attention to:\n\n1. Naturalness: Does it flow as if it were originally written in ${targetLanguage}?\n2. Fidelity: Does it capture the full meaning and nuance of the original?\n3. Completeness: Is EVERY part of the source text included in the translation?\n4. Impact: Does it have the same emotional and rhetorical effect as the original?\n5. Consistency: Are terms, tone, and style consistent throughout?\n6. Cultural resonance: Would it connect with native ${targetLanguage} speakers on a cultural level?\n\nAfter your critique, please provide a further improved version that addresses any issues you find.\n\nIMPORTANT: Verify that no content has been omitted. Your translation must include EVERY part of the original text from start to finish.\n\nPlease put your critique in <second_critique> tags and your improved translation in <further_improved_translation> tags.`) as PromptTemplate,\n\n  finalTranslation: ((\n    targetLanguage: string,\n    sourceLanguage: string | undefined,\n    sourceText?: string,\n    previousTranslation?: string\n  ): string => `Now it's time for our final comprehensive review and translation.\n\nHere's the original text:\n\n<source_text>\n${sourceText}\n</source_text>\n\nAnd our current translation:\n\n<previous_translation>\n${previousTranslation}\n</previous_translation>\n\nLet's do one final pass to perfect this translation. Consider all the aspects we've discussed:\n- Overall flow and readability\n- Accuracy and fidelity to the original\n- Cultural adaptation\n- Natural expression in ${targetLanguage}\n- Preservation of tone, style, and voice\n- Literary quality\n- COMPLETENESS: Ensure that EVERY part of the source text is translated\n\nAfter your review, please provide what you consider to be the final, polished translation.\n\nCRITICAL: Your final translation MUST include the ENTIRE source text with no omissions whatsoever. Double-check that you have translated everything completely from beginning to end.\n\nPlease put your final translation in <final_translation> tags.`) as PromptTemplate,\n\n  externalReviewSystem: ((\n    targetLanguage: string,\n    sourceLanguage?: string\n  ): string => `You are an expert literary translator and critic with deep fluency in ${targetLanguage}${\n    sourceLanguage ? ` and ${sourceLanguage}` : \"\"\n  }.\nYour task is to critically review a translation ${\n    sourceLanguage ? `from ${sourceLanguage} ` : \"\"\n  }to ${targetLanguage}, providing detailed,\nconstructive feedback on how well it captures the essence, tone, and cultural nuances of the original text.\nPlease be candid but fair in your assessment.`) as PromptTemplate,\n\n  externalReviewUser: ((\n    targetLanguage: string,\n    sourceLanguage: string | undefined,\n    sourceText?: string,\n    translation?: string\n  ): string => `I'd like you to provide an external review of a translation ${\n    sourceLanguage ? `from ${sourceLanguage} ` : \"\"\n  }to ${targetLanguage}.\n\nHere's the original text:\n\n<source_text>\n${sourceText}\n</source_text>\n\nAnd here's the translation:\n\n<translated_text>\n${translation}\n</translated_text>\n\nCould you critically evaluate how well this translation captures the essence, tone, and cultural nuances of the original?\nPlease consider aspects like:\n- Accuracy and fidelity to the source\n- Natural flow and readability in ${targetLanguage}\n- Cultural adaptation and resonance\n- Preservation of literary devices, metaphors, and style\n- Overall effectiveness as a ${targetLanguage} text\n- COMPLETENESS: Has the entire source text been translated? Or are there missing parts?\n\nIMPORTANT: Please explicitly check if any paragraphs, sentences, or sections from the source text are missing in the translation. If you find any omissions, highlight them clearly at the beginning of your review.\n\nPlease format your review within <external_review> tags.`) as PromptTemplate,\n\n  applyExternalFeedback: ((\n    targetLanguage: string,\n    sourceLanguage: string | undefined,\n    sourceText?: string,\n    translation?: string,\n    externalReview?: string\n  ): string => `We've received an external review of our translation. Let's use this feedback to create our final refined version.\n\nHere's the original text:\n\n<source_text>\n${sourceText}\n</source_text>\n\nOur current translation:\n\n<current_translation>\n${translation}\n</current_translation>\n\nAnd the external review we received:\n\n<external_review>\n${externalReview}\n</external_review>\n\nBased on this feedback, please create a refined final version of the translation that addresses the reviewer's points\nwhile maintaining the strengths of our current version.\n\nPlease apply your best judgment - incorporate suggestions that improve the translation, but feel free to respectfully\ndisagree with points that you believe would not enhance the final result.\n\nPlease provide your refined final translation within <refined_final_translation> tags.`) as PromptTemplate,\n\n  continuationTranslation: ((\n    targetLanguage: string,\n    sourceLanguage: string | undefined,\n    sourceText?: string,\n    partialTranslation?: string,\n    continuationPoint?: string\n  ): string => `I need you to continue a translation that was cut off. The full source text and the partial translation are provided.\n\n<source_text>\n${sourceText}\n</source_text>\n\n<partial_translation>\n${partialTranslation}\n</partial_translation>\n\nThis translation is incomplete. Please continue translating from the point where it cuts off.\n\nIMPORTANT: Focus on completing the translation from where it was interrupted. Your continuation should maintain the same style, tone, and formatting as the existing partial translation.\n\nPlease put your continuation in <continued_translation> tags.`) as PromptTemplate,\n};\n\nexport type PromptKey = keyof typeof prompts;\n","import * as path from \"path\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport {\n  ConversationMessage,\n  TranslationConfig,\n  TranslationMetrics,\n} from \"../types\";\nimport { AiService, CostResult, AiRequestOptions } from \"../services/ai\";\nimport { Logger } from \"../utils/logger\";\nimport { XmlProcessor } from \"../utils/xml\";\nimport {\n  calculateMetricsForLanguage,\n  createProgressBar,\n  ensureDirectoryExists,\n  findLatestFile,\n  findFilesInDirectory,\n  formatTime,\n  formatDuration,\n  saveText,\n  saveJson,\n  loadJson,\n  loadText,\n  calculateChange,\n  checkTranslationCompletion,\n  createContinuationPrompt,\n  createSimpleContinuationPrompt,\n  backupPartialTranslation,\n  combineTranslation,\n  removeUnpairedXmlTags,\n  removeContinuationMarkers,\n  MODEL_CONTEXT_LIMITS,\n} from \"../utils\";\nimport { prompts } from \"../prompts/translation\";\n\n/**\n * Main translation workflow class\n * Orchestrates the multi-stage translation process\n */\nexport class TranslationWorkflow {\n  private conversation: ConversationMessage[] = [];\n  private config: TranslationConfig;\n  private intermediatesDir: string;\n  private spinner = ora();\n  private totalTokens = 0;\n  private totalInputTokens = 0;\n  private totalOutputTokens = 0;\n  private estimatedCost = 0;\n  private xmlProcessor: XmlProcessor;\n  private translationSteps: string[] = [];\n  private outputFiles: { [key: string]: string } = {};\n  private stepCounter = 0;\n  private conversationJsonPath: string;\n  private conversationTextPath: string;\n  private metricsPath: string;\n  private sourceMetrics!: TranslationMetrics;\n  private translationMetrics: Map<string, TranslationMetrics> = new Map();\n  private finalOutputPath: string;\n  private aiService: AiService;\n  private logger: Logger;\n  private spinnerStartTime: number = 0;\n  private spinnerInterval: NodeJS.Timeout | null = null;\n\n  // Track continuation progress to prevent infinite loops\n  private continuationAttempts = 0;\n  private previousTranslationLength = 0;\n  private minimumMeaningfulProgress = 100; // Require at least 100 chars of new content\n  private previousSourceLine = \"\"; // Track the previous source line we continued from\n\n  constructor(config: TranslationConfig) {\n    this.config = config;\n    this.logger = new Logger(this.config.verbose);\n    this.aiService = new AiService();\n    this.xmlProcessor = new XmlProcessor();\n\n    // Initialize properties\n    let resumed = false;\n\n    // Define paths\n    this.intermediatesDir = path.join(\n      this.config.outputDir,\n      \".translation-intermediates\"\n    );\n\n    this.finalOutputPath = path.join(\n      this.config.outputDir,\n      `${this.config.originalFilename}-${this.config.targetLanguage}${this.config.originalExtension}`\n    );\n\n    // Create directories\n    ensureDirectoryExists(this.config.outputDir);\n    ensureDirectoryExists(this.intermediatesDir);\n\n    // Set file paths\n    this.conversationJsonPath = path.join(\n      this.intermediatesDir,\n      \"conversation_history.json\"\n    );\n    this.conversationTextPath = path.join(\n      this.intermediatesDir,\n      \"conversation_history.txt\"\n    );\n    this.metricsPath = path.join(\n      this.intermediatesDir,\n      \"translation_metrics.json\"\n    );\n\n    // Try to resume or initialize new conversation\n    if (!this.tryResume()) {\n      this.initializeNewConversation();\n    }\n  }\n\n  /**\n   * Try to resume a previous translation session\n   */\n  private tryResume(): boolean {\n    if (loadText(this.conversationJsonPath, \"\").length === 0) {\n      return false;\n    }\n\n    try {\n      const historyData = loadJson<{\n        metadata: {\n          timestamp: string;\n          label: string;\n          step: number;\n          totalTokens: number;\n          totalInputTokens: number;\n          totalOutputTokens: number;\n          estimatedCost: number;\n        };\n        conversation: ConversationMessage[];\n      }>(this.conversationJsonPath, {\n        metadata: {\n          timestamp: \"\",\n          label: \"\",\n          step: 0,\n          totalTokens: 0,\n          totalInputTokens: 0,\n          totalOutputTokens: 0,\n          estimatedCost: 0,\n        },\n        conversation: [],\n      });\n\n      if (historyData.conversation && historyData.metadata) {\n        this.conversation = historyData.conversation;\n        this.totalTokens = historyData.metadata.totalTokens || 0;\n        this.stepCounter = historyData.metadata.step || 0;\n        const lastLabel = historyData.metadata.label || \"Unknown Step\";\n\n        // Load cost tracking data\n        this.totalInputTokens = historyData.metadata.totalInputTokens || 0;\n        this.totalOutputTokens = historyData.metadata.totalOutputTokens || 0;\n        this.estimatedCost = historyData.metadata.estimatedCost || 0;\n\n        // Scan intermediates directory for existing step files\n        const files = findFilesInDirectory(\n          this.intermediatesDir,\n          /^\\d{2}_.*\\.txt$/\n        );\n        files.forEach((filePath) => {\n          const fileName = path.basename(filePath);\n          // Convert filename like 01_initial_analysis.txt to \"01 Initial Analysis\"\n          const stepKey = fileName\n            .substring(0, fileName.length - 4) // Remove .txt\n            .replace(/_/g, \" \")\n            .replace(/\\b\\w/g, (l) => l.toUpperCase());\n          this.outputFiles[stepKey] = filePath;\n        });\n\n        // Reconstruct translation steps\n        const stepNames = [\n          \"Initial Analysis\",\n          \"Expression Exploration\",\n          \"Cultural Adaptation Discussion\",\n          \"Title & Inspiration Exploration\",\n          \"First Translation\",\n          \"Self-Critique & First Refinement\",\n          \"Second Refinement\",\n          \"Final Translation\",\n          \"External Review\",\n          \"Final Refinement\",\n        ];\n\n        // Extract step numbers from keys and sort them\n        this.translationSteps = Object.keys(this.outputFiles)\n          .filter((key) => /^\\d{2}\\s/.test(key))\n          .sort((a, b) => {\n            const numA = parseInt(a.substring(0, 2));\n            const numB = parseInt(b.substring(0, 2));\n            return numA - numB;\n          })\n          .map((key) => {\n            const stepNum = parseInt(key.substring(0, 2)) - 1;\n            return stepNum >= 0 && stepNum < stepNames.length\n              ? stepNames[stepNum]\n              : key.substring(3);\n          });\n\n        // Load existing metrics\n        const metricsData = loadJson<Record<string, any>>(this.metricsPath, {\n          source: null,\n        });\n\n        if (metricsData.source) {\n          this.sourceMetrics = metricsData.source as TranslationMetrics;\n        } else {\n          this.sourceMetrics = calculateMetricsForLanguage(\n            this.config.sourceText,\n            this.config.sourceLanguage,\n            true\n          );\n        }\n\n        Object.entries(metricsData).forEach(([key, value]) => {\n          if (key !== \"source\") {\n            this.translationMetrics.set(key, value as TranslationMetrics);\n          }\n        });\n\n        this.logger.success(\n          `🔄 Resuming translation workflow from step ${this.stepCounter} (${lastLabel})`\n        );\n        return true;\n      }\n    } catch (error) {\n      this.logger.error(\n        `❌ Error reading or parsing conversation history file. Starting fresh: ${error}`\n      );\n    }\n\n    return false;\n  }\n\n  /**\n   * Initialize a new conversation\n   */\n  private initializeNewConversation(): void {\n    // Calculate source metrics\n    this.sourceMetrics = calculateMetricsForLanguage(\n      this.config.sourceText,\n      this.config.sourceLanguage,\n      true\n    );\n\n    // Reset state\n    this.conversation = [];\n    this.totalTokens = 0;\n    this.totalInputTokens = 0;\n    this.totalOutputTokens = 0;\n    this.estimatedCost = 0;\n    this.stepCounter = 0;\n    this.translationSteps = [];\n    this.translationMetrics = new Map();\n    this.outputFiles = {};\n\n    // Build initial system prompt with initial_analysis as the target step\n    const systemPrompt = prompts.system(\n      this.config.targetLanguage,\n      this.config.sourceLanguage,\n      this.config.customInstructions,\n      \"initial_analysis\" // Start with the first step\n    );\n\n    // Add system prompt to conversation\n    this.conversation.push({\n      role: \"system\",\n      content: systemPrompt,\n    });\n\n    // Save initial state\n    this.saveConversationHistory(\"Initial system prompt\");\n  }\n\n  /**\n   * Main execution method\n   */\n  public async execute(): Promise<void> {\n    this.logger.logHeader(\"Starting Translation Workflow\");\n    this.logger.log(\n      chalk.blue(\n        `📄 Translating ${\n          this.config.sourceLanguage\n            ? `from ${this.config.sourceLanguage} `\n            : \"\"\n        }to ${this.config.targetLanguage}`\n      )\n    );\n    this.logger.log(chalk.blue(`   Input file: ${this.config.inputPath}`));\n    this.logger.log(chalk.blue(`   Output file: ${this.finalOutputPath}`));\n    this.logger.log(chalk.blue(`   Intermediates: ${this.intermediatesDir}`));\n    this.displaySourceMetrics();\n\n    const startTime = Date.now();\n    let latestTranslationContent = \"\"; // Track the latest completed translation text\n\n    try {\n      // Step 1: Initial Analysis\n      if (this.stepCounter < 1) {\n        this.startSpinnerWithTimer(\"Step 1/10: Analyzing source text\");\n\n        const initialAnalysisPrompt = prompts.initialAnalysis(\n          this.config.sourceText,\n          this.config.targetLanguage,\n          this.config.sourceLanguage\n        );\n\n        const analysisResponse = await this.callAiService(\n          initialAnalysisPrompt\n        );\n        const analysisContent = this.xmlProcessor.extractTagContent(\n          analysisResponse,\n          \"analysis\"\n        );\n\n        // Save analysis to file\n        const analysisPath = path.join(\n          this.intermediatesDir,\n          \"01_initial_analysis.txt\"\n        );\n        saveText(analysisPath, analysisContent);\n        this.outputFiles[\"01 Initial Analysis\"] = analysisPath;\n\n        // Add to translation steps\n        this.translationSteps.push(\"Initial Analysis\");\n        this.succeedSpinner(\"✅ Initial analysis completed\");\n        this.logger.success(\"Initial analysis saved to intermediates\");\n\n        // Update step counter AFTER completing the step\n        this.stepCounter = 1;\n        // Save conversation history with updated step counter\n        this.saveConversationHistory(\"Completed Step 1: Initial Analysis\");\n      }\n\n      // Step 2: Expression Exploration\n      if (this.stepCounter < 2) {\n        this.startSpinnerWithTimer(\n          \"Step 2/10: Exploring expressions in target language\"\n        );\n\n        const expressionExplorationPrompt = prompts.expressionExploration(\n          this.config.sourceText,\n          this.config.targetLanguage\n        );\n\n        const expressionResponse = await this.callAiService(\n          expressionExplorationPrompt\n        );\n        const expressionContent = this.xmlProcessor.extractTagContent(\n          expressionResponse,\n          \"expression_exploration\"\n        );\n\n        // Save expressions to file\n        const expressionPath = path.join(\n          this.intermediatesDir,\n          \"02_expression_exploration.txt\"\n        );\n        saveText(expressionPath, expressionContent);\n        this.outputFiles[\"02 Expression Exploration\"] = expressionPath;\n\n        // Add to translation steps\n        this.translationSteps.push(\"Expression Exploration\");\n        this.succeedSpinner(\"✅ Expression exploration completed\");\n        this.logger.success(\"Expression exploration saved to intermediates\");\n\n        // Update step counter AFTER completing the step\n        this.stepCounter = 2;\n        // Save conversation history with updated step counter\n        this.saveConversationHistory(\n          \"Completed Step 2: Expression Exploration\"\n        );\n      }\n\n      // Step 3: Cultural Adaptation\n      if (this.stepCounter < 3) {\n        this.startSpinnerWithTimer(\"Step 3/10: Discussing cultural adaptation\");\n\n        const culturalAdaptationPrompt = prompts.toneAndCulturalDiscussion(\n          this.config.sourceText,\n          this.config.targetLanguage\n        );\n\n        const culturalResponse = await this.callAiService(\n          culturalAdaptationPrompt\n        );\n        const culturalContent = this.xmlProcessor.extractTagContent(\n          culturalResponse,\n          \"cultural_discussion\"\n        );\n\n        // Save cultural adaptation to file\n        const culturalPath = path.join(\n          this.intermediatesDir,\n          \"03_cultural_adaptation.txt\"\n        );\n        saveText(culturalPath, culturalContent);\n        this.outputFiles[\"03 Cultural Adaptation Discussion\"] = culturalPath;\n\n        // Add to translation steps\n        this.translationSteps.push(\"Cultural Adaptation Discussion\");\n        this.succeedSpinner(\"✅ Cultural adaptation discussion completed\");\n        this.logger.success(\n          \"Cultural adaptation discussion saved to intermediates\"\n        );\n\n        // Update step counter AFTER completing the step\n        this.stepCounter = 3;\n        // Save conversation history with updated step counter\n        this.saveConversationHistory(\"Completed Step 3: Cultural Adaptation\");\n      }\n\n      // Step 4: Title & Inspiration Exploration\n      if (this.stepCounter < 4) {\n        this.startSpinnerWithTimer(\"Step 4/10: Exploring title & inspiration\");\n\n        const titleInspirationPrompt = prompts.titleAndInspirationExploration(\n          this.config.sourceText,\n          this.config.targetLanguage\n        );\n\n        const titleResponse = await this.callAiService(titleInspirationPrompt);\n        const titleContent = this.xmlProcessor.extractTagContent(\n          titleResponse,\n          \"title_options\"\n        );\n\n        // Save title & inspiration to file\n        const titlePath = path.join(\n          this.intermediatesDir,\n          \"04_title_inspiration.txt\"\n        );\n        saveText(titlePath, titleContent);\n        this.outputFiles[\"04 Title & Inspiration Exploration\"] = titlePath;\n\n        // Add to translation steps\n        this.translationSteps.push(\"Title & Inspiration Exploration\");\n        this.succeedSpinner(\"✅ Title & inspiration exploration completed\");\n        this.logger.success(\n          \"Title & inspiration exploration saved to intermediates\"\n        );\n\n        // Update step counter AFTER completing the step\n        this.stepCounter = 4;\n        // Save conversation history with updated step counter\n        this.saveConversationHistory(\"Completed Step 4: Title & Inspiration\");\n      }\n\n      // Step 5: First Translation\n      if (this.stepCounter < 5) {\n        this.startSpinnerWithTimer(\n          \"Step 5/10: Creating first translation draft\"\n        );\n\n        const firstTranslationPrompt = prompts.firstTranslationAttempt(\n          this.config.sourceText,\n          this.config.targetLanguage\n        );\n\n        const translationResponse = await this.callAiService(\n          firstTranslationPrompt\n        );\n        const translationPath = path.join(\n          this.intermediatesDir,\n          \"05_first_translation.txt\"\n        );\n        const translationContent = await this.extractAndContinueTagContent(\n          translationResponse,\n          \"first_translation\",\n          translationPath\n        );\n\n        // Update latest translation content\n        latestTranslationContent = translationContent;\n\n        // Calculate metrics for this step\n        const metrics = calculateMetricsForLanguage(\n          translationContent,\n          this.config.targetLanguage,\n          false,\n          this.sourceMetrics\n        );\n\n        this.translationMetrics.set(\"first_translation\", metrics);\n\n        // Add to translation steps\n        this.translationSteps.push(\"First Translation\");\n        this.succeedSpinner(\"✅ First translation draft completed\");\n        this.logger.success(\"First translation draft saved to intermediates\");\n\n        // First translation step - add the outputFiles entry\n        this.outputFiles[\"05 First Translation\"] = translationPath;\n\n        // Update step counter AFTER completing the step\n        this.stepCounter = 5;\n        // Save conversation history with updated step counter\n        this.saveConversationHistory(\"Completed Step 5: First Translation\");\n      }\n\n      // Step 6: Self-critique & First Refinement\n      if (this.stepCounter < 6) {\n        this.startSpinnerWithTimer(\n          \"Step 6/10: Self-critique & first refinement\"\n        );\n\n        // Get the previous translation content\n        const prevTranslationPath = path.join(\n          this.intermediatesDir,\n          \"05_first_translation.txt\"\n        );\n        const prevTranslation = loadText(prevTranslationPath, \"\");\n\n        const selfCritiquePrompt = prompts.selfCritiqueAndRefinement(\n          this.config.targetLanguage,\n          this.config.sourceLanguage,\n          this.config.sourceText,\n          prevTranslation\n        );\n\n        const critiqueResponse = await this.callAiService(selfCritiquePrompt);\n        const improvedPath = path.join(\n          this.intermediatesDir,\n          \"07_improved_translation.txt\"\n        );\n        const improvedTranslation = await this.extractAndContinueTagContent(\n          critiqueResponse,\n          \"improved_translation\",\n          improvedPath\n        );\n\n        // Update latest translation content\n        latestTranslationContent = improvedTranslation;\n\n        // Calculate metrics for this step\n        const metrics = calculateMetricsForLanguage(\n          improvedTranslation,\n          this.config.targetLanguage,\n          false,\n          this.sourceMetrics\n        );\n\n        this.translationMetrics.set(\"improved_translation\", metrics);\n\n        // Add to translation steps\n        this.translationSteps.push(\"Self-Critique & First Refinement\");\n        this.succeedSpinner(\"✅ Self-critique & first refinement completed\");\n        this.logger.success(\"Improved translation saved to intermediates\");\n\n        // Improved translation step - add the outputFiles entry\n        this.outputFiles[\"07 Improved Translation\"] = improvedPath;\n\n        // Update step counter AFTER completing the step\n        this.stepCounter = 6;\n        // Save conversation history with updated step counter\n        this.saveConversationHistory(\n          \"Completed Step 6: Self-critique & First Refinement\"\n        );\n      }\n\n      // Step 7: Second Refinement\n      if (this.stepCounter < 7) {\n        this.startSpinnerWithTimer(\"Step 7/10: Second refinement\");\n\n        // Get the previous translation content\n        const prevTranslationPath = path.join(\n          this.intermediatesDir,\n          \"07_improved_translation.txt\"\n        );\n        const prevTranslation = loadText(prevTranslationPath, \"\");\n\n        const secondRefinementPrompt = prompts.furtherRefinement(\n          this.config.targetLanguage,\n          this.config.sourceLanguage,\n          this.config.sourceText,\n          prevTranslation\n        );\n\n        const secondRefineResponse = await this.callAiService(\n          secondRefinementPrompt\n        );\n        const furtherImprovedPath = path.join(\n          this.intermediatesDir,\n          \"09_further_improved_translation.txt\"\n        );\n        const furtherImprovedTranslation =\n          await this.extractAndContinueTagContent(\n            secondRefineResponse,\n            \"further_improved_translation\",\n            furtherImprovedPath\n          );\n\n        // Update latest translation content\n        latestTranslationContent = furtherImprovedTranslation;\n\n        // Calculate metrics for this step\n        const metrics = calculateMetricsForLanguage(\n          furtherImprovedTranslation,\n          this.config.targetLanguage,\n          false,\n          this.sourceMetrics\n        );\n\n        this.translationMetrics.set(\"further_improved_translation\", metrics);\n\n        // Add to translation steps\n        this.translationSteps.push(\"Second Refinement\");\n        this.succeedSpinner(\"✅ Second refinement completed\");\n        this.logger.success(\n          \"Further improved translation saved to intermediates\"\n        );\n\n        // Further improved translation step - add the outputFiles entry\n        this.outputFiles[\"09 Further Improved Translation\"] =\n          furtherImprovedPath;\n\n        // Update step counter AFTER completing the step\n        this.stepCounter = 7;\n        // Save conversation history with updated step counter\n        this.saveConversationHistory(\"Completed Step 7: Second Refinement\");\n      }\n\n      // Step 8: Final Translation\n      if (this.stepCounter < 8) {\n        this.startSpinnerWithTimer(\"Step 8/10: Creating final translation\");\n\n        // Get the previous translation content\n        const prevTranslationPath = path.join(\n          this.intermediatesDir,\n          \"09_further_improved_translation.txt\"\n        );\n        const prevTranslation = loadText(prevTranslationPath, \"\");\n\n        // For final translation step, consider using a fresh conversation for long texts\n        const estimatedSourceTokens = Math.ceil(\n          this.config.sourceText.length / 4\n        );\n        const estimatedTranslationTokens = Math.ceil(\n          prevTranslation.length / 4\n        );\n\n        // Get model's context limit\n        const modelContextLimit =\n          MODEL_CONTEXT_LIMITS[this.config.modelName] || 0;\n\n        // If text is very large or conversation history is getting too big, reset conversation\n        // Use 50% of the context limit as a threshold to be safe\n        const currentConversationTokens = this.conversation.reduce(\n          (total, msg) => total + Math.ceil(msg.content.length / 4),\n          0\n        );\n\n        const resetThreshold = modelContextLimit * 0.5;\n        const wouldExceedLimit =\n          currentConversationTokens +\n            estimatedSourceTokens +\n            estimatedTranslationTokens >\n          resetThreshold;\n\n        if (wouldExceedLimit) {\n          this.logger.info(\n            `📝 Large translation or conversation history detected (${currentConversationTokens.toLocaleString()} tokens + ${estimatedSourceTokens.toLocaleString()} source tokens). Starting fresh conversation for final translation step.`\n          );\n          // Reset conversation with just the system message\n          const systemPrompt = prompts.system(\n            this.config.targetLanguage,\n            this.config.sourceLanguage,\n            this.config.customInstructions,\n            \"final_translation\"\n          );\n          this.conversation = [\n            {\n              role: \"system\",\n              content: systemPrompt,\n            },\n          ];\n          this.saveConversationHistory(\"Reset for final translation\");\n        } else if (this.config.verbose) {\n          this.logger.info(\n            `📝 Continuing with existing conversation (${currentConversationTokens.toLocaleString()} tokens).`\n          );\n        }\n\n        const finalTranslationPrompt = prompts.finalTranslation(\n          this.config.targetLanguage,\n          this.config.sourceLanguage,\n          this.config.sourceText,\n          prevTranslation\n        );\n\n        const finalResponse = await this.callAiService(finalTranslationPrompt);\n        const finalPath = path.join(\n          this.intermediatesDir,\n          \"11_final_translation.txt\"\n        );\n        const finalTranslation = await this.extractAndContinueTagContent(\n          finalResponse,\n          \"final_translation\",\n          finalPath\n        );\n\n        // Update latest translation content\n        latestTranslationContent = finalTranslation;\n\n        // Calculate metrics for this step\n        const metrics = calculateMetricsForLanguage(\n          finalTranslation,\n          this.config.targetLanguage,\n          false,\n          this.sourceMetrics\n        );\n\n        this.translationMetrics.set(\"final_translation\", metrics);\n\n        // Add to translation steps\n        this.translationSteps.push(\"Final Translation\");\n        this.succeedSpinner(\"✅ Final translation completed\");\n        this.logger.success(\"Final translation saved to intermediates\");\n\n        // Final translation step - add the outputFiles entry\n        this.outputFiles[\"11 Final Translation\"] = finalPath;\n\n        // Update step counter AFTER completing the step\n        this.stepCounter = 8;\n        // Save conversation history with updated step counter\n        this.saveConversationHistory(\"Completed Step 8: Final Translation\");\n      }\n\n      // Step 9: External Review (optional)\n      let externalReviewContent = \"\";\n      if (!this.config.skipExternalReview && this.stepCounter < 9) {\n        this.startSpinnerWithTimer(\"Step 9/10: Conducting external review\");\n\n        // Get the final translation content\n        const finalTranslationPath = path.join(\n          this.intermediatesDir,\n          \"11_final_translation.txt\"\n        );\n        const finalTranslation = loadText(finalTranslationPath, \"\");\n\n        const externalReviewPrompt = prompts.externalReviewUser(\n          this.config.targetLanguage,\n          this.config.sourceLanguage,\n          this.config.sourceText,\n          finalTranslation\n        );\n\n        // Use a different model for external review if possible\n        const externalResponse = await this.callAiService(\n          externalReviewPrompt,\n          0,\n          true\n        );\n        externalReviewContent = this.xmlProcessor.extractTagContent(\n          externalResponse,\n          \"external_review\"\n        );\n\n        // Save external review to file\n        const reviewPath = path.join(\n          this.intermediatesDir,\n          \"12_external_review.txt\"\n        );\n        saveText(reviewPath, externalReviewContent);\n        this.outputFiles[\"12 External Review\"] = reviewPath;\n\n        // Add to translation steps\n        this.translationSteps.push(\"External Review\");\n        this.succeedSpinner(\"✅ External review completed\");\n        this.logger.success(\"External review saved to intermediates\");\n\n        // Update step counter AFTER completing the step\n        this.stepCounter = 9;\n        // Save conversation history with updated step counter\n        this.saveConversationHistory(\"Completed Step 9: External Review\");\n      }\n\n      // Step 10: Final Refinement\n      if (\n        (!this.config.skipExternalReview && this.stepCounter < 10) ||\n        (this.config.skipExternalReview && this.stepCounter < 9)\n      ) {\n        this.startSpinnerWithTimer(\"Step 10/10: Applying final refinements\");\n\n        // Get the final translation content\n        const finalTranslationPath = path.join(\n          this.intermediatesDir,\n          \"11_final_translation.txt\"\n        );\n        const finalTranslation = loadText(finalTranslationPath, \"\");\n\n        // For final refinement, manage conversation history for long texts\n        const estimatedTranslationTokens = Math.ceil(\n          finalTranslation.length / 4\n        );\n        const estimatedReviewTokens = externalReviewContent\n          ? Math.ceil(externalReviewContent.length / 4)\n          : 0;\n\n        // Get model's context limit (same as in step 8)\n        const modelContextLimit =\n          MODEL_CONTEXT_LIMITS[this.config.modelName] || 0;\n\n        // Calculate current conversation size and determine if we need to reset\n        const currentConversationTokens = this.conversation.reduce(\n          (total, msg) => total + Math.ceil(msg.content.length / 4),\n          0\n        );\n\n        const resetThreshold = modelContextLimit * 0.5;\n        const wouldExceedLimit =\n          currentConversationTokens +\n            estimatedTranslationTokens +\n            estimatedReviewTokens >\n          resetThreshold;\n\n        // If text is very large or conversation history is getting too big, reset conversation\n        if (wouldExceedLimit) {\n          this.logger.info(\n            `📝 Large conversation detected (${currentConversationTokens.toLocaleString()} tokens + ${(\n              estimatedTranslationTokens + estimatedReviewTokens\n            ).toLocaleString()} new tokens). Starting fresh conversation for final refinement step.`\n          );\n          // Reset conversation with just the system message\n          const systemPrompt = prompts.system(\n            this.config.targetLanguage,\n            this.config.sourceLanguage,\n            this.config.customInstructions,\n            \"apply_feedback\"\n          );\n          this.conversation = [\n            {\n              role: \"system\",\n              content: systemPrompt,\n            },\n          ];\n          this.saveConversationHistory(\"Reset for final refinement\");\n        } else if (this.config.verbose) {\n          this.logger.info(\n            `📝 Continuing with existing conversation (${currentConversationTokens.toLocaleString()} tokens).`\n          );\n        }\n\n        // Skip this step if external review was skipped\n        let refinedFinalTranslation = finalTranslation;\n\n        // Define the refinedPath here (outside the if block)\n        const refinedPath = path.join(\n          this.intermediatesDir,\n          \"13_refined_final_translation.txt\"\n        );\n\n        if (!this.config.skipExternalReview) {\n          const finalRefinementPrompt = prompts.applyExternalFeedback(\n            this.config.targetLanguage,\n            this.config.sourceLanguage,\n            this.config.sourceText,\n            finalTranslation,\n            externalReviewContent\n          );\n\n          const refinedResponse = await this.callAiService(\n            finalRefinementPrompt\n          );\n\n          // Get the refined translation with continuation check\n          refinedFinalTranslation = await this.extractAndContinueTagContent(\n            refinedResponse,\n            \"refined_final_translation\",\n            refinedPath\n          );\n        } else {\n          // If external review is skipped, just save the final translation as the refined one\n          saveText(refinedPath, refinedFinalTranslation);\n        }\n\n        // Add to output files dictionary\n        this.outputFiles[\"13 Refined Final Translation\"] = refinedPath;\n\n        // Update latest translation content\n        latestTranslationContent = refinedFinalTranslation;\n\n        // Calculate metrics for this step\n        const metrics = calculateMetricsForLanguage(\n          refinedFinalTranslation,\n          this.config.targetLanguage,\n          false,\n          this.sourceMetrics\n        );\n\n        this.translationMetrics.set(\"refined_final_translation\", metrics);\n\n        // Add to translation steps\n        this.translationSteps.push(\"Final Refinement\");\n        this.succeedSpinner(\"✅ Final refinement completed\");\n        this.logger.success(\"Refined final translation saved to intermediates\");\n\n        // Save the final output\n        saveText(this.finalOutputPath, refinedFinalTranslation);\n\n        // Update step counter AFTER completing the step\n        this.stepCounter = 10;\n        // Save conversation history with updated step counter\n        this.saveConversationHistory(\"Completed Step 10: Final Refinement\");\n      }\n\n      // Save the final results\n      this.saveTranslationMetrics();\n\n      // Display final statistics\n      const endTime = Date.now();\n      const duration = (endTime - startTime) / 1000; // in seconds\n\n      this.logger.logHeader(\"Translation Complete\");\n      this.logger.log(\n        chalk.green(\n          `✅ Translation successfully completed in ${formatDuration(duration)}`\n        )\n      );\n      this.logger.log(\n        chalk.cyan(`   Input tokens: ${this.totalInputTokens.toLocaleString()}`)\n      );\n      this.logger.log(\n        chalk.cyan(\n          `   Output tokens: ${this.totalOutputTokens.toLocaleString()}`\n        )\n      );\n      this.logger.log(\n        chalk.yellow(\n          `💲 Estimated total cost: $${this.estimatedCost.toFixed(4)}`\n        )\n      );\n      this.logger.log(\n        chalk.green(`📁 Intermediate files saved to: ${this.intermediatesDir}`)\n      );\n      this.logger.log(\n        chalk.green(`📄 Final output saved to: ${this.finalOutputPath}`)\n      );\n\n      // Make sure to stop the spinner when we're done\n      this.stopSpinner();\n    } catch (error) {\n      // Make sure to stop the spinner on error\n      this.stopSpinner();\n\n      // Save whatever we have so far\n      this.saveLatestTranslationOnError();\n      throw error;\n    }\n  }\n\n  /**\n   * Save conversation history\n   */\n  private saveConversationHistory(label = \"Update\"): void {\n    try {\n      // Create metadata object\n      const conversationWithMetadata = {\n        metadata: {\n          timestamp: new Date().toISOString(),\n          label: label,\n          step: this.stepCounter,\n          totalTokens: this.totalTokens,\n          totalInputTokens: this.totalInputTokens,\n          totalOutputTokens: this.totalOutputTokens,\n          estimatedCost: this.estimatedCost,\n        },\n        conversation: this.conversation,\n      };\n\n      // Save as JSON\n      saveJson(this.conversationJsonPath, conversationWithMetadata);\n      this.outputFiles[\"Conversation History (JSON)\"] =\n        this.conversationJsonPath;\n\n      // Also save in human-readable format\n      let readableHistory = `# Translation Conversation History\\n\\n`;\n      readableHistory += `Last update: ${new Date().toISOString()}\\n`;\n      readableHistory += `Label: ${label}\\n`;\n      readableHistory += `Step: ${this.stepCounter}\\n`;\n      readableHistory += `Total tokens used: ${this.totalTokens.toLocaleString()}\\n`;\n      readableHistory += `Input tokens: ${this.totalInputTokens.toLocaleString()}\\n`;\n      readableHistory += `Output tokens: ${this.totalOutputTokens.toLocaleString()}\\n`;\n      readableHistory += `Estimated total cost: $${this.estimatedCost.toFixed(\n        4\n      )}\\n\\n`;\n      readableHistory += `${\"=\".repeat(80)}\\n\\n`;\n\n      this.conversation.forEach((message, index) => {\n        if (index > 0) readableHistory += \"\\n\\n\" + \"-\".repeat(80) + \"\\n\\n\";\n        readableHistory += `## ${message.role.toUpperCase()}:\\n\\n${\n          message.content\n        }`;\n      });\n\n      saveText(this.conversationTextPath, readableHistory);\n      this.outputFiles[\"Conversation History (Text)\"] =\n        this.conversationTextPath;\n    } catch (error) {\n      this.logger.warn(\n        `⚠️ Warning: Failed to save conversation history: ${error}`\n      );\n    }\n  }\n\n  /**\n   * Save translation metrics\n   */\n  private saveTranslationMetrics(): void {\n    try {\n      // Convert metrics Map to an object for saving\n      const metricsObject: Record<string, any> = {\n        source: this.sourceMetrics,\n      };\n\n      this.translationMetrics.forEach((value, key) => {\n        metricsObject[key] = value;\n      });\n\n      // Save to intermediates directory\n      saveJson(this.metricsPath, metricsObject);\n      this.outputFiles[\"Translation Metrics\"] = this.metricsPath;\n\n      this.logger.success(\n        `📊 Translation metrics saved to ${this.metricsPath}`\n      );\n    } catch (error) {\n      this.logger.warn(`⚠️ Warning: Failed to save metrics: ${error}`);\n    }\n  }\n\n  /**\n   * Call AI service with retry logic\n   */\n  private async callAiService(\n    prompt: string,\n    retryCount = 0,\n    isExternalReview = false\n  ): Promise<string> {\n    let currentStepLabel: string = \"Unknown Step\";\n    let currentStepKey: string | undefined;\n\n    try {\n      // Prepare a descriptive step name for logging\n      const stepName =\n        this.translationSteps.length > 0\n          ? this.translationSteps[this.translationSteps.length - 1]\n          : \"Initial Step\";\n\n      currentStepLabel = isExternalReview\n        ? `External Review`\n        : `Step ${this.stepCounter} - ${stepName}`;\n\n      // Determine current step for system prompt\n      if (!isExternalReview) {\n        switch (this.stepCounter) {\n          case 1:\n            currentStepKey = \"initial_analysis\";\n            break;\n          case 2:\n            currentStepKey = \"expression_exploration\";\n            break;\n          case 3:\n            currentStepKey = \"cultural_discussion\";\n            break;\n          case 4:\n            currentStepKey = \"title_options\";\n            break;\n          case 5:\n            currentStepKey = \"first_translation\";\n            break;\n          case 6:\n            currentStepKey = \"self_critique\";\n            break;\n          case 7:\n            currentStepKey = \"further_refinement\";\n            break;\n          case 8:\n            currentStepKey = \"final_translation\";\n            break;\n          case 10:\n            currentStepKey = \"apply_feedback\";\n            break;\n        }\n      } else {\n        currentStepKey = \"external_review\";\n      }\n\n      // For external review, start a fresh conversation to avoid biases\n      let messages: ConversationMessage[] = [];\n\n      if (isExternalReview) {\n        // Create a new conversation for external review\n        messages.push({\n          role: \"system\",\n          content: prompts.externalReviewSystem(\n            this.config.targetLanguage,\n            this.config.sourceLanguage\n          ),\n        });\n        messages.push({\n          role: \"user\",\n          content: prompt,\n        });\n      } else {\n        // Set step-specific system prompt\n        const systemPrompt = prompts.system(\n          this.config.targetLanguage,\n          this.config.sourceLanguage,\n          this.config.customInstructions,\n          currentStepKey\n        );\n\n        // Replace the existing system message with an updated one\n        if (\n          this.conversation.length > 0 &&\n          this.conversation[0].role === \"system\"\n        ) {\n          this.conversation[0].content = systemPrompt;\n        } else {\n          // If there's no system message for some reason, add one\n          this.conversation.unshift({\n            role: \"system\",\n            content: systemPrompt,\n          });\n        }\n\n        // Add the prompt to the main conversation\n        this.conversation.push({\n          role: \"user\",\n          content: prompt,\n        });\n\n        // Manage conversation context before API call to prevent token limit issues\n        this.manageConversationContext(this.config.modelName);\n\n        messages = this.conversation;\n      }\n\n      // Save conversation history before API call\n      if (!isExternalReview) {\n        this.saveConversationHistory(currentStepLabel);\n      }\n\n      // Prepare options for AI call\n      const options: AiRequestOptions = {\n        modelName: this.config.modelName,\n        maxOutputTokens: this.config.maxOutputTokens,\n        reasoningEffort: this.config.reasoningEffort,\n        temperature: 0.7,\n      };\n\n      // Call appropriate AI service\n      const response = await this.aiService.generateResponse(messages, options);\n\n      // Update token counts and cost\n      this.totalInputTokens += response.inputTokens;\n      this.totalOutputTokens += response.outputTokens;\n      this.totalTokens = this.totalInputTokens + this.totalOutputTokens;\n      this.updateCost(\n        response.modelName,\n        response.inputTokens,\n        response.outputTokens\n      );\n\n      // Log TPS if verbose\n      if (this.config.verbose) {\n        const tps =\n          response.duration > 0\n            ? (response.outputTokens / response.duration).toFixed(2)\n            : \"Infinity\";\n\n        this.logger.log(chalk.cyan(`  ⚡ Tokens per second (output): ${tps}`));\n        this.logger.log(\n          chalk.dim(\n            `     (Duration: ${response.duration.toFixed(2)}s, Output Tokens: ${\n              response.outputTokens\n            })`\n          )\n        );\n      }\n\n      // Add the response to the conversation (only for main conversation)\n      if (!isExternalReview) {\n        this.conversation.push({\n          role: \"assistant\",\n          content: response.content,\n        });\n\n        // Save conversation history after API call\n        this.saveConversationHistory(currentStepLabel);\n      }\n\n      return response.content;\n    } catch (error: any) {\n      this.failSpinner(\n        `API call failed (attempt ${retryCount + 1}/${\n          this.config.maxRetries + 1\n        })`\n      );\n\n      console.error(\n        chalk.red(`❌ Error during API call (Attempt ${retryCount + 1}):`),\n        error?.message || error\n      );\n\n      // Save conversation history even on error\n      if (!isExternalReview) {\n        this.saveConversationHistory(\n          `API Call Error - ${currentStepLabel} - Attempt ${retryCount + 1}`\n        );\n      }\n\n      // Check if this is a context length error\n      const isContextLengthError =\n        error?.message?.includes(\"context length\") ||\n        error?.message?.includes(\"maximum context length\") ||\n        error?.message?.includes(\"tokens exceeds the model's context length\") ||\n        error?.code === \"context_length_exceeded\";\n\n      if (isContextLengthError && !isExternalReview) {\n        this.logger.warn(\n          \"🔄 Context length exceeded. Adjusting conversation history...\"\n        );\n\n        // Get system message\n        const systemMessage = this.conversation[0];\n\n        // For all models, try to keep more context by removing some middle messages\n        if (this.conversation.length > 6) {\n          this.logger.info(\n            \"📝 Using selective pruning for context length error...\"\n          );\n\n          // Keep system message, first user message, and last 2-3 exchanges\n          const systemMessage = this.conversation[0];\n          const firstUserMessage = this.conversation.find(\n            (m) => m.role === \"user\"\n          );\n\n          // Keep just the latest user message (the prompt we just tried to use)\n          const latestUserMessage = this.conversation\n            .filter((m) => m.role === \"user\")\n            .slice(-1)[0];\n\n          // Reset conversation to just the essential messages\n          if (firstUserMessage && firstUserMessage !== latestUserMessage) {\n            this.conversation = [\n              systemMessage,\n              firstUserMessage,\n              latestUserMessage,\n            ];\n          } else {\n            this.conversation = [systemMessage, latestUserMessage];\n          }\n\n          this.logger.info(\n            `📝 Pruned conversation to ${this.conversation.length} messages, keeping essential context`\n          );\n        } else {\n          // For smaller conversations, just keep system + current prompt\n          const latestUserMessage =\n            this.conversation[this.conversation.length - 1];\n\n          this.conversation = [systemMessage, latestUserMessage];\n\n          this.logger.info(\n            \"📝 Conversation history aggressively pruned to only system message and current prompt\"\n          );\n        }\n\n        this.saveConversationHistory(\"Pruned for context length error\");\n      }\n\n      if (retryCount < this.config.maxRetries) {\n        this.logger.warn(\n          `  ↪ Retrying in ${this.config.retryDelay / 1000} seconds...`\n        );\n\n        await new Promise((resolve) =>\n          setTimeout(resolve, this.config.retryDelay)\n        );\n\n        this.startSpinnerWithTimer(\"Retrying API call\");\n        return this.callAiService(prompt, retryCount + 1, isExternalReview);\n      }\n\n      // Make sure to stop the spinner when maximum retries are reached\n      this.stopSpinner();\n      this.logger.error(\"❌ Error calling AI API after maximum retries\");\n      throw error;\n    }\n  }\n\n  /**\n   * Update cost calculations\n   */\n  private updateCost(\n    model: string,\n    inputTokens: number,\n    outputTokens: number\n  ): void {\n    try {\n      const costResult = this.aiService.calculateCost(\n        model,\n        inputTokens,\n        outputTokens\n      );\n      this.estimatedCost += costResult.totalCost;\n\n      if (this.config.verbose) {\n        this.logger.log(\n          chalk.dim(\n            `  💲 Cost for this call ($${costResult.totalCost.toFixed(\n              5\n            )}): Input $${costResult.inputCost.toFixed(\n              5\n            )} (${inputTokens} tokens) + Output $${costResult.outputCost.toFixed(\n              5\n            )} (${outputTokens} tokens)`\n          )\n        );\n      }\n    } catch (error) {\n      this.logger.warn(`⚠️ Error calculating cost: ${error}`);\n    }\n  }\n\n  /**\n   * Display source metrics\n   */\n  private displaySourceMetrics(): void {\n    this.logger.log(chalk.cyan(`📏 Source text metrics:`));\n\n    if (this.config.sourceLanguage) {\n      this.logger.log(chalk.cyan(`   Language: ${this.config.sourceLanguage}`));\n    } else {\n      this.logger.log(chalk.cyan(`   Language: (Auto-detected/Not specified)`));\n    }\n\n    this.logger.log(\n      chalk.cyan(\n        `   Word count: ${this.sourceMetrics.sourceWordCount.toLocaleString()}`\n      )\n    );\n\n    this.logger.log(\n      chalk.cyan(\n        `   Character count: ${this.sourceMetrics.sourceCharCount.toLocaleString()}`\n      )\n    );\n\n    this.logger.log(\n      chalk.cyan(\n        `   Estimated reading time: ${formatTime(\n          this.sourceMetrics.estimatedReadingTime\n        )}`\n      )\n    );\n  }\n\n  /**\n   * Display comparison with source text\n   */\n  private displayComparisonWithSource(metrics: TranslationMetrics): void {\n    // Check if source counts are valid\n    const validSource =\n      this.sourceMetrics &&\n      this.sourceMetrics.sourceWordCount > 0 &&\n      this.sourceMetrics.sourceCharCount > 0;\n\n    const wordCountRatio = validSource\n      ? (\n          (metrics.targetWordCount / this.sourceMetrics.sourceWordCount) *\n          100\n        ).toFixed(1)\n      : \"N/A\";\n\n    const charCountRatio = validSource\n      ? (\n          (metrics.targetCharCount / this.sourceMetrics.sourceCharCount) *\n          100\n        ).toFixed(1)\n      : \"N/A\";\n\n    this.logger.log(chalk.magenta(`📊 Comparison with source text:`));\n\n    this.logger.log(\n      chalk.magenta(\n        `   Word count ratio: ${wordCountRatio}${\n          validSource ? \"%\" : \"\"\n        } of source`\n      )\n    );\n\n    this.logger.log(\n      chalk.magenta(\n        `   Character count ratio: ${charCountRatio}${\n          validSource ? \"%\" : \"\"\n        } of source`\n      )\n    );\n\n    // Visualize the difference\n    const ratioValue = validSource\n      ? metrics.targetWordCount / this.sourceMetrics.sourceWordCount\n      : 0;\n\n    const wordBar = createProgressBar(ratioValue, validSource);\n    this.logger.log(chalk.magenta(`   Word ratio: ${wordBar}`));\n  }\n\n  /**\n   * Save the latest translation on error\n   */\n  public saveLatestTranslationOnError(): void {\n    const translationFileOrder = [\n      \"13_refined_final_translation.txt\",\n      \"11_final_translation.txt\",\n      \"09_further_improved_translation.txt\",\n      \"07_improved_translation.txt\",\n      \"05_first_translation.txt\",\n    ];\n\n    let latestFileFound: string | null = findLatestFile(\n      this.intermediatesDir,\n      translationFileOrder\n    );\n\n    if (latestFileFound) {\n      try {\n        const content = loadText(latestFileFound);\n        saveText(this.finalOutputPath, content);\n\n        console.log(\n          chalk.yellow(\n            `⚠️ Process interrupted. Saved latest available translation (${path.basename(\n              latestFileFound\n            )}) to: ${this.finalOutputPath}`\n          )\n        );\n      } catch (saveError) {\n        console.error(\n          chalk.red(\n            `❌ Failed to save latest translation on error from ${latestFileFound} to ${this.finalOutputPath}:`\n          ),\n          saveError\n        );\n      }\n    } else {\n      console.log(\n        chalk.yellow(\n          `⚠️ Process interrupted. No intermediate translation files found to save.`\n        )\n      );\n    }\n  }\n\n  /**\n   * Start spinner with elapsed time tracking\n   */\n  private startSpinnerWithTimer(message: string): void {\n    // Clear any existing interval\n    this.clearSpinnerInterval();\n\n    // Start spinner with initial message\n    this.spinner.start(message);\n\n    // Record start time\n    this.spinnerStartTime = performance.now();\n\n    // Set up interval to update spinner text with elapsed time\n    this.spinnerInterval = setInterval(() => {\n      const elapsedSeconds = (performance.now() - this.spinnerStartTime) / 1000;\n      this.spinner.text = `${message} (${elapsedSeconds.toFixed(1)}s)`;\n    }, 100); // Update every 100ms for smooth display\n  }\n\n  /**\n   * Clear spinner interval\n   */\n  private clearSpinnerInterval(): void {\n    if (this.spinnerInterval) {\n      clearInterval(this.spinnerInterval);\n      this.spinnerInterval = null;\n    }\n  }\n\n  /**\n   * Stop spinner and clear interval\n   */\n  private stopSpinner(): void {\n    this.clearSpinnerInterval();\n    this.spinner.stop();\n  }\n\n  /**\n   * Succeed spinner and clear interval\n   */\n  private succeedSpinner(message: string): void {\n    this.clearSpinnerInterval();\n    const elapsedSeconds = (performance.now() - this.spinnerStartTime) / 1000;\n    this.spinner.succeed(`${message} (${elapsedSeconds.toFixed(1)}s)`);\n  }\n\n  /**\n   * Fail spinner and clear interval\n   */\n  private failSpinner(message: string): void {\n    this.clearSpinnerInterval();\n    const elapsedSeconds = (performance.now() - this.spinnerStartTime) / 1000;\n    this.spinner.fail(`${message} (${elapsedSeconds.toFixed(1)}s)`);\n  }\n\n  /**\n   * Manage conversation context to prevent exceeding token limits\n   */\n  private manageConversationContext(modelName: string): void {\n    try {\n      // Skip if conversation has fewer than 3 messages (just system + 1-2 exchanges)\n      if (this.conversation.length < 3) {\n        return;\n      }\n\n      // Calculate rough token estimation for current conversation\n      let totalEstimatedTokens = 0;\n      for (const message of this.conversation) {\n        totalEstimatedTokens += Math.ceil(message.content.length / 4);\n      }\n\n      // Get model's context limit\n      let modelContextLimit = MODEL_CONTEXT_LIMITS[this.config.modelName] || 0;\n\n      // If no exact match, try prefix matching with common model prefixes\n      if (!modelContextLimit) {\n        const prefixMap: Record<string, number> = {\n          \"gpt-4.5\": 128000,\n          \"gpt-4o\": 128000,\n          \"gpt-4\": 8192,\n          \"gpt-3.5\": 4096,\n          \"claude-3-opus\": 200000,\n          \"claude-3-sonnet\": 200000,\n          \"claude-3-haiku\": 200000,\n          \"claude-3.5\": 200000,\n          \"claude-3-7\": 200000,\n        };\n\n        for (const [prefix, limit] of Object.entries(prefixMap)) {\n          if (\n            this.config.modelName.toLowerCase().startsWith(prefix.toLowerCase())\n          ) {\n            modelContextLimit = limit;\n            if (this.config.verbose) {\n              this.logger.info(\n                `📚 Matched model ${\n                  this.config.modelName\n                } to prefix ${prefix} with ${limit.toLocaleString()} context limit`\n              );\n            }\n            break;\n          }\n        }\n      }\n\n      if (!modelContextLimit) {\n        modelContextLimit = MODEL_CONTEXT_LIMITS.default || 16384; // Use default or fallback to 16K\n        this.logger.warn(\n          `⚠️ Unknown model ${\n            this.config.modelName\n          }, using default context limit of ${modelContextLimit.toLocaleString()} tokens`\n        );\n      }\n\n      // Use different thresholds based on model size\n      const warningThreshold = Math.floor(modelContextLimit * 0.7);\n      const tokenThreshold = Math.floor(modelContextLimit * 0.9);\n\n      // Show current token usage in verbose mode\n      if (this.config.verbose) {\n        const usagePercentage = (\n          (totalEstimatedTokens / modelContextLimit) *\n          100\n        ).toFixed(1);\n        this.logger.info(\n          `ℹ️ Current conversation size: ~${totalEstimatedTokens.toLocaleString()} tokens (${usagePercentage}% of ${modelContextLimit.toLocaleString()} context limit)`\n        );\n      }\n\n      // Warning zone: 70% of limit\n      if (\n        totalEstimatedTokens > warningThreshold &&\n        totalEstimatedTokens <= tokenThreshold\n      ) {\n        this.logger.warn(\n          `⚠️ Approaching context limit (est. ${totalEstimatedTokens.toLocaleString()} tokens, ${(\n            (totalEstimatedTokens / modelContextLimit) *\n            100\n          ).toFixed(1)}% of limit). No trimming yet.`\n        );\n      }\n\n      // If we exceed threshold (90% of limit), trim conversation\n      if (totalEstimatedTokens > tokenThreshold) {\n        this.logger.warn(\n          `⚠️ Reached token threshold (est. ${totalEstimatedTokens.toLocaleString()} tokens, ${(\n            (totalEstimatedTokens / modelContextLimit) *\n            100\n          ).toFixed(\n            1\n          )}% of ${modelContextLimit.toLocaleString()} context limit). Trimming conversation history...`\n        );\n\n        // Always keep system message (first message) and last two exchanges (4 messages)\n        const systemMessage = this.conversation[0];\n        const recentMessages = this.conversation.slice(-4);\n\n        // Replace conversation with system message + recent messages\n        this.conversation = [systemMessage, ...recentMessages];\n\n        // Recalculate token estimate after trimming\n        let newEstimate = 0;\n        for (const message of this.conversation) {\n          newEstimate += Math.ceil(message.content.length / 4);\n        }\n\n        this.logger.info(\n          `ℹ️ Trimmed conversation history to ${\n            this.conversation.length\n          } messages (est. ${newEstimate.toLocaleString()} tokens, ${(\n            (newEstimate / modelContextLimit) *\n            100\n          ).toFixed(1)}% of limit)`\n        );\n      }\n    } catch (error) {\n      // Don't let token management errors block the workflow\n      this.logger.error(\n        `❌ Error in conversation context management: ${error}`\n      );\n    }\n  }\n\n  /**\n   * Handle translation continuation for potentially incomplete translations\n   * @param sourceText Original source text\n   * @param translationText Current translation (potentially incomplete)\n   * @param translationPath Path to save the translation\n   * @param tag XML tag name used in the translation\n   * @param forceCheck Force continuation regardless of completion check (for known truncation)\n   * @returns Completed translation or the original if no continuation needed\n   */\n  private async handleTranslationContinuation(\n    sourceText: string,\n    translationText: string,\n    translationPath: string,\n    tag: string,\n    forceCheck = false\n  ): Promise<string> {\n    try {\n      // First check if the translation is complete (unless we're forcing continuation)\n      const completionCheck = await checkTranslationCompletion(\n        sourceText,\n        translationText,\n        this.config.verbose\n      );\n\n      if (!forceCheck && (!completionCheck || !completionCheck.continue)) {\n        // Translation is complete or check failed - return original\n        // Reset continuation tracking\n        this.continuationAttempts = 0;\n        this.previousTranslationLength = 0;\n        this.previousSourceLine = \"\";\n        return translationText;\n      }\n\n      // Check if we're making minimal progress\n      if (translationText.length === this.previousTranslationLength) {\n        this.continuationAttempts++;\n        // If we've tried 3 times with no change, break the loop\n        if (this.continuationAttempts >= 3) {\n          this.logger.warn(\n            `⚠️ Breaking continuation loop after ${this.continuationAttempts} attempts with no progress`\n          );\n          this.continuationAttempts = 0;\n          this.previousTranslationLength = 0;\n          this.previousSourceLine = \"\";\n          return translationText;\n        }\n      } else if (\n        translationText.length - this.previousTranslationLength <\n          this.minimumMeaningfulProgress &&\n        this.previousTranslationLength > 0\n      ) {\n        // We're making very little progress (less than minimumMeaningfulProgress chars)\n        this.continuationAttempts++;\n        if (this.continuationAttempts >= 2) {\n          this.logger.warn(\n            `⚠️ Breaking continuation loop after ${\n              this.continuationAttempts\n            } attempts with minimal progress (only ${\n              translationText.length - this.previousTranslationLength\n            } chars added)`\n          );\n          this.continuationAttempts = 0;\n          this.previousTranslationLength = 0;\n          this.previousSourceLine = \"\";\n          return translationText;\n        }\n      } else {\n        // Reset counter when making good progress\n        this.continuationAttempts = 0;\n      }\n\n      // Store current length for next comparison\n      this.previousTranslationLength = translationText.length;\n\n      // Determine if we need continuation\n      const needsContinuation =\n        forceCheck || (completionCheck && completionCheck.continue);\n      if (!needsContinuation) {\n        return translationText;\n      }\n\n      // For forced check with no completion data, use last paragraph as continuation point\n      let targetLastLine = \"\";\n      let sourceLine = \"\";\n\n      if (\n        forceCheck &&\n        (!completionCheck ||\n          !completionCheck.targetLastLine ||\n          !completionCheck.sourceLine)\n      ) {\n        // Find the last paragraph of the translated text\n        const paragraphs = translationText.split(/\\n\\n+/);\n        if (paragraphs.length > 0) {\n          targetLastLine = paragraphs[paragraphs.length - 1].trim();\n          this.logger.info(\n            `📝 Using last paragraph as continuation point for forced continuation`\n          );\n        } else {\n          targetLastLine = translationText.split(\"\\n\").pop() || \"\";\n          this.logger.info(\n            `📝 Using last line as continuation point for forced continuation`\n          );\n        }\n\n        // Use approximate source position - midpoint if we can't determine\n        const sourceLines = sourceText.split(\"\\n\");\n        const midpoint = Math.floor(sourceLines.length / 2);\n        sourceLine = sourceLines[midpoint] || \"\";\n      } else {\n        // Use the identified continuation points\n        targetLastLine = completionCheck?.targetLastLine || \"\";\n        sourceLine = completionCheck?.sourceLine || \"\";\n      }\n\n      // Check if we're trying to continue from the same source line as before\n      if (sourceLine && sourceLine === this.previousSourceLine) {\n        this.continuationAttempts++;\n\n        // If we've tried to continue from the same source line twice, assume we're at the end\n        if (this.continuationAttempts >= 2) {\n          this.logger.warn(\n            `⚠️ Breaking continuation loop: detected same source line \"${sourceLine.substring(\n              0,\n              30\n            )}...\" in consecutive attempts`\n          );\n          this.logger.info(\n            `📝 This likely means we've reached the end of the document or the model can't make further progress`\n          );\n\n          // Reset tracking variables\n          this.continuationAttempts = 0;\n          this.previousTranslationLength = 0;\n          this.previousSourceLine = \"\";\n\n          return translationText;\n        }\n      } else {\n        // Different source line, reset attempt counter for this check\n        this.continuationAttempts = 0;\n      }\n\n      // Store current source line for next comparison\n      this.previousSourceLine = sourceLine;\n\n      // We need to continue translation - log information\n      this.logger.warn(\n        `⚠️ Translation appears to be incomplete${\n          forceCheck ? \" (forced check due to truncation)\" : \"\"\n        }. Attempting to continue from identified point.`\n      );\n\n      // Create backup of partial translation\n      const backupPath = backupPartialTranslation(translationPath);\n      if (backupPath) {\n        this.logger.info(`📋 Backed up partial translation to: ${backupPath}`);\n      }\n\n      // NEW APPROACH: Use a simple continuation prompt that preserves conversation context\n      // instead of creating a completely new contextual prompt that might lose nuances\n\n      const simpleContinuationPrompt =\n        createSimpleContinuationPrompt(targetLastLine);\n\n      this.startSpinnerWithTimer(\"Continuing incomplete translation\");\n\n      try {\n        // Instead of creating a new conversation, just add the continuation request to the existing one\n        // This preserves all the context from previous steps\n        this.conversation.push({\n          role: \"user\",\n          content: simpleContinuationPrompt,\n        });\n\n        // Save current conversation state before continuation\n        this.saveConversationHistory(\"Before continuation attempt\");\n\n        // Call the AI service with the existing conversation that now has the continuation request\n        const continuationResponse = await this.aiService.generateResponse(\n          this.conversation,\n          {\n            modelName: this.config.modelName,\n            temperature: 0.7,\n            maxOutputTokens: this.config.maxOutputTokens,\n            reasoningEffort: this.config.reasoningEffort,\n          }\n        );\n\n        // Add the model's response to the conversation\n        this.conversation.push({\n          role: \"assistant\",\n          content: continuationResponse.content,\n        });\n\n        // Save updated conversation history\n        this.saveConversationHistory(\"After continuation attempt\");\n\n        // Combine the partial translation with the continuation\n        const combinedTranslation = combineTranslation(\n          translationText,\n          continuationResponse.content,\n          targetLastLine\n        );\n\n        // Check if we successfully combined the translations\n        if (!combinedTranslation) {\n          this.logger.error(\n            \"❌ Failed to combine partial translation with continuation\"\n          );\n          // Reset counters on failure\n          this.continuationAttempts = 0;\n          this.previousTranslationLength = 0;\n          this.previousSourceLine = \"\";\n          return translationText; // Return original on failure\n        }\n\n        // Always save the combined translation immediately after each successful continuation\n        saveText(translationPath, combinedTranslation);\n        this.logger.success(\n          `✅ Saved continued translation (${combinedTranslation.length} characters)`\n        );\n\n        // Check if the combined translation is complete\n        const secondCheck = await checkTranslationCompletion(\n          sourceText,\n          combinedTranslation,\n          this.config.verbose\n        );\n\n        if (secondCheck && secondCheck.continue) {\n          // Still incomplete - recursive call to continue further\n          this.logger.warn(\n            `⚠️ Translation still incomplete after continuation. Attempting another continuation.`\n          );\n\n          // Do NOT pass forceCheck in recursive calls - let the completion check determine if we need more\n          return this.handleTranslationContinuation(\n            sourceText,\n            combinedTranslation, // Pass the updated combined translation for the next continuation\n            translationPath,\n            tag,\n            false // Don't force on recursive calls\n          );\n        }\n\n        this.succeedSpinner(\n          \"✅ Successfully continued and completed translation\"\n        );\n        // Reset counters on successful completion\n        this.continuationAttempts = 0;\n        this.previousTranslationLength = 0;\n        this.previousSourceLine = \"\";\n        return combinedTranslation;\n      } catch (error) {\n        this.logger.error(`❌ Error during translation continuation: ${error}`);\n        this.failSpinner(\"❌ Failed to continue translation\");\n\n        // Reset counters on error\n        this.continuationAttempts = 0;\n        this.previousTranslationLength = 0;\n        this.previousSourceLine = \"\";\n\n        return translationText; // Return original on failure\n      }\n    } catch (error) {\n      this.logger.error(`❌ Error in continuation handling: ${error}`);\n      return translationText; // Return original on any error\n    }\n  }\n\n  // Add this function to extract tag content with continuation check\n  private async extractAndContinueTagContent(\n    response: string,\n    tag: string,\n    outputPath: string\n  ): Promise<string> {\n    try {\n      // Check if there's an opening tag but no closing tag (truncation indicator)\n      const openTagRegex = new RegExp(`<${tag}>`, \"s\");\n      const closeTagRegex = new RegExp(`</${tag}>`, \"s\");\n      const hasOpenTag = openTagRegex.test(response);\n      const hasCloseTag = closeTagRegex.test(response);\n\n      if (hasOpenTag && !hasCloseTag) {\n        this.logger.warn(\n          `⚠️ Detected truncated response: Opening <${tag}> tag found but no closing tag. Response likely cut off.`\n        );\n      }\n\n      // Extract content using existing method (now improved to handle truncation)\n      const content = this.xmlProcessor.extractTagContent(response, tag);\n\n      // Check if content was successfully extracted\n      if (!content || content.trim().length === 0) {\n        this.logger.warn(\n          `⚠️ Warning: Could not extract content from <${tag}> tags. The response might be malformed.`\n        );\n\n        // Save the entire response to a debug file in case of extraction failure\n        const debugPath = path.join(\n          this.intermediatesDir,\n          `${tag}_extraction_debug.txt`\n        );\n        saveText(debugPath, response);\n\n        this.logger.info(\n          `📝 Saved full response to ${debugPath} for debugging.`\n        );\n\n        // Try to safely extract the content with a different approach if the tag is missing\n        let extractedContent = \"\";\n\n        // If this is a translation, try to find the actual translation content\n        if (tag.includes(\"translation\")) {\n          // First check if there's an opening tag but no closing tag\n          if (hasOpenTag && !hasCloseTag) {\n            // Extract everything after the opening tag as our content\n            const openTagIndex = response.indexOf(`<${tag}>`);\n            if (openTagIndex !== -1) {\n              extractedContent = response\n                .substring(openTagIndex + tag.length + 2)\n                .trim();\n              this.logger.info(\n                `📝 Extracted content from truncated response starting with <${tag}> tag.`\n              );\n            }\n          }\n\n          // If still no content, try other extraction methods\n          if (!extractedContent) {\n            // Look for common patterns in the response that might indicate where the translation starts\n            const possibleStart = response.indexOf(\"```\");\n            if (possibleStart !== -1) {\n              const possibleEnd = response.lastIndexOf(\"```\");\n              if (possibleEnd > possibleStart && possibleEnd !== -1) {\n                extractedContent = response\n                  .substring(possibleStart + 3, possibleEnd)\n                  .trim();\n                this.logger.info(\n                  `📝 Attempted to extract translation using code block markers.`\n                );\n              } else {\n                // Try the entire response without the initial system message parts\n                extractedContent = response.trim();\n                this.logger.info(\n                  `📝 Using entire response as translation content.`\n                );\n              }\n            }\n          }\n        }\n\n        if (extractedContent) {\n          // Clean up any XML tags and continuation markers\n          extractedContent = this.cleanTranslationContent(extractedContent);\n\n          saveText(outputPath, extractedContent);\n          this.logger.info(`📝 Saved extracted content as fallback.`);\n\n          // Even for fallback content, check if continuation is needed\n          const needsContinuation = hasOpenTag && !hasCloseTag;\n          if (needsContinuation) {\n            this.logger.warn(\n              `⚠️ Fallback extraction from truncated response. Will attempt continuation.`\n            );\n\n            const continuedContent = await this.handleTranslationContinuation(\n              this.config.sourceText,\n              extractedContent,\n              outputPath,\n              tag,\n              true // Force continuation for fallback extraction from truncated response\n            );\n\n            return continuedContent;\n          }\n\n          return extractedContent;\n        }\n\n        // Return empty string if no content could be extracted\n        // This will be handled by the calling method\n        return \"\";\n      }\n\n      // Clean up the extracted content (remove any XML tags, continuation markers)\n      const cleanedContent = this.cleanTranslationContent(content);\n\n      // Save cleaned content to file\n      saveText(outputPath, cleanedContent);\n\n      // Log what we're doing\n      this.logger.info(\n        `📊 Extracted ${cleanedContent.length} characters for ${tag}. Checking if translation is complete...`\n      );\n\n      // If we detected truncation earlier, we definitely need continuation\n      const needsContinuation = hasOpenTag && !hasCloseTag;\n      if (needsContinuation) {\n        this.logger.warn(\n          `⚠️ Response was truncated. Will attempt continuation regardless of completion check result.`\n        );\n      }\n\n      // Check for continuation and handle if needed\n      const completedContent = await this.handleTranslationContinuation(\n        this.config.sourceText,\n        cleanedContent,\n        outputPath,\n        tag,\n        needsContinuation // Force continuation if truncation was detected\n      );\n\n      // Clean up the final content one more time before returning\n      const finalCleanedContent =\n        this.cleanTranslationContent(completedContent);\n\n      // Save final cleaned content if different\n      if (finalCleanedContent !== completedContent) {\n        saveText(outputPath, finalCleanedContent);\n        this.logger.info(`📝 Saved final cleaned content.`);\n      }\n\n      // Return the completed content\n      return finalCleanedContent;\n    } catch (error) {\n      this.logger.error(\n        `❌ Error extracting and continuing content for ${tag}: ${error}`\n      );\n\n      // Return empty string on error\n      return \"\";\n    }\n  }\n\n  /**\n   * Clean translation content by removing XML tags and continuation markers\n   */\n  private cleanTranslationContent(content: string): string {\n    if (!content) return \"\";\n\n    try {\n      // Use the utility functions from continuation.ts\n      // First, remove any unpaired XML tags\n      const contentWithoutTags = removeUnpairedXmlTags(content);\n\n      // Then remove any continuation markers\n      const cleanedContent = removeContinuationMarkers(contentWithoutTags);\n\n      return cleanedContent;\n    } catch (error) {\n      this.logger.warn(`⚠️ Error cleaning content: ${error}`);\n      return content; // Return original on error\n    }\n  }\n\n  /**\n   * Get the final translation output path\n   */\n  getFinalOutputPath(): string {\n    return this.finalOutputPath;\n  }\n\n  /**\n   * Display human-readable token estimation (helper)\n   */\n  private displayTokenEstimation(text: string): void {\n    const tokens = Math.ceil(text.length / 4);\n    this.logger.info(\n      `📊 Estimated tokens: ${tokens.toLocaleString()} (${text.length.toLocaleString()} chars)`\n    );\n  }\n}\n","/**\n * Dadeumi - AI-powered literary translation workflow\n *\n * This module exports the Dadeumi public API for use as a library.\n */\n\n// Re-export types\nexport interface ConversationMessage {\n  role: \"system\" | \"user\" | \"assistant\";\n  content: string;\n}\n\nexport interface TranslationConfig {\n  sourceLanguage?: string; // Optional, can be auto-detected\n  targetLanguage: string;\n  sourceText: string;\n  outputDir: string;\n  modelName: string;\n  verbose: boolean;\n  maxRetries: number;\n  retryDelay: number;\n  skipExternalReview: boolean;\n  customInstructions?: string;\n  reasoningEffort: \"low\" | \"medium\" | \"high\";\n  maxOutputTokens: number;\n  originalFilename: string; // Used for final output filename\n  originalExtension: string; // Used for final output filename\n  inputPath: string; // For convenience\n}\n\nexport interface TranslationMetrics {\n  sourceWordCount: number;\n  targetWordCount: number;\n  sourceCharCount: number;\n  targetCharCount: number;\n  ratio: number;\n  estimatedReadingTime: number;\n}\n\n// Re-export main functionality\nexport { TranslationWorkflow } from \"./core/TranslationWorkflow\";\nexport { AiService } from \"./services/ai\";\nexport { XmlProcessor } from \"./utils/xml\";\nexport { Logger } from \"./utils/logger\";\n\n// Re-export utility functions\nexport {\n  calculateMetrics,\n  calculateMetricsForLanguage,\n  formatTime,\n  formatDuration,\n  saveText,\n  loadText,\n  saveJson,\n  loadJson,\n  findLatestFile,\n  ensureDirectoryExists,\n} from \"./utils\";\n\n/**\n * Simple standalone function to translate text\n */\nexport async function translate(\n  text: string,\n  targetLanguage: string,\n  options?: {\n    sourceLanguage?: string;\n    modelName?: string;\n    outputDir?: string;\n    verbose?: boolean;\n    skipExternalReview?: boolean;\n    customInstructions?: string;\n  }\n): Promise<string> {\n  // Use current directory as output if not specified\n  const outputDir = options?.outputDir || process.cwd();\n  const { TranslationWorkflow } = await import(\"./core/TranslationWorkflow\");\n\n  // Create a translation config\n  const config: TranslationConfig = {\n    sourceText: text,\n    targetLanguage,\n    sourceLanguage: options?.sourceLanguage,\n    modelName: options?.modelName || \"gpt-4o\",\n    outputDir,\n    verbose: options?.verbose !== undefined ? options.verbose : false,\n    maxRetries: 3,\n    retryDelay: 5000,\n    skipExternalReview:\n      options?.skipExternalReview !== undefined\n        ? options.skipExternalReview\n        : false,\n    customInstructions: options?.customInstructions,\n    reasoningEffort: \"medium\",\n    maxOutputTokens: 30000,\n    originalFilename: \"translation\",\n    originalExtension: \".txt\",\n    inputPath: \"memory\", // No actual file input\n  };\n\n  // Create and execute workflow\n  const workflow = new TranslationWorkflow(config);\n  await workflow.execute();\n\n  // Return the translated text from the output file\n  const outputPath = `${outputDir}/translation-${targetLanguage}.txt`;\n\n  // Use dynamic import for fs to avoid bundling issues\n  const fs = await import(\"fs\");\n  if (fs.existsSync(outputPath)) {\n    return fs.readFileSync(outputPath, \"utf-8\");\n  }\n\n  throw new Error(\"Translation failed: no output file generated\");\n}\n"]}