Agent: Tokens Saved Dashboard Counter + CLI Savings Summary

  You are building a "Tokens Saved" feature for ProClaw. This is a HIGH priority retention hook that shows users how much money they're saving by running models locally (Ollama) or on flat-rate VPC instead of
  paying per-token API costs.

  Context: ProClaw is a security-first agent runner. Users can run AI agents via cloud APIs (per-token cost) OR self-hosted Ollama (zero cost). The runner already tracks token usage in SessionState. Provider
  pricing is already in model_gateway/profiles/registry.py. Your job: surface savings in the dashboard + CLI.

  Deliverable 1: TypeScript Types (~15 LOC)

  Create: dashboard/src/lib/types/usage.ts

  export interface TokenSavings {
    period: "day" | "week" | "month";
    tokens_consumed: number;
    equivalent_api_cost: number;      // what this would cost at cloud API rates
    actual_cost: number;              // what user actually paid (0 for Ollama)
    savings_amount: number;           // equivalent - actual
    savings_percent: number;          // month-over-month change
    model_name: string;               // e.g. "Llama 3.3 70B (Ollama)"
    provider: string;                 // e.g. "ollama"
    reference_provider: string;       // comparison provider, e.g. "openai"
    reference_cost_per_million: number; // e.g. 2.50
  }

  Deliverable 2: Mock Data (~25 LOC)

  Create: dashboard/src/lib/mock/usage.ts

  Provide mock TokenSavings data for dev mode. Use realistic numbers:
  - tokens_consumed: 2_400_000 (2.4M tokens this month)
  - equivalent_api_cost: 648.00 (at OpenAI $2.50/M + $0.10/M completion rates, simplified to $0.27/1K)
  - actual_cost: 0.0 (Ollama)
  - savings_amount: 648.00
  - savings_percent: 23 (up 23% from last month)
  - model_name: "Llama 3.3 70B"
  - provider: "ollama"
  - reference_provider: "openai"
  - reference_cost_per_million: 2.50

  Deliverable 3: API Route (~35 LOC)

  Create: dashboard/src/app/api/usage/savings/route.ts

  Follow the exact pattern used by existing API routes in dashboard/src/app/api/.

  GET handler that returns TokenSavings for the requested period (query param ?period=month). In dev mode, return mock data. In production, read from the backend API (placeholder URL:
  ${process.env.PROCLAW_API_URL}/api/v1/usage/savings).

  Look at an existing route like dashboard/src/app/api/monitoring/overview/route.ts for the exact pattern (it should use NextResponse.json, handle errors, check for dev/prod mode).

  Deliverable 4: React Query Hook (~30 LOC)

  Create: dashboard/src/lib/hooks/use-token-savings.ts

  Follow the exact pattern in dashboard/src/lib/hooks/use-proclaw-monitoring.ts:
  - Query key factory: tokenSavingsKeys.savings(period)
  - Hook: useTokenSavings(period: "day" | "week" | "month" = "month")
  - Fetches from /api/usage/savings?period=${period}
  - Dev mode fallback to mock data
  - staleTime: 60_000 (refresh every 60s)
  - Returns UseQueryResult<TokenSavings>

  Deliverable 5: Dashboard Card (~80 LOC)

  Modify: dashboard/src/app/(admin)/admin/page.tsx

  Add a "Tokens Saved" card to the dashboard. Place it in the secondary stats row (the grid gap-4 md:grid-cols-4 section around line 286). Replace the "Uptime" card (least useful metric) with the Tokens Saved
  card.

  The card design:

  ┌─────────────────────────────────────┐
  │  Tokens Saved              DollarSign│
  │                                     │
  │  $648.00                    ▲ 23%   │
  │  saved this month                   │
  │                                     │
  │  2.4M tokens · Llama 3.3 70B       │
  │  vs $648 at OpenAI rates           │
  └─────────────────────────────────────┘

  Implementation details:
  - Import DollarSign from lucide-react
  - Import useTokenSavings from the hook you created
  - Show savings_amount as the big number (formatted as currency)
  - Show savings_percent with TrendIcon (already exists in the file)
  - Subtitle: {formatted_tokens} tokens · {model_name}
  - Description: vs ${equivalent_api_cost} at ${reference_provider} rates
  - If savings_amount is 0 (cloud API user), show "Switch to local model to save" as description
  - Use text-emerald-500 for the dollar icon (green = money saved)

  IMPORTANT: Read the existing page.tsx carefully before modifying. Match the exact component patterns (Card, CardHeader, CardTitle, CardContent, CardDescription). The file uses recharts, lucide-react, and
  shadcn/ui components.

  Deliverable 6: CLI Savings Line (~20 LOC)

  Modify: runner/entrypoint.py

  After the agent run completes (after result = await runner.run(user_prompt) around line 458), add a savings summary that prints to logger.info AND returns as part of the result metadata.

  Logic:
  1. Get the provider from config.provider (e.g., "ollama", "deepseek")
  2. Get state.total_tokens from the runner state
  3. Look up cost_per_million_tokens for the current provider from the profiles registry:
  from model_gateway.profiles.registry import PROFILES
  current_cost = PROFILES.get(config.provider, {})
  4. Calculate equivalent cost at the most expensive provider (OpenAI at $2.50/M):
  reference_cost = 2.50  # OpenAI rate per 1M tokens
  equivalent = (state.total_tokens / 1_000_000) * reference_cost
  actual = (state.total_tokens / 1_000_000) * current_profile.cost_per_million_tokens
  saved = equivalent - actual
  5. If saved > 0.01, log:
  Token savings: {total_tokens:,} tokens used. At OpenAI rates: ${equivalent:.2f}. Your cost: ${actual:.2f}. Saved: ${saved:.2f}
  6. If provider is "ollama", the actual cost is always $0.00.

  IMPORTANT: This is additive only. Do NOT change any existing behavior. The savings line is informational logging only. If the profile lookup fails or provider isn't found, silently skip the savings
  calculation. Use a try/except around the entire block.

  Files to READ before writing:

  1. dashboard/src/app/(admin)/admin/page.tsx — The main dashboard page you're modifying. Understand its structure completely.
  2. dashboard/src/lib/hooks/use-proclaw-monitoring.ts — Pattern for React Query hooks.
  3. dashboard/src/app/api/monitoring/overview/route.ts — Pattern for API routes (if it exists, otherwise check any route in dashboard/src/app/api/).
  4. runner/entrypoint.py — The entrypoint you're modifying. Add savings after line ~458.
  5. model_gateway/profiles/registry.py — Provider profiles with cost_per_million_tokens.
  6. runner/models.py — SessionState with total_tokens property.

  Testing

  No separate test files needed for this deliverable, but verify:
  1. Dashboard compiles: cd dashboard && npx tsc --noEmit
  2. Existing Python tests still pass: python -m pytest runner/tests/test_entrypoint.py -v
  3. The mock data renders correctly in the dashboard card

  Key Constraints

  - Do NOT modify any existing test files
  - Do NOT change the dashboard color scheme or layout beyond replacing the Uptime card
  - Do NOT add new npm dependencies — use only what's already installed (lucide-react, recharts, @tanstack/react-query, etc.)
  - Match existing code style exactly (check imports, spacing, naming conventions)
  - All TypeScript must pass strict mode (npx tsc --noEmit)