aiuse 3.3.2__tar.gz → 3.3.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. {aiuse-3.3.2/src/aiuse.egg-info → aiuse-3.3.3}/PKG-INFO +1 -1
  2. {aiuse-3.3.2 → aiuse-3.3.3}/pyproject.toml +1 -1
  3. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/__init__.py +1 -1
  4. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/codexbar.py +10 -0
  5. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/runner.py +1 -0
  6. {aiuse-3.3.2 → aiuse-3.3.3/src/aiuse.egg-info}/PKG-INFO +1 -1
  7. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_codexbar_parse.py +25 -0
  8. {aiuse-3.3.2 → aiuse-3.3.3}/LICENSE +0 -0
  9. {aiuse-3.3.2 → aiuse-3.3.3}/README.md +0 -0
  10. {aiuse-3.3.2 → aiuse-3.3.3}/setup.cfg +0 -0
  11. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/__main__.py +0 -0
  12. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/agent_notes.py +0 -0
  13. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/ai_stub.py +0 -0
  14. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/analysis/__init__.py +0 -0
  15. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/analysis/history.py +0 -0
  16. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/analysis/local_runtimes.py +0 -0
  17. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/analysis/pace.py +0 -0
  18. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/analysis/selfdescribe.py +0 -0
  19. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/analysis/suggest.py +0 -0
  20. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/analysis/use_or_lose.py +0 -0
  21. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/attribute.py +0 -0
  22. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/chat_format.py +0 -0
  23. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/cli.py +0 -0
  24. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/__init__.py +0 -0
  25. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/bailian.py +0 -0
  26. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/base.py +0 -0
  27. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/caut.py +0 -0
  28. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/clinepass.py +0 -0
  29. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/cswap.py +0 -0
  30. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/grok.py +0 -0
  31. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/hermes.py +0 -0
  32. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/muse.py +0 -0
  33. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/opencode_go.py +0 -0
  34. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/opencode_zen.py +0 -0
  35. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/openrouter.py +0 -0
  36. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/openusage.py +0 -0
  37. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/openusage_sh.py +0 -0
  38. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/qwencloud.py +0 -0
  39. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/throttle.py +0 -0
  40. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/collectors/tokscale.py +0 -0
  41. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/config.py +0 -0
  42. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/credentials.py +0 -0
  43. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/ledger.py +0 -0
  44. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/macos_trust.py +0 -0
  45. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/models.py +0 -0
  46. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/report.py +0 -0
  47. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/sampler.py +0 -0
  48. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/secretspec.py +0 -0
  49. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/serve.py +0 -0
  50. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/tty.py +0 -0
  51. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/tui/__init__.py +0 -0
  52. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/tui/app.py +0 -0
  53. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/tui/builders.py +0 -0
  54. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse/watch.py +0 -0
  55. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse.egg-info/SOURCES.txt +0 -0
  56. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse.egg-info/dependency_links.txt +0 -0
  57. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse.egg-info/entry_points.txt +0 -0
  58. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse.egg-info/requires.txt +0 -0
  59. {aiuse-3.3.2 → aiuse-3.3.3}/src/aiuse.egg-info/top_level.txt +0 -0
  60. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_attribution.py +0 -0
  61. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_bailian.py +0 -0
  62. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_base_run_json.py +0 -0
  63. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_caut_parse.py +0 -0
  64. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_chat_format.py +0 -0
  65. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_claude_sublimits.py +0 -0
  66. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_cli.py +0 -0
  67. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_clinepass.py +0 -0
  68. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_config.py +0 -0
  69. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_credentials.py +0 -0
  70. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_cswap_parse.py +0 -0
  71. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_grok.py +0 -0
  72. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_hermes_parse.py +0 -0
  73. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_history.py +0 -0
  74. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_install_deps.py +0 -0
  75. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_local_runtimes.py +0 -0
  76. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_macos_trust.py +0 -0
  77. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_models_cli_binary.py +0 -0
  78. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_models_pace.py +0 -0
  79. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_muse.py +0 -0
  80. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_opencode_go.py +0 -0
  81. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_opencode_zen.py +0 -0
  82. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_openrouter.py +0 -0
  83. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_openusage_cli_resolution.py +0 -0
  84. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_openusage_parse.py +0 -0
  85. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_pace.py +0 -0
  86. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_query_throttle.py +0 -0
  87. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_qwencloud.py +0 -0
  88. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_release_script.py +0 -0
  89. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_report.py +0 -0
  90. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_runner_consolidation.py +0 -0
  91. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_selfdescribe.py +0 -0
  92. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_serve.py +0 -0
  93. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_shared_quota_semantics.py +0 -0
  94. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_snapshots_persistence.py +0 -0
  95. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_suggest.py +0 -0
  96. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_tokscale_parse.py +0 -0
  97. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_tty.py +0 -0
  98. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_tui.py +0 -0
  99. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_use_or_lose.py +0 -0
  100. {aiuse-3.3.2 → aiuse-3.3.3}/tests/test_watch.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiuse
