Skip to content

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

8 Commits

Folders and files

Repository files navigation

LLM Ledger

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.

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages