Oracle B2C Service offers translation capabilities in the Incident threads and Chat modules of the Agent Browser UI. Both features require a language detection External Object (XO) endpoint and a language translation External Object (XO) endpoint. Refer to Answer ID 12891 for Incident threads and Answer ID 12842 for Chat for further details. This article explains how the language detection and translation endpoints can be configured using Oracle Cloud Infrastructure (OCI). There are a couple of ways to achieve this with OCI: one using the Language service and another using the Generative AI service—both native to OCI. The following sections provide configuration details for both options.

B2C Service Translation Configuration Technical Design

1. Using OCI Language Service

The OCI Language service requires separate request paths for language detection and language translation. The host-name for the service is region-specific and can be found on the Language Service API documentation page. The request path for language detection is batchDetectDominantLanguage, and for language translation, it is batchLanguageTranslation. Requests to the Language service can be authenticated using the OCI Signature v1 authentication method.

An advantage of using the OCI Language Service is that the request formats for detection and translation expected by the service are the same as those sent by B2C Service, and the respective response formats returned by the service match what B2C Service expects.

1.1 Configuration Steps in B2C Service

1.1.1 Create External Object & Integration (XOI) configuration for Language Detection

Create External Object & Integration (XOI) Configuration for Language Detection

1.1.2 Create External Object & Integration (XOI) configuration for Language Translation

Create External Object & Integration (XOI) configuration for Language Translation

1.1.3 Create Thread Translation Configuration

Create Thread Translation Configuration

1.1.4 Create Chat Translation Configuration

Create Chat Translation Configuration

2. Using OCI Generative AI Service

The OCI Generative AI service responds to prompt texts specific to language detection and language translation. The host-name for the service is region-specific and can be found on the Generative AI Service API documentation page. The required request path for both detection and translation requests is Gen AI Chat. Requests to the Generative AI service can be authenticated using the OCI Signature v1 authentication method.

An advantage of using the OCI Generative AI Service is that the responses could be finer controlled as per business need with appropriate prompts.

However, an additional console extension must be configured in the Agent Browser UI to transform the detection and translation requests into the corresponding Generative AI prompts and to convert the responses into the format expected by B2C Service. This extension includes logic to handle the extensibility action names for requests and responses, as configured on the Thread Translation or Chat Translation administration page.

2.1 Configuration Steps in B2C Service

2.1.1 Create External Object & Integration (XOI) configuration for Language Detection and Language Translation

Create External Object & Integration (XOI) configuration for Language Detection and Language Translation

2.1.2 Configure Console Extension for Request and Response Transformation

2.1.2.1 Building the Extension

Sample extension (refer appendix – Sample Extension Code) for GenAI requests/responses conversion is written in TypeScript could be compiled using tsc command.

jacobgeorge@jacobgeorge-mac ociGenAITranslation % ls
    convertTranslationReqResponse.ts        osvcExtension.d.ts                      tsconfig.json
    jacobgeorge@jacobgeorge-mac ociGenAITranslation % tsc
    jacobgeorge@jacobgeorge-mac ociGenAITranslation % ls
    convertTranslationReqResponse.js        convertTranslationReqResponse.ts        osvcExtension.d.ts                      tsconfig.json
    jacobgeorge@jacobgeorge-mac ociGenAITranslation % 

2.1.2.2 Uploading the ociGenAITranslation Extension

Upload the ociGenaiTranslation extension and publish it out as a console extension after selecting convertTranslationReqResponse.js as the init file and giving the required profile access as shown below.

Uploading the ociGenAITranslation Extension

2.1.3 Create Thread Translation Configuration

Create Thread Translation Configuration

2.1.4 Create Chat Translation Configuration

Create Chat Translation Configuration

2.2 Fine Tuning Generative AI Request Prompt Examples (if necessary)

2.2.1 Language Specific Considerations

if (param.translationType === 'TRANSLATION') {
      if (param.targetLanguageCode === 'ja') {
        prompt = `Translate to Japanese: "${param.text}"
          Use 丁微語 (polite language). Avoid 尊敬語 and 謙輝語 unless necessary.
          Do not use outdated or overly formal expressions (e.g. 愛顧客機).
          Do not use double punctuation such as 。。 or !!. Use clean, proper punctuation only.
          Output Format:
          Return the output in the dictionary format.
          Example:
          {"translatedText": "..."}`
      } else {
          ...
      }
    }

