boriskwemo/llm-ledger

Framework-agnostic PHP package to call and track costs of LLMs (OpenAI, Anthropic, Google, Mistral, DeepSeek, Qwen and more) with a unified API, a bundled model registry, and Symfony 8 / Laravel integrations.

Maintainers

Package info

github.com/boriskwemo/llm-ledger

pkg:composer/boriskwemo/llm-ledger

Transparency log

Statistics

Installs: 30

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.0.5 2026-08-29 11:18 UTC

This package is auto-updated.

Last update: 2026-09-01 17:09:09 UTC


README

Track and control LLM spend from one PHP API. Call OpenAI, Anthropic, Google Gemini, Mistral, DeepSeek, Qwen, Kimi, GLM, Grok and any OpenAI-compatible endpoint, with automatic cost and usage tracking baked in.

Packagist PHP License

use LlmCostTracker\Client\Llm;

$llm = Llm::fromYaml('llm.yaml');

$result = $llm->chat('deepseek-chat', 'Explain quantum computing in one sentence.');

echo $result->text();                 // the answer
echo $result->usage->totalTokens;     // 42
echo $result->usage->reasoningTokens; // hidden thinking tokens, exposed
echo $result->cost->total;            // 0.000123 USD

Every call is recorded and shown in a dashboard: cost per model, provider and day, plus thinking tokens and response previews.

Install

composer require boriskwemo/llm-ledger

Requires PHP 8.2+ with ext-json and ext-pdo.

Configure

Create llm.yaml:

providers:
  openai:    { api_key: env(OPENAI_API_KEY) }
  deepseek:  { api_key: env(DEEPSEEK_API_KEY) }
  # ...anthropic, google, mistral, qwen, xai and more

tracking:
  enabled: true
  storage: sqlite://llm.db

That's it. Drop in your keys and go.

Why LLM Ledger?

  • One API for 19 providers - OpenAI, Anthropic, Google, xAI, Mistral, DeepSeek, Qwen, Kimi, GLM and any OpenAI-compatible server (vLLM, LiteLLM, local).
  • Costs you can't miss - reasoning tokens, cached input and per-call USD are normalized and stored, not just the end-of-month bill.
  • Built-in dashboard + CLI - a themed admin UI (light/dark, fully responsive) plus llm-tracker for the terminal.
  • Deprecation-aware model registry - a YAML catalog marks retired models and their replacements before they break you.
  • Batch processing - one batch() call across OpenAI, Anthropic and Gemini.
  • Symfony 8 + Laravel - an idiomatic bundle and service provider, not a raw HTTP client.
  • Secure by default - API keys live in memory only; never persisted or logged.

Quickstart

require 'vendor/autoload.php';

use LlmCostTracker\Client\Llm;

$llm = Llm::fromYaml('llm.yaml');

$result = $llm->chat('gpt-5.2', 'Hello!', ['tags' => ['demo']]);

echo $result->text();
printf("cost: $%.6f\n", $result->cost->total);

$totals = $llm->tracker()->totals(); // lifetime aggregates

Symfony 8

// config/bundles.php
LlmCostTracker\Symfony\LlmCostTrackerBundle::class => ['all' => true],
# config/routes/llm_cost_tracker.yaml
llm_cost_tracker:
    resource: '@LlmCostTrackerBundle/Resources/config/routes.yaml'
    prefix: /llm
public function __construct(private \LlmCostTracker\Client\Llm $llm) {}

$answer = $this->llm->complete('mistral-large-latest', 'Hello!');

Dashboard at /llm, model catalog at /llm/models.

Laravel

php artisan vendor:publish --provider="LlmCostTracker\Laravel\LlmCostTrackerServiceProvider"
php artisan migrate
use Llm;

$answer = Llm::complete('qwen3-max', 'Hello!');

Dashboard at /llm.

CLI

vendor/bin/llm-tracker models:list
vendor/bin/llm-tracker usage:report --days=30
vendor/bin/llm-tracker call deepseek-chat "Hello!"

More

License

MIT. See LICENSE. Contributions welcome - CONTRIBUTING.md; report vulnerabilities per SECURITY.md.