Skip to content

Bblslug is a versatile translation tool that can be used as both a CLI utility and a PHP library. It leverages LLM-based APIs to translate plain text, HTML and JSON while preserving structure, code blocks, and URLs via placeholder filters.

License

Notifications You must be signed in to change notification settings

habralab/bblslug

Repository files navigation

Bblslug

Bblslug is a versatile translation tool that can be used as both a CLI utility and a PHP library.

It leverages LLM-based APIs to translate plain text, HTML and JSON while preserving structure, code blocks, and URLs via placeholder filters.

APIs supported:

  • Anthropic (Claude):
    • anthropic:claude-haiku-3.5 - Claude Haiku 3.5 (latest)
    • anthropic:claude-opus-4 - Claude Opus 4 (20250514)
    • anthropic:claude-sonnet-4 - Claude Sonnet 4 (20250514)
  • DeepL:
    • deepl:free - DeepL free tier
    • deepl:pro - DeepL pro tier
  • Google (Gemini):
    • google:gemini-2.5-flash - Gemini 2.5 Flash
    • google:gemini-2.5-flash-lite - Gemini 2.5 Flash Lite
    • google:gemini-2.5-pro - Gemini 2.5 Pro
    • google:gemini-2.0-flash - Gemini 2.0 Flash
  • OpenAI (GPT):
    • openai:gpt-5 - OpenAI GPT-5
    • openai:gpt-5-mini - OpenAI GPT-5 Mini
    • openai:gpt-5-nano - OpenAI GPT-5 Nano
    • openai:gpt-4o - OpenAI GPT-4o
    • openai:gpt-4o-mini - OpenAI GPT-4o Mini
    • openai:gpt-4 - OpenAI GPT-4
    • openai:gpt-4-turbo - OpenAI GPT-4 Turbo
  • Yandex:
    • yandex:gpt-lite - YandexGPT Lite
    • yandex:gpt-pro - YandexGPT Pro
    • yandex:gpt-32k - YandexGPT Pro 32K
  • X.ai:
    • xai:grok-4 - Grok 4
    • xai:grok-3 - Grok 3
    • xai:grok-3-mini - Grok 3 Mini

Features

  • Supports HTML, JSON and plain text (--format=text|html|json)
  • Placeholder-based protection with filters: html_pre, html_code, url, etc.
  • Model selection via --model=vendor:name
  • Fully configurable backend registry (via resources/models.yaml)
  • Dry-run mode to preview placeholders without making API calls
  • Variables (--variables) to send or override model-specific options
  • Verbose mode (--verbose) to print request previews
  • Can be invoked as a CLI tool or embedded in PHP code
  • Validation of container syntax for HTML or JSON; disable with --no-validate

Installation

composer require habr/bblslug
chmod +x vendor/bin/bblslug

CLI Usage

Prepare

  1. Always specify a model with --model=vendor:name option.

  2. Export your API key(s) before running:

export ANTHROPIC_API_KEY=...
export DEEPL_FREE_API_KEY=...
export DEEPL_PRO_API_KEY=...
export GOOGLE_API_KEY=...
export OPENAI_API_KEY=...
export YANDEX_API_KEY=... && export YANDEX_FOLDER_ID=...
export XAI_API_KEY=...

NB! Some vendors require additional parameters, e.g. YANDEX_FOLDER_ID.

  1. Input / output:
  • If --source is omitted, Bblslug reads from STDIN.
  • If --translated is omitted, Bblslug writes to STDOUT.
  1. Optional proxy:

To route requests through a proxy (e.g. HTTP or SOCKS5), use the --proxy option or set the BBLSLUG_PROXY environment variable:

# using CLI flag
vendor/bin/bblslug --proxy="http://localhost:8888" ...

# or set it globally
export BBLSLUG_PROXY="socks5h://127.0.0.1:9050"

