{% extends "base.html" %} {% set active_nav = "costs" %} {% block title %}Costs - Distill{% endblock %} {% block content %}
Total spend: ${{ "%.2f"|format(total_spend) }}
{% if not entries and not topic_rollups and not source_rollups and not biggest_prompts %}Operator view
Cost rows appear after a real or preview run that uses a model route. Local operational evidence stays on disk; Distill does not phone home for product analytics.
library/.distill/cost_log.jsonl (legacy: library/cost_log.jsonl)library/.distill/telemetry.jsonldistill costs or distill --json costsdistill --cost-mode no-metered doctor refuses API-billed routes before callsIf you expected spend here, run distill doctor and confirm the active library path and cost mode.
| Topic | Cost | Runs |
|---|---|---|
| {{ topic_name }} | ${{ "%.2f"|format(cost) }} | {{ runs }} |
| Source | Cost | Runs |
|---|---|---|
| {{ source }} | ${{ "%.2f"|format(cost) }} | {{ runs }} |
| When | Workload | Call Type | Model | Provider | Tokens | Time |
|---|---|---|---|---|---|---|
| {{ record.timestamp|format_timestamp }} | {{ record.workload_tag or '-' }} | {{ record.call_type or '-' }} | {{ record.model or '-' }} | {{ record.provider or '-' }} | {{ record.tokens_label }} | {{ "%.1f"|format(record.elapsed_seconds|float) }}s |
| When | Command | Topic | Cost | Time | Videos |
|---|---|---|---|---|---|
| {{ entry.get('timestamp', '')|format_timestamp }} | {{ entry.get('command', 'unknown') }} | {% if meta.get('topic') %}{{ meta.topic }}{% else %}-{% endif %} | ${{ "%.2f"|format(entry.get('actual_cost', 0)|float) }} | {{ "%.1f"|format(entry.get('elapsed_seconds', 0)|float) }}s | {{ meta.get('videos_processed', '-') }} |
| No runs logged yet | |||||