2.2.2 Custom Translation Considerations

//Have a variable defined with custom translations
    
    const glossary = [ { en: "English", ja: "英語", ... },
    
    //Look for matching texts
    function getGlossaryEntries(text) {
      const loweredText = text.toLowerCase();
      return glossary.filter(entry => (
        (entry.en && loweredText.includes(entry.en.toLowerCase())) ||
        (entry.ja && text.includes(entry.ja)) ||
         ...
      ));
    }
    
    //Building prompt
    ...
      const glossaryMatches = getGlossaryEntries(param.text);
    
      let glossaryNote = '';
      if (glossaryMatches.length > 0) {
        const glossaryTerms = glossaryMatches.map(entry => {
          const terms = [];
          if (entry.en) terms.push(`"${entry.en}"`);
          if (entry.ja) terms.push(`"${entry.ja}"`);
          if (entry.hu) terms.push(`"${entry.hu}"`);
          if (entry.th) terms.push(`"${entry.th}"`);
          if (entry.vi) terms.push(`"${entry.vi}"`);
          return terms.join(" / ");
        }).join(", ");
        glossaryNote = `\nPreserve terms: ${glossaryTerms}`;
      }
      if (param.translationType === 'TRANSLATION') {
        prompt = `You are an assistant for translation. The messages you will be given for translation come from a chat.Exclude product names from translation. Preserve html tags. Do not translate links. Do not give explanations, give only the translated text. ${glossaryNote}. Translate the following text to ${param.targetLanguageCode} :${param.text}. 
          Output Format:
          Return the output in the dictionary format.
          Example:
          {"translatedText": "..."}`
      }

3. Appendices

3.1 Sample Extension Code

The sample extension includes three files:

  • convertTranslationReqResponse.ts
  • tsconfig.json
  • osvcExtension.d.ts

Note: The sample extension code shared here is tested with BUI build # 3.25.07.18-b0002

3.1.1 convertTranslationReqResponse.ts

/// <reference path="./osvcExtension.d.ts" />
     
    /* * **********************************************************************************************
     *  $Disclaimer: This file is part of a sample reference solution, which is not intended to be used directly in production. It is expected that it will be modified and thoroughly validated to suite the specific purpose. You accept the responsibility to maintain and support any changes so desired for the working of the solution using the file. $
     * ************************************************************************************************
     *  $File Name: convertTranslationReqResponse.ts $
     *  $Checkout Date: August 21, 2025 $
     *  $Id: 4d02c3afc02673049b69b8054f1fb9b751db4c45 $
     * ********************************************************************************************* */
    
    const languageCodeMap = {
      'ar': 'Arabic',
      'zh-CN': 'Chinese(Simplified)',
      'zh-TW': 'Chinese(Traditional)',
      'cs': 'Czech',
      'da': 'Danish',
      'nl': 'Dutch',
      'en': 'English',
      'fi': 'Finnish',
      'fr': 'French',
      'fr-CA': 'French(Canada)',
      'de': 'German',
      'el': 'Greek',
      'hu': 'Hungarian',
      'it': 'Italian',
      'ja': 'Japanese',
      'ko': 'Korean',
      'nb-NO': 'Norwegian(Bokmål)',
      'pl': 'Polish',
      'pt': 'Portuguese',
      'pt-BR': 'Portuguese(Brazil)',
      'ro': 'Romanian',
      'ru': 'Russian',
      'es': 'Spanish',
      'sv': 'Swedish',
      'tr': 'Turkish'
    }
    class ConvertTranslationReqResponse {
      public async initialize(): Promise<void> {
        const extensionProvider: IExtensionProvider = await ORACLE_SERVICE_CLOUD.extension_loader.load("CUSTOM_APP_ID", "1");
        const globalContext: IExtensionGlobalContext = await extensionProvider.getGlobalContext();
        globalContext.registerAction('TranslationRequest', this.convertRequest.bind(this));
        globalContext.registerAction('TranslationResponse', this.convertResponse.bind(this));
      }
    
      public convertRequest(param: ILanguageTranslationRequest): ILanguageTranslationTransformedRequest {
        console.log('TranslationRequest action with param = ' + JSON.stringify(param));
        let transformedRequest: ILanguageTranslationTransformedRequest;
        let prompt;
        let genAIRequstMessages = [];
        let genAIRequstMessageContents = [];
        if (param.translationType === 'TRANSLATION') {
          prompt = `You are an assistant for translation. 
            The messages you will be given for translation come from a chat.
            Exclude product names from translation.
            Preserve html tags.
            Do not translate links.
            Do not give explanations, give only the translated text. Translate the following text to ${param.targetLanguageCode} :${param.text}.
            Output Format:
            Return the output in the dictionary format.
            Example:
            {"translatedText": "..."}`
        }
        else if (param.translationType === 'DETECT_LANGUAGE') {
          prompt = `You are a translation assistant. Detect the language of the given sentence and return its language code along with confidence in response. Return the output in the dictionary format as detectedLanguageCode and confidence without any explanation. Sentence: ${param.text}`;
        }
        genAIRequstMessageContents.push({"type": "TEXT", "text": JSON.stringify(prompt)});
        genAIRequstMessages.push({ "role": "USER", "content": genAIRequstMessageContents });
        let payload = {
            "compartmentId": "<ID of the compartment which has the required permission policies>",
            "servingMode": {
                "modelId": "meta.llama-3.3-70b-instruct",
                "servingType": "ON_DEMAND"
            },
            "chatRequest": {
                "messages": genAIRequstMessages,
                "maxTokens": 600,
                "isStream": false,
                "apiFormat": "GENERIC",
                "frequencyPenalty": 0,
                "presencePenalty": 0,
                "temperature": 0,
                "topP": 0.75,
                "topK": -1
            }
          }
    
          //Request payload details could be referred at https://docs.oracle.com/en-us/iaas/api/#/en/generative-ai-inference/20231130/datatypes/ChatDetails
    
          transformedRequest = {
            "payload" : payload
          };
          return transformedRequest;
      }
     
      public convertResponse(param: ILanguageTranslationResponse): ILanguageDetectionTransformedResponse | ILanguageTranslationTransformedResponse {
        console.log('TranslationResponse action with param = ' + JSON.stringify(param));
        let transformedResponse: ILanguageDetectionTransformedResponse | ILanguageTranslationTransformedResponse;
    
        //Response payload details could be referred at https://docs.oracle.com/en-us/iaas/api/#/en/generative-ai-inference/20231130/ChatResult/
        let genAIResponse = param?.payload.chatResponse?.choices[0]?.message?.content[0]?.text;
        let genAIResponseString = genAIResponse.replace(/```json\n|```/g, '');
        let parsedGenAIResponseData = JSON.parse(genAIResponseString);
        console.log('TranslationResponse parsed string = ' + JSON.stringify(parsedGenAIResponseData));
    
        if (param.translationType === 'TRANSLATION') {
          transformedResponse = {
            translatedText: parsedGenAIResponseData.translatedText
          }
        }
        else if (param.translationType === 'DETECT_LANGUAGE') {
          const languageCode = parsedGenAIResponseData.detectedLanguageCode;
          const languageScore = parsedGenAIResponseData.confidence;
          const languageLabel = languageCodeMap[languageCode];
          let languages: IDetectedLanguage[] = [{
            code: languageCode,
            name: languageLabel,
            score: languageScore
          }]
          transformedResponse = {
            languages: languages
          }
        }
        return transformedResponse;
      }
    }
     
    (async () => {
      return await new ConvertTranslationReqResponse().initialize();
    })()

3.1.2 tsconfig.json

{
      "compilerOptions": {
        "module": "amd",
        "target": "ES5",
        "lib": ["es5", "dom", "es2015.promise", "es2015", "ES2021"]   
      }
    }

3.1.3 osvcExtension.d.ts

Could download from https://documentation.custhelp.com/euf/assets/devdocs/unversioned/BUI_Extensibility/scripts/osvcExtension.d.ts