frolax/laravel-llm-tokenkit

Token estimation, cost calculation & context-window utilities for LLM-powered Laravel apps

Fund package maintenance!
frolaxhq

Installs: 1

Dependents: 0

Suggesters: 0

Security: 0

Stars: 1

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/frolax/laravel-llm-tokenkit

v1.0.0 2026-02-11 20:58 UTC

This package is not auto-updated.

Last update: 2026-02-12 00:31:00 UTC


README

Latest Version on Packagist GitHub Tests Action Status Total Downloads

Token estimation, cost calculation & context-window utilities for LLM-powered Laravel apps.

TokenKit is a stateless Laravel package that helps you:

  • 📊 Estimate tokens for text and chat message arrays
  • 💰 Calculate costs based on provider-specific pricing
  • 📐 Build context windows with rolling window and token-budget truncation strategies

No database, no migrations, no external API calls. Works offline.

Installation

composer require frolax/laravel-llm-tokenkit

Publish the config file:

php artisan vendor:publish --tag="llm-tokenkit-config"

Quick Start

use Frolax\LlmTokenKit\Facades\LlmTokenKit;
use Frolax\LlmTokenKit\Data\ModelRef;

$model = new ModelRef(provider: 'openai', model: 'gpt-4o');

// Or use a simple array:
$model = ['provider' => 'openai', 'model' => 'gpt-4o'];

Estimate Tokens for Text

$estimate = LlmTokenKit::estimateText('Hello, world!', $model);

$estimate->inputTokensEstimated; // ~4
$estimate->confidence;           // Confidence::Medium
$estimate->method;               // EstimationMethod::Heuristic
$estimate->notes;                // ['...']

Estimate Tokens for Chat Messages

$messages = [
    ['role' => 'system', 'content' => 'You are a helpful assistant.'],
    ['role' => 'user', 'content' => 'What is Laravel?'],
];

$estimate = LlmTokenKit::estimateMessages($messages, $model);

$estimate->inputTokensEstimated; // ~18

Calculate Cost

use Frolax\LlmTokenKit\Data\TokenUsage;

$cost = LlmTokenKit::cost(
    usage: new TokenUsage(promptTokens: 1500, completionTokens: 500),
    model: $model,
);

$cost->inputCost;   // 0.00375
$cost->outputCost;  // 0.005
$cost->totalCost;   // 0.00875
$cost->currency;    // 'USD'

You can also pass arrays:

$cost = LlmTokenKit::cost(
    usage: ['prompt_tokens' => 1500, 'completion_tokens' => 500],
    model: ['provider' => 'openai', 'model' => 'gpt-4o'],
);

Or provide explicit pricing:

use Frolax\LlmTokenKit\Data\Pricing;

$cost = LlmTokenKit::cost(
    usage: new TokenUsage(promptTokens: 1000, completionTokens: 200),
    pricing: new Pricing(inputPer1m: 15.00, outputPer1m: 60.00, reasoningPer1m: 60.00),
);

Build Context Window

use Frolax\LlmTokenKit\Data\ContextBuildRequest;
use Frolax\LlmTokenKit\Enums\ContextStrategy;

$result = LlmTokenKit::buildContext(new ContextBuildRequest(
    system: 'You are a helpful assistant.',
    memorySummary: 'User prefers dark mode.',
    historyMessages: $chatHistory,
    newUserMessage: 'How do I use Eloquent?',
    modelRef: $model,
    tokenBudget: 4000,
    reservedOutputTokens: 1024,
    strategy: ContextStrategy::TruncateByTokens,
));

$result->messages;            // Ready-to-send message array
$result->tokenEstimate;       // TokenEstimate DTO
$result->wasTruncated;        // true if messages were dropped
$result->droppedMessageCount; // Number of dropped messages
$result->warnings;            // Any warnings

Or pass an array:

$result = LlmTokenKit::buildContext([
    'system' => 'You are helpful.',
    'history_messages' => $chatHistory,
    'new_user_message' => 'Hello!',
    'model_ref' => ['provider' => 'openai', 'model' => 'gpt-4o'],
    'token_budget' => 4000,
    'strategy' => 'truncate_by_tokens',
]);

Configuration

Pricing

Pricing is resolved in this order:

  1. Exact model matchpricing.providers.{provider}.models.{model}
  2. Wildcard match — e.g. gpt-4.1* matches gpt-4.1-mini
  3. Provider defaultpricing.providers.{provider}.default
  4. Global defaultpricing.default
// config/llm-tokenkit.php
'pricing' => [
    'default' => [
        'input_per_1m' => 1.00,
        'output_per_1m' => 2.00,
        'currency' => 'USD',
    ],
    'providers' => [
        'openai' => [
            'models' => [
                'gpt-4o' => ['input_per_1m' => 2.50, 'output_per_1m' => 10.00],
                'gpt-4.1*' => ['input_per_1m' => 2.00, 'output_per_1m' => 8.00],
            ],
            'default' => ['input_per_1m' => 2.50, 'output_per_1m' => 10.00],
        ],
    ],
],

Estimation

'estimation' => [
    'code_json_penalty' => 1.3,       // Multiplier for code/JSON
    'enable_code_json_penalty' => true,
    'language_multipliers' => [
        'bn' => 2.5,  // Bangla
        'hi' => 2.0,  // Hindi
        'ar' => 2.0,  // Arabic
        'zh' => 1.5,  // Chinese
    ],
],

Context Builder

'context' => [
    'reserved_output_tokens' => 4096,
    'window_size' => 50,
    'default_strategy' => 'rolling_window',
    'tool_token_threshold' => 200,
],

Artisan Command

Check which estimation backend is active:

php artisan tokenkit:check

This will report active estimators, detected tokenizer libraries, sample estimates, and pricing configuration. No network calls are made.

⚠️ Important Notes

  • Token estimates are approximations. Different providers/models tokenize differently.
  • The heuristic estimator uses a chars/4 base rule, which is reasonable for GPT models but may vary.
  • For non-Latin scripts (Bangla, Hindi, Arabic, CJK), multipliers are applied but accuracy is lower.
  • Always compare estimates against actual provider usage before relying on them for billing.

Suggested Defaults for SaaS

If building a SaaS product, consider:

  • Adding a 10-15% buffer to cost estimates for safety
  • Using Confidence::Medium or higher estimates for billing purposes
  • Regularly updating pricing in your config to match provider changes
  • Implementing usage tracking with actual provider-reported tokens alongside estimates

Testing

composer test

License

The MIT License (MIT). Please see License File for more information.