This works for all HTTP requests and supports authentication (http://user:pass@host:port).

Show available models

vendor/bin/bblslug --list-models

Show available prompt templates

vendor/bin/bblslug --list-prompts

Translate an HTML file and write to another file

vendor/bin/bblslug \
  --model=vendor:name \
  --format=html \
  --source=input.html \
  --translated=output.html

Translate an JSON file and write to another file

vendor/bin/bblslug \
  --model=vendor:name \
  --format=json \
  --source=input.json \
  --translated=output.json

Translate an HTML file and write to another file with filters

vendor/bin/bblslug \
  --model=vendor:name \
  --format=html \
  --source=input.html \
  --translated=output.html \
  --filters=url,html_code,html_pre

Add translation context (prompt), source and target language

vendor/bin/bblslug \
  --model=vendor:name \
  --format=html \
  --source=input.html \
  --translated=output.html \
  --target-lang=EN \
  --source-lang=DE \
  --context="Translate as a professional technical translator"

Pass model-specific variables

vendor/bin/bblslug \
  --model=vendor:name \
  --format=text \
  --variables=foo=bar,foo2=bar2 \
  --source=in.txt \
  --translated=out.txt

Choose a different prompt template

vendor/bin/bblslug \
  --model=vendor:name \
  --format=html \
  --source=input.html \
  --translated=out.html \
  --prompt-key=smart-legal

Dry-run placeholders only

vendor/bin/bblslug \
  --model=vendor:name \
  --format=text \
  --filters=url \
  --source=input.txt \
  --dry-run

Verbose mode (prints request preview to stderr)

vendor/bin/bblslug \
  --model=vendor:name \
  --format=html \
  --verbose \
  --source=input.html \
  --translated=out.html

Pipe STDIN → file

cat input.txt | vendor/bin/bblslug \
  --model=vendor:name \
  --format=text \
  --translated=out.txt

Pipe STDIN → STDOUT

echo "Hello world" | vendor/bin/bblslug \
  --model=vendor:name \
  --format=text > translated.out

Disable validation

For HTML and JSON formats, Bblslug performs basic syntax validation before and after translation. To skip this step, add:

vendor/bin/bblslug \
  --model=vendor:name \
  --format=html \
  --no-validate \
  --source=input.html \
  --translated=out.html

Statistics

  • Usage metrics

    After each translation (when not in dry-run), Bblslug prints to stderr a summary of consumed usage metrics, for example:

    Usage metrics:
        Tokens:
            Total:       1074
            -----------------
            Prompt:      631
            Completion:  443
    

PHP Library Usage

You can embed Bblslug in your PHP project.

Quickstart

  1. Install:
composer require habr/bblslug
  1. Require & Import:
require 'vendor/autoload.php';
use Bblslug\Bblslug;

Translate

Text translation function example:

$text = file_get_contents('input.html');
$result = Bblslug::translate(
    apiKey:   getenv('MODEL_API_KEY'),         // API key for the chosen model
    format:   'html',                          // 'text', 'html' of 'json'
    modelKey: 'vendor:model',                  // Model identifier (e.g. deepl:free, openai:gpt-4o, etc.)
    text:     $text,                           // Source text to be translated
    // optional:
    // Additional context/prompt pass to model
    context:    'Translate as a professional technical translator',
    filters:    ['url','html_code'],           // List of placeholder filters
    promptKey: 'translator',                   // which prompt template to use
    proxy:      getenv('BBLSLUG_PROXY'),       // Optional proxy URI (http://..., socks5h://...)
    sourceLang: 'DE',                          // Source language code (optional; autodetect if null)
    targetLang: 'EN',                          // Target language code (optional; default from driver settings)
    validate: false,                           // perform or skip syntax validation for container formats
    variables:  ['foo'=>'bar'],                // model-specific overrides
    verbose:    true,                          // If true, returns debug request/response
);
echo $result['result'];

Result structure:

[
  'original'        => string,   // Original input
  'prepared'        => string,   // After placeholder filters
  'result'          => string,   // Translated result
  'httpStatus'      => int,      // HTTP status
  'debugRequest'    => string,   // Request debug
  'debugResponse'   => string,   // Response debug
  'rawResponseBody' => string,   // Response body
  'consumed'        => [                  // Normalized usage metrics
     'tokens' => [
       'total'     => int,                // Total tokens consumed
       'breakdown' => [                   // Per-type breakdown
         'prompt'      => int,            // Name depeds of model
         'completion'  => int,            // Name depeds of model
       ],
     ],
     // additional categories if supported by the model...
  'lengths'         => [         // Text length statistics
     'original'    => int,       // - original text
     'prepared'    => int,       // - after placeholder filters
     'translated'  => int,       // - returned translated text
  ],
  'filterStats'     => [         // Placeholder stats
     ['filter'=>'url','count'=>3], …
  ],
]

List available models

$modelsByVendor = Bblslug::listModels();

foreach ($modelsByVendor as $vendor => $models) {
    echo "Vendor: {$vendor}\n";
    foreach ($models as $key => $config) {
        printf("  - %s: %s\n", $key, $config['notes'] ?? '(no notes)');
    }
}

Returns an array like:

[
  'deepl'  => ['deepl:free' => […], 'deepl:pro' => […]],
  'openai' => ['openai:gpt-4' => […], …],
  …
]

List available prompts

$prompts = Bblslug::listPrompts();

foreach ($prompts as $key => $info) {
    $formats = implode(', ', $info['formats']);
    echo "{$key} ({$formats})";
    if (! empty($info['notes'])) {
        echo "{$info['notes']}";
    }
    echo "\n";
}

Returns an array like:

[
  'translator' => [
      'formats' => ['text', 'html', 'json'],
      'notes'   => 'professional translator template',
  ],
  'legal'      => [
      'formats' => ['text'],
      'notes'   => 'legal-style translator template',
  ],
  // …
]

Error handling

try {
    $res = Bblslug::translate(...);
} catch (\InvalidArgumentException $e) {
    // invalid model, missing API key, etc.
} catch (\RuntimeException $e) {
    // HTTP error, parse failure, driver-specific error
}

Samples

You can find sample input files under the samples/ directory.

License

This project is licensed under the MIT License – see the LICENSE file for details.

About

Bblslug is a versatile translation tool that can be used as both a CLI utility and a PHP library. It leverages LLM-based APIs to translate plain text, HTML and JSON while preserving structure, code blocks, and URLs via placeholder filters.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors