Skip to content

fix(quota): provider-aware budget gating and per-provider usage tracking#1837

Merged
atoomic merged 3 commits into
Anantys-oss:mainfrom
BabyKoan:koan.atoomic/fix-ollama-quota-display
Jun 9, 2026
Merged

fix(quota): provider-aware budget gating and per-provider usage tracking#1837
atoomic merged 3 commits into
Anantys-oss:mainfrom
BabyKoan:koan.atoomic/fix-ollama-quota-display

Conversation

@BabyKoan

@BabyKoan BabyKoan commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Problem

When using ollama-launch provider, Kōan displayed incorrect 100%/100% quota numbers from previous regular Claude API usage. The usage_state.json accumulated tokens across provider switches without resetting, causing stale data to persist.

Root Cause

  • usage_estimator.py tracked tokens in a single shared state file regardless of which CLI provider was active.
  • UsageTracker had no awareness of whether the current provider had metered API quota, so it gated on stale usage.md even for local/self-hosted providers.

Fix

  1. Add CLIProvider.has_api_quota() — returns False for ollama-launch and LocalLLMProvider (no metered API quota). Base class defaults to True.

  2. Make _get_budget_mode() provider-aware — when the active provider has no API quota, budget_mode is forced to 'disabled' so stale usage.md never gates the agent into wait/review mode.

  3. Add per-provider tracking to usage_estimator.py — stores name in and resets session/weekly counters when the provider changes. This prevents stale Claude numbers from polluting ollama-launch display.

  4. Update TUI dashboard — shows 'no API quota' messages for no-quota providers instead of misleading usage bars.

Verification

  • Full test suite: 15877 passed, 1 warning
  • New tests added for:
    • OllamaLaunchProvider.has_api_quota() returns False
    • LocalLLMProvider.has_api_quota() returns False
    • ClaudeProvider.has_api_quota() returns True
    • Provider-aware budget mode override
    • Usage counter reset on provider change
    • Usage counter preservation when provider unchanged

Related


Quality Report

Changes: 11 files changed, 228 insertions(+), 21 deletions(-)

Code scan: clean

Tests: passed (403
tests)

Branch hygiene: clean

Generated by Kōan

@Koan-Bot Koan-Bot self-requested a review June 9, 2026 04:34
@atoomic atoomic self-assigned this Jun 9, 2026
@BabyKoan

BabyKoan commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator Author

PR Review — fix(quota): provider-aware budget gating and per-provider usage tracking

Clean, well-tested provider-aware quota implementation.

  • Correctly adds has_api_quota() to provider hierarchy with appropriate overrides
  • Per-provider tracking in usage_estimator prevents stale data accumulation
  • TUI dashboard properly shows 'no API quota' for local providers
  • Comprehensive test coverage for all provider types and edge cases
  • Minor suggestion: call decide_mode() instead of hardcoding 'deep' in TUI

🟡 Important

1. Hardcoded mode display may be inaccurate (`koan/app/tui_dashboard.py`, L883)

When provider has no API quota, the TUI displays Mode deep (budget disabled for ...) with hardcoded 'deep'. This should call t.decide_mode() to show the actual mode the agent would operate in.

The UsageTracker.decide_mode() should return 'deep' when budget_mode is 'disabled', but this should be verified rather than assumed. If the logic changes, the TUI will show stale information.

Suggested fix:

try:
    mode = t.decide_mode()
    lines.append(f"Mode      [{_MINT}]{mode}[/]  [dim](budget disabled for {_provider_name()})[/]")
except Exception as exc:
    lines.append(f"Mode      [{_MINT}]deep[/]  [dim](budget disabled for {_provider_name()})[/]")
lines.append(f"Mode      [{_MINT}]deep[/]  [dim](budget disabled for {_provider_name()})[/]")

Checklist

  • No hardcoded secrets
  • Input validation at boundaries
  • Error handling with proper cleanup
  • No resource leaks
  • No mutable default arguments
  • Test coverage for new code paths
  • Architecture and abstraction level appropriate