3
- Version: 3.3.2
3
+ Version: 3.3.3
4
4
  Summary: Aggregate AI subscription/API usage and flag use-it-or-lose-it allotments
5
5
  Author: djbclark
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "aiuse"
7
- version = "3.3.2"
7
+ version = "3.3.3"
8
8
  description = "Aggregate AI subscription/API usage and flag use-it-or-lose-it allotments"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1,3 +1,3 @@
1
1
  """Aggregate provider quotas and flag use-it-or-lose-it allotments."""
2
2
 
3
- __version__ = "3.3.2"
3
+ __version__ = "3.3.3"
@@ -12,6 +12,7 @@ from aiuse.models import (
12
12
  BillingKind,
13
13
  QuotaWindow,
14
14
  UsageCredits,
15
+ canonical_provider,
15
16
  classify_window_minutes,
16
17
  keep_copilot_report_window,
17
18
  parse_dt,
@@ -109,6 +110,7 @@ def collect_codexbar(
109
110
  timeout: float = 45.0,
110
111
  discovery_timeout: float | None = None,
111
112
  min_intervals: dict[str, float] | None = None,
113
+ skip_providers: frozenset[str] | None = None,
112
114
  ) -> list[AccountUsage]:
113
115
  if not which("codexbar"):
114
116
  raise CollectorError("codexbar not found on PATH")
@@ -124,6 +126,14 @@ def collect_codexbar(
124
126
  if discovered:
125
127
  provider_list = discovered
126
128
 
129
+ if skip_providers:
130
+ # [disabled_services]: never spawn a query (or surface its timeout) for a
131
+ # provider the operator turned off, even if CodexBar still has it enabled.
132
+ kept = [p for p in provider_list if p is None or canonical_provider(p) not in skip_providers]
133
+ if not kept:
134
+ return []
135
+ provider_list = kept
136
+
127
137
  accounts: list[AccountUsage] = []
128
138
  errors: list[str] = []
129
139
  reuse_notes: dict[str, str] = {}
@@ -156,6 +156,7 @@ def _run_collectors(config: dict[str, Any] | None = None) -> Snapshot:
156
156
  timeout=codexbar_timeout,
157
157
  discovery_timeout=discovery_timeout,
158
158
  min_intervals=intervals,
159
+ skip_providers=frozenset(disabled_providers),
159
160
  ),
160
161
  )
161
162
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiuse
3
- Version: 3.3.2
3
+ Version: 3.3.3
4
4
  Summary: Aggregate AI subscription/API usage and flag use-it-or-lose-it allotments
5
5
  Author: djbclark
6
6
  License-Expression: MIT
@@ -788,3 +788,28 @@ def test_slot_label_names_a_window_by_its_reset_when_duration_is_missing():
788
788
  in_five_days = (utcnow() + timedelta(days=5)).isoformat()
789
789
  assert _slot_label("somevendor", 1, {"resetsAt": in_three_hours}) == "Somevendor 5-hour quota (1)"
790
790
  assert _slot_label("somevendor", 1, {"resetsAt": in_five_days}) == "Somevendor weekly quota (1)"
791
+
792
+
793
+ def test_collect_codexbar_never_queries_disabled_services(monkeypatch):
794
+ queried = []
795
+
796
+ def fake_run_json(argv, *, timeout=90.0, allow_empty=False):
797
+ if "config" in argv:
798
+ return [
799
+ {"provider": "codex", "enabled": True},
800
+ {"provider": "alibaba", "enabled": True},
801
+ {"provider": "alibabatokenplan", "enabled": True},
802
+ ]
803
+ provider = argv[argv.index("--provider") + 1]
804
+ queried.append(provider)
805
+ return [{"provider": provider, "usage": {"primary": {"usedPercent": 1}}}]
806
+
807
+ monkeypatch.setattr("aiuse.collectors.codexbar.which", lambda _cmd: "/usr/bin/codexbar")
808
+ monkeypatch.setattr("aiuse.collectors.codexbar.run_json", fake_run_json)
809
+
810
+ from aiuse.collectors.codexbar import collect_codexbar
811
+
812
+ accounts = collect_codexbar(skip_providers=frozenset({"alibaba", "alibabatokenplan"}))
813
+
814
+ assert queried == ["codex"]
815
+ assert {account.provider for account in accounts} == {"codex"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes