{% extends "base.html" %} {% set active_nav = "costs" %} {% block title %}Costs - Distill{% endblock %} {% block content %}

Costs

{% if cost_history.complete and cost_aggregate_available %}

Total spend: ${{ "%.2f"|format(total_spend) }}

{% else %}

Totals and rollups are unavailable. Retained valid runs are shown below.

Evidence warning

{% if cost_history.complete %}Cost total is unavailable{% else %}Cost history is incomplete{% endif %}

{{ cost_history_message }}

Repair the ledger before relying on historical totals, topic rollups, or source rollups.

{% endif %} {% if cost_history.complete and cost_aggregate_available and not entries and not topic_rollups and not source_rollups and not biggest_prompts %}

Operator view

No spend recorded yet

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.

  1. Ledger: {{ cost_log_path }} (legacy: {{ legacy_cost_log_path }})
  2. Per-call tokens: {{ telemetry_path }}
  3. CLI: distill costs or distill --json costs
  4. Budget mode: distill --cost-mode no-metered doctor refuses API-billed routes before calls

If you expected spend here, run distill --cost-mode no-metered doctor and confirm the active library path and cost mode.

{% else %}
{% if topic_rollups %}

By Topic (30d)

{% for topic_name, cost, runs in topic_rollups %} {% endfor %}
Cost by topic over 30 days
TopicCostRuns
{{ topic_name }} ${{ "%.2f"|format(cost) }} {{ runs }}
{% endif %} {% if source_rollups %}

By Source (30d)

{% for source, cost, runs in source_rollups %} {% endfor %}
Cost by source over 30 days
SourceCostRuns
{{ source }} ${{ "%.2f"|format(cost) }} {{ runs }}
{% endif %}
{% if biggest_prompts %}

Biggest Prompts

{% for record in biggest_prompts %} {% endfor %}
Largest prompts by token count
WhenWorkloadCall TypeModelProviderTokensTime
{{ 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
{% endif %}

Recent Runs

{% for entry in entries %} {% set meta = entry.get('metadata', {}) or {} %} {% else %} {% endfor %}
Recent costed runs
WhenCommandTopicCostTimeVideos
{{ 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
{% endif %} {% endblock %}