Silent Failure Analysis

🟡 **MEDIUM** — silent fallback on error (`koan/app/tui_dashboard.py:94-101`)

Risk: When provider quota check fails, returns True (has quota) which could incorrectly apply budget gating to local providers that should be exempt.

def _provider_has_api_quota() -> bool:
    try:
        from app.cli_provider import get_provider
        return get_provider().has_api_quota()
    except Exception as exc:
        _log.debug("provider_has_api_quota failed: %s", exc)
        return True

Fix: Consider logging at WARNING level since this affects budget gating behavior, or document why fail-closed (True) is the safe default.

🟡 **MEDIUM** — silent fallback on error (`koan/app/usage_tracker.py:285-291`)

Risk: If provider quota check throws, budget_mode falls back to config value instead of forcing 'disabled' - local providers could get incorrectly gated on stale usage.

if not get_provider().has_api_quota():
    return "disabled"
except Exception as exc:
    logger.debug("Provider quota check failed: %s", exc)
    # falls through to return config mode

Fix: Log at WARNING level since incorrect budget gating blocks agent iterations, or consider fail-safe behavior that assumes no quota when check fails.


Automated review by Kōan (Ollama-launch · model qwen3.5:cloud) HEAD=1b1fcbf 1 min 58s

Koan-Bot and others added 2 commits June 9, 2026 14:20
When using ollama-launch or local providers, Kōan was displaying stale
100%/100% quota numbers from previous Claude API usage because the
usage_state.json was shared across all providers without reset.

This fix:

1. Adds CLIProvider.has_api_quota() — returns False for ollama-launch
   and LocalLLMProvider (no metered API quota).

2. Makes _get_budget_mode() provider-aware: when the active provider
   has no API quota, budget_mode is forced to 'disabled' so stale
   usage.md never gates the agent into wait/review mode.

3. Adds per-provider tracking to usage_estimator.py: stores the
   cli_provider name in usage_state.json and resets session/weekly
   counters when the provider changes. This prevents stale Claude
   numbers from polluting ollama-launch display.

4. Updates TUI dashboard to show 'no API quota' messages for
   no-quota providers instead of misleading usage bars.

Closes Anantys-oss#319

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@BabyKoan

BabyKoan commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator Author

Rebase with requested adjustments

Branch koan.atoomic/fix-ollama-quota-display was rebased onto main and review feedback was applied.

Changes applied

  • Applied all three review suggestions:
  • Replace hardcoded deep mode in TUI Usage tab with dynamic t.decide_mode() call, falling back to deep on exception.
  • Upgrade _provider_has_api_quota() failure log from debug to warning in tui_dashboard.py since incorrect fallback affects budget gating.
  • Upgrade _get_budget_mode() failure log from debug to warning in usage_tracker.py since provider check failure can block agent iterations.

Stats

11 files changed, 233 insertions(+), 22 deletions(-)
Actions performed
  • Already-solved check: negative (confidence=high, reasoning=None of the PR's core changes — has_api_quota(), _maybe_reset_provider(), or provider-aware budg)
  • Resolved merge conflicts (1 round(s))
  • Rebased koan.atoomic/fix-ollama-quota-display onto upstream/main
  • Applied review feedback
  • Pre-push CI check: previous run passed
  • Force-pushed koan.atoomic/fix-ollama-quota-display to origin
  • CI check enqueued in ## CI (async)

CI status

CI will be checked asynchronously.


Automated by Kōan

@BabyKoan BabyKoan force-pushed the koan.atoomic/fix-ollama-quota-display branch from 1b1fcbf to d586fb6 Compare June 9, 2026 20:21
@atoomic atoomic marked this pull request as ready for review June 9, 2026 21:34
@atoomic atoomic merged commit b0d41ad into Anantys-oss:main Jun 9, 2026
5 checks passed
@BabyKoan BabyKoan deleted the koan.atoomic/fix-ollama-quota-display branch June 10, 2026 01:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve local support using ollama command

3 participants