agentshim 0.23.0__tar.gz → 0.24.0__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 (147) hide show
  1. {agentshim-0.23.0 → agentshim-0.24.0}/CHANGELOG.md +59 -0
  2. {agentshim-0.23.0 → agentshim-0.24.0}/PKG-INFO +5 -2
  3. {agentshim-0.23.0 → agentshim-0.24.0}/README.md +4 -1
  4. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/__init__.py +81 -1
  5. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/__init__.py +61 -2
  6. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/plugin.py +39 -0
  7. agentshim-0.24.0/agentshim/core/rates.py +235 -0
  8. agentshim-0.24.0/agentshim/core/transcripts.py +269 -0
  9. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/usage.py +90 -2
  10. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/pricing.py +9 -2
  11. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/cost.py +77 -10
  12. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/events.py +3 -0
  13. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/model_data.py +27 -44
  14. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/parser.py +28 -2
  15. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/plugin.py +5 -1
  16. agentshim-0.24.0/agentshim/providers/claude/prices_generated.py +158 -0
  17. agentshim-0.24.0/agentshim/providers/claude/transcripts.py +209 -0
  18. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/app_server/transport.py +34 -9
  19. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/model_data.py +15 -33
  20. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/plugin.py +4 -1
  21. agentshim-0.24.0/agentshim/providers/codex/prices_generated.py +285 -0
  22. agentshim-0.24.0/agentshim/providers/codex/speed.py +14 -0
  23. agentshim-0.24.0/agentshim/providers/codex/transcripts.py +393 -0
  24. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/static_plugin.py +24 -1
  25. agentshim-0.24.0/agentshim/rates.py +507 -0
  26. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/testing/__init__.py +3 -0
  27. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/testing/codex_app_server.py +8 -1
  28. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/testing/contracts.py +28 -0
  29. agentshim-0.24.0/agentshim/testing/rates.py +55 -0
  30. agentshim-0.24.0/agentshim/transcripts.py +490 -0
  31. {agentshim-0.23.0 → agentshim-0.24.0}/pyproject.toml +1 -1
  32. {agentshim-0.23.0 → agentshim-0.24.0}/.gitignore +0 -0
  33. {agentshim-0.23.0 → agentshim-0.24.0}/LICENSE +0 -0
  34. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/agent.py +0 -0
  35. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/_files.py +0 -0
  36. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/auth.py +0 -0
  37. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/checkpoints.py +0 -0
  38. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/clock.py +0 -0
  39. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/conversation.py +0 -0
  40. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/env.py +0 -0
  41. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/errors.py +0 -0
  42. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/events.py +0 -0
  43. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/home.py +0 -0
  44. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/ids.py +0 -0
  45. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/mcp.py +0 -0
  46. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/models.py +0 -0
  47. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/permissions.py +0 -0
  48. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/pricing.py +0 -0
  49. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/profile.py +0 -0
  50. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/provider.py +0 -0
  51. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/schema.py +0 -0
  52. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/session_policy.py +0 -0
  53. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/skills.py +0 -0
  54. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/status.py +0 -0
  55. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/stream.py +0 -0
  56. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/core/turn.py +0 -0
  57. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/execution/__init__.py +0 -0
  58. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/execution/confinement.py +0 -0
  59. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/execution/docker.py +0 -0
  60. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/execution/executor.py +0 -0
  61. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/execution/host.py +0 -0
  62. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/execution/process.py +0 -0
  63. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/execution/readiness.py +0 -0
  64. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/execution/transform.py +0 -0
  65. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/models.py +0 -0
  66. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/oneshot.py +0 -0
  67. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/probe.py +0 -0
  68. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/__init__.py +0 -0
  69. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/_testing.py +0 -0
  70. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/catalog.py +0 -0
  71. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/__init__.py +0 -0
  72. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/failures.py +0 -0
  73. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/hooks/__init__.py +0 -0
  74. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/hooks/confine_reads.py +0 -0
  75. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/probe.py +0 -0
  76. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/provider.py +0 -0
  77. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/rate_limits.py +0 -0
  78. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/sandbox.py +0 -0
  79. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/scripted.py +0 -0
  80. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/stream_argv.py +0 -0
  81. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/stream_transport.py +0 -0
  82. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/testing.py +0 -0
  83. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/tools.py +0 -0
  84. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/claude/user_hooks.py +0 -0
  85. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/__init__.py +0 -0
  86. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/_toml.py +0 -0
  87. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/app_server/__init__.py +0 -0
  88. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/app_server/_wire.py +0 -0
  89. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/app_server/approvals.py +0 -0
  90. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/app_server/channel.py +0 -0
  91. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/app_server/errors.py +0 -0
  92. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/app_server/items.py +0 -0
  93. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/app_server/mcp.py +0 -0
  94. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/app_server/permissions.py +0 -0
  95. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/app_server/profile.py +0 -0
  96. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/app_server/protocol.py +0 -0
  97. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/app_server/rate_limits.py +0 -0
  98. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/app_server/usage.py +0 -0
  99. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/events.py +0 -0
  100. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/failures.py +0 -0
  101. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/mcp_scope.py +0 -0
  102. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/parser.py +0 -0
  103. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/probe.py +0 -0
  104. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/provider.py +0 -0
  105. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/rules.py +0 -0
  106. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/sandbox.py +0 -0
  107. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/scripted.py +0 -0
  108. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/skills.py +0 -0
  109. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/codex/testing.py +0 -0
  110. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/copilot/__init__.py +0 -0
  111. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/copilot/events.py +0 -0
  112. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/copilot/parser.py +0 -0
  113. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/copilot/plugin.py +0 -0
  114. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/copilot/probe.py +0 -0
  115. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/copilot/provider.py +0 -0
  116. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/copilot/scripted.py +0 -0
  117. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/copilot/testing.py +0 -0
  118. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/gemini/__init__.py +0 -0
  119. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/gemini/events.py +0 -0
  120. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/gemini/parser.py +0 -0
  121. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/gemini/plugin.py +0 -0
  122. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/gemini/probe.py +0 -0
  123. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/gemini/provider.py +0 -0
  124. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/gemini/scripted.py +0 -0
  125. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/gemini/testing.py +0 -0
  126. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/opencode/__init__.py +0 -0
  127. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/opencode/events.py +0 -0
  128. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/opencode/model_data.py +0 -0
  129. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/opencode/parser.py +0 -0
  130. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/opencode/plugin.py +0 -0
  131. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/opencode/probe.py +0 -0
  132. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/opencode/provider.py +0 -0
  133. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/opencode/scripted.py +0 -0
  134. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/providers/opencode/testing.py +0 -0
  135. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/py.typed +0 -0
  136. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/runtime.py +0 -0
  137. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/session.py +0 -0
  138. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/testing/claude_stream.py +0 -0
  139. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/testing/clock.py +0 -0
  140. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/testing/confinement.py +0 -0
  141. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/testing/conversation.py +0 -0
  142. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/testing/probe.py +0 -0
  143. {agentshim-0.23.0 → agentshim-0.24.0}/agentshim/testing/process.py +0 -0
  144. {agentshim-0.23.0 → agentshim-0.24.0}/tests/fixtures/claude/README.md +0 -0
  145. {agentshim-0.23.0 → agentshim-0.24.0}/tests/fixtures/claude_stream/README.md +0 -0
  146. {agentshim-0.23.0 → agentshim-0.24.0}/tests/fixtures/codex/README.md +0 -0
  147. {agentshim-0.23.0 → agentshim-0.24.0}/tests/fixtures/codex_app_server/README.md +0 -0
@@ -1,5 +1,64 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.24.0 (2026-10-30)
4
+
5
+ Everything here is additive. Recorded cost does not move: every price, `price_for`, `cost_usd`,
6
+ `PricingTable` and `ModelPricing` behave as in 0.23.1, and `tests/fixtures/recorded_costs.json`
7
+ (recorded on 0.23.1) proves the costs equal.
8
+
9
+ ### Added
10
+
11
+ - Pinned prices are generated from a LiteLLM snapshot instead of kept by hand.
12
+ `scripts/generate_prices.py` reads `tests/fixtures/litellm/snapshot.json` (trimmed to the priced
13
+ models, with the day it was read and the SHA-256 of the whole file) and writes
14
+ `providers/{claude,codex}/prices_generated.py`; a test fails if they differ. All 29 rows already
15
+ matched LiteLLM, so no price changes. `PricingTable.version` is now `litellm-<snapshot date>`
16
+ (`litellm-2026-10-30`) and every entry's `checked` is that date. The test that every catalogue
17
+ model is priced or a documented exclusion stays; `gemini-3-pro-preview` is still unpriced.
18
+ - `RateTable`, `RateEntry` and `Rates`: flat per-model rates for estimates, a separate type from the
19
+ recorded-cost table (a zero rate is allowed, there are fast and ultrafast tiers, and no function
20
+ takes both kinds). `parse_litellm` reads LiteLLM's price file, `price_tokens` splits a cost by
21
+ token class, and `speed_premium_usd` and `cache_savings_usd` give the other report figures.
22
+ `UsageSpeed` is the service speed.
23
+ - `read_rates` and `refresh_rates` keep a rate document fresh for a caller-supplied `RateSource` and
24
+ `RateStore` (24 hour TTL, 60 second floor that also holds after a failure; an empty or invalid
25
+ document never replaces a good one). `bundled_rates` is the pinned table with speed tiers, the
26
+ fallback when nothing was fetched. `rates_for` maps a provider's model names onto the table.
27
+ agentshim still has no HTTP client. `FakeRateSource`, `FakeRateStore` and `RateStoreContract` are
28
+ in `agentshim.testing`.
29
+ - `ProviderUsage.by_model`: a `ModelUsage` row for every model a turn ran, with its tokens, its
30
+ recorded price (the pinned-table price, never the CLI's), the turn's speed and turn count on one
31
+ primary row. Claude reads it from `modelUsage`, so Task subagents and advisors are visible
32
+ (`ProviderUsage.tokens` is still the main conversation only, so budgets do not move);
33
+ `thinkingTokens` fills reasoning. The Codex app-server transport reports one row at the model and
34
+ service tier the server started the thread with. `merge_model_usage` adds two turns.
35
+ `ProviderUsage.to_dict` gains a `by_model` key. `CodexScript(service_tier=...)` scripts the tier.
36
+ - `read_transcript_usage`, `transcript_roots` and `transcript_providers`: token usage from the CLIs'
37
+ own session files, for work done outside agentshim. Claude (`projects/**.jsonl`) and Codex
38
+ (`sessions` and `archived_sessions`) are read. The reader keeps no state: the caller passes back a
39
+ `FilePosition` per file and gets only what is new. It resumes only when the file did not shrink
40
+ and the 64 bytes before the resume point hash the same, otherwise it rereads (`reset`); stops at a
41
+ line boundary after a byte budget and reports `pending`; skips files by modification time; lists
42
+ files it cannot read in `failed`; and reduces a line over 8 MiB to the fields it needs. A Claude
43
+ message repeated per content block counts once; subagent files take their parent's session.
44
+ `TranscriptSource`, `RateCatalog` and `RateNaming` are new optional plugin capabilities.
45
+
46
+ ## 0.23.1 (2026-10-30)
47
+
48
+ ### Fixed
49
+
50
+ - `gpt-6.1-sol` has a price. The catalogue listed it since 0.18.2 but the price table did not, so
51
+ `price_for("codex", "gpt-6.1-sol")` returned `None` and its turns recorded no cost. The rates are
52
+ the standard short-context tier on https://developers.openai.com/api/docs/pricing, read
53
+ 2026-10-30: input 2.00, cache read 0.10, cache write 2.50, output 10.00 USD per million tokens.
54
+ The cache read rate is half of `gpt-6-sol`'s. The table version is `2026-10-30`.
55
+
56
+ ### Added
57
+
58
+ - A test that every model the catalogue or a provider profile lists is priced or named, with its
59
+ reason, in an exclusion list. `gemini-3-pro-preview` is the one exclusion: Google's pricing page
60
+ no longer lists it, so no official number can be checked, and Gemini models are not priced.
61
+
3
62
  ## 0.23.0 (2026-10-20)
4
63
 
5
64
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: agentshim
3
- Version: 0.23.0
3
+ Version: 0.24.0
4
4
  Summary: Provider-agnostic coding-agent CLI shims
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -28,7 +28,10 @@ No required runtime dependencies. Python 3.10+.
28
28
  - typed events delivered on the calling thread
29
29
  - normalized token accounting (total input, cache reads, cache writes,
30
30
  uncached input, output and reasoning) on every provider, plus a static,
31
- versioned pricing table (see [Usage and Pricing](docs/pricing.md))
31
+ versioned pricing table generated from a LiteLLM snapshot (see
32
+ [Usage and Pricing](docs/pricing.md)), usage by model, list-price estimates
33
+ from LiteLLM's rates, and usage read from the CLIs' own session files (see
34
+ [Usage Outside agentshim](docs/transcripts.md))
32
35
  - declared capabilities on `ProviderProfile`, so no caller probes a provider
33
36
  - injectable `CommandExecutor`s for running the CLI in a container or over a
34
37
  remote shell
@@ -16,7 +16,10 @@ No required runtime dependencies. Python 3.10+.
16
16
  - typed events delivered on the calling thread
17
17
  - normalized token accounting (total input, cache reads, cache writes,
18
18
  uncached input, output and reasoning) on every provider, plus a static,
19
- versioned pricing table (see [Usage and Pricing](docs/pricing.md))
19
+ versioned pricing table generated from a LiteLLM snapshot (see
20
+ [Usage and Pricing](docs/pricing.md)), usage by model, list-price estimates
21
+ from LiteLLM's rates, and usage read from the CLIs' own session files (see
22
+ [Usage Outside agentshim](docs/transcripts.md))
20
23
  - declared capabilities on `ProviderProfile`, so no caller probes a provider
21
24
  - injectable `CommandExecutor`s for running the CLI in a container or over a
22
25
  remote shell
@@ -36,6 +36,7 @@ from .core import (
36
36
  ContinuityError,
37
37
  Conversation,
38
38
  ConversationSpec,
39
+ CostBreakdown,
39
40
  CostSource,
40
41
  CredentialKind,
41
42
  CredentialSource,
@@ -45,6 +46,8 @@ from .core import (
45
46
  ExternalCredential,
46
47
  FailureKind,
47
48
  FileCredential,
49
+ FilePosition,
50
+ FileScan,
48
51
  FlagsInstallation,
49
52
  HostAuthGap,
50
53
  HostAuthUnplannableError,
@@ -59,6 +62,7 @@ from .core import (
59
62
  McpScope,
60
63
  McpServer,
61
64
  McpTransport,
65
+ ModelUsage,
62
66
  NativeMode,
63
67
  NativePermissions,
64
68
  NoopInstallation,
@@ -78,7 +82,13 @@ from .core import (
78
82
  ProviderStatus,
79
83
  ProviderUsage,
80
84
  RandomIds,
85
+ RateCatalog,
86
+ RateDocumentError,
87
+ RateEntry,
81
88
  RateLimitStatus,
89
+ RateNaming,
90
+ Rates,
91
+ RateTable,
82
92
  RawOutput,
83
93
  ReapError,
84
94
  Reasoning,
@@ -115,6 +125,12 @@ from .core import (
115
125
  ToolCall,
116
126
  ToolResult,
117
127
  ToolTracker,
128
+ TranscriptFormat,
129
+ TranscriptParser,
130
+ TranscriptRecord,
131
+ TranscriptRoot,
132
+ TranscriptScan,
133
+ TranscriptSource,
118
134
  Transport,
119
135
  TransportKind,
120
136
  TurnCancelledError,
@@ -124,6 +140,8 @@ from .core import (
124
140
  TurnResult,
125
141
  TurnTimeoutError,
126
142
  UsageReport,
143
+ UsageSpeed,
144
+ cache_savings_usd,
127
145
  compact_json,
128
146
  compose_event_handlers,
129
147
  dialect_problems,
@@ -131,11 +149,15 @@ from .core import (
131
149
  install_config_file,
132
150
  interactive_env,
133
151
  materialize,
152
+ merge_model_usage,
134
153
  normalize,
135
154
  normalized_usage,
136
155
  parse_json_object,
156
+ parse_timestamp,
137
157
  plan_auth,
138
158
  prepare_config_home,
159
+ price_tokens,
160
+ speed_premium_usd,
139
161
  )
140
162
  from .execution import (
141
163
  CallbackCommandStreamSink,
@@ -183,10 +205,28 @@ from .providers.codex.app_server import CodexAppServerTransport
183
205
  from .providers.copilot import CopilotProvider
184
206
  from .providers.gemini import GeminiProvider
185
207
  from .providers.opencode import OpencodeProvider
208
+ from .rates import (
209
+ LITELLM_ENDPOINTS,
210
+ RATES_TTL,
211
+ REFRESH_FLOOR,
212
+ RateEndpoint,
213
+ RateFetchError,
214
+ RateRead,
215
+ RateSnapshot,
216
+ RateSource,
217
+ RateStatus,
218
+ RateStore,
219
+ bundled_rates,
220
+ parse_litellm,
221
+ rates_for,
222
+ read_rates,
223
+ refresh_rates,
224
+ )
186
225
  from .runtime import Agent
187
226
  from .session import Session, Turn, TurnTicket, map_mcp_servers
227
+ from .transcripts import read_transcript_usage, transcript_providers, transcript_roots
188
228
 
189
- __version__ = "0.23.0"
229
+ __version__ = "0.24.0"
190
230
 
191
231
  __all__ = [ # noqa: RUF022 - public API test uses Python's case-sensitive order
192
232
  "Agent",
@@ -235,6 +275,7 @@ __all__ = [ # noqa: RUF022 - public API test uses Python's case-sensitive order
235
275
  "Conversation",
236
276
  "ConversationSpec",
237
277
  "CopilotProvider",
278
+ "CostBreakdown",
238
279
  "CostSource",
239
280
  "CredentialKind",
240
281
  "CredentialSource",
@@ -246,6 +287,8 @@ __all__ = [ # noqa: RUF022 - public API test uses Python's case-sensitive order
246
287
  "ExternalCredential",
247
288
  "FailureKind",
248
289
  "FileCredential",
290
+ "FilePosition",
291
+ "FileScan",
249
292
  "FlagsInstallation",
250
293
  "GeminiProvider",
251
294
  "HostAuthGap",
@@ -255,6 +298,7 @@ __all__ = [ # noqa: RUF022 - public API test uses Python's case-sensitive order
255
298
  "HttpMcpServer",
256
299
  "IdAllocator",
257
300
  "InMemoryCheckpointStore",
301
+ "LITELLM_ENDPOINTS",
258
302
  "Lifecycle",
259
303
  "LoginSpec",
260
304
  "McpConfigError",
@@ -266,6 +310,7 @@ __all__ = [ # noqa: RUF022 - public API test uses Python's case-sensitive order
266
310
  "ModelPricing",
267
311
  "ModelSpec",
268
312
  "ModelTable",
313
+ "ModelUsage",
269
314
  "NativeMode",
270
315
  "NativePermissions",
271
316
  "NoRunningTurnError",
@@ -294,8 +339,23 @@ __all__ = [ # noqa: RUF022 - public API test uses Python's case-sensitive order
294
339
  "ProviderStatus",
295
340
  "ProviderTestSupport",
296
341
  "ProviderUsage",
342
+ "RATES_TTL",
343
+ "REFRESH_FLOOR",
297
344
  "RandomIds",
345
+ "RateCatalog",
346
+ "RateDocumentError",
347
+ "RateEndpoint",
348
+ "RateEntry",
349
+ "RateFetchError",
298
350
  "RateLimitStatus",
351
+ "RateNaming",
352
+ "RateRead",
353
+ "RateSnapshot",
354
+ "RateSource",
355
+ "RateStatus",
356
+ "RateStore",
357
+ "RateTable",
358
+ "Rates",
299
359
  "RawOutput",
300
360
  "ReapError",
301
361
  "Reasoning",
@@ -337,6 +397,12 @@ __all__ = [ # noqa: RUF022 - public API test uses Python's case-sensitive order
337
397
  "ToolCall",
338
398
  "ToolResult",
339
399
  "ToolTracker",
400
+ "TranscriptFormat",
401
+ "TranscriptParser",
402
+ "TranscriptRecord",
403
+ "TranscriptRoot",
404
+ "TranscriptScan",
405
+ "TranscriptSource",
340
406
  "TransformingExecutor",
341
407
  "Transport",
342
408
  "TransportKind",
@@ -349,7 +415,10 @@ __all__ = [ # noqa: RUF022 - public API test uses Python's case-sensitive order
349
415
  "TurnTicket",
350
416
  "TurnTimeoutError",
351
417
  "UsageReport",
418
+ "UsageSpeed",
352
419
  "__version__",
420
+ "bundled_rates",
421
+ "cache_savings_usd",
353
422
  "compact_json",
354
423
  "compose_event_handlers",
355
424
  "confine",
@@ -364,14 +433,25 @@ __all__ = [ # noqa: RUF022 - public API test uses Python's case-sensitive order
364
433
  "interactive_env",
365
434
  "map_mcp_servers",
366
435
  "materialize",
436
+ "merge_model_usage",
367
437
  "model_spec",
368
438
  "normalize",
369
439
  "normalized_usage",
370
440
  "parse_json_object",
441
+ "parse_litellm",
442
+ "parse_timestamp",
371
443
  "plan_auth",
372
444
  "prepare_config_home",
373
445
  "price_for",
446
+ "price_tokens",
374
447
  "probe_provider",
375
448
  "provider_names",
449
+ "rates_for",
450
+ "read_rates",
451
+ "read_transcript_usage",
452
+ "refresh_rates",
453
+ "speed_premium_usd",
376
454
  "stream_provider_names",
455
+ "transcript_providers",
456
+ "transcript_roots",
377
457
  ]
@@ -98,7 +98,15 @@ from .mcp import (
98
98
  )
99
99
  from .models import ModelSpec, ModelTable
100
100
  from .permissions import ApprovalPolicy, NativeMode, NativePermissions
101
- from .plugin import ConnectionOptions, PricingContext, ProviderPlugin, ProviderTestSupport
101
+ from .plugin import (
102
+ ConnectionOptions,
103
+ PricingContext,
104
+ ProviderPlugin,
105
+ ProviderTestSupport,
106
+ RateCatalog,
107
+ RateNaming,
108
+ TranscriptSource,
109
+ )
102
110
  from .pricing import ModelPricing, PricingTable, cost_usd
103
111
  from .profile import (
104
112
  ConfigScope,
@@ -120,13 +128,42 @@ from .provider import (
120
128
  Provider,
121
129
  StreamParser,
122
130
  )
131
+ from .rates import (
132
+ CostBreakdown,
133
+ RateDocumentError,
134
+ RateEntry,
135
+ Rates,
136
+ RateTable,
137
+ cache_savings_usd,
138
+ price_tokens,
139
+ speed_premium_usd,
140
+ )
123
141
  from .schema import compact_json, dialect_problems, materialize, normalize
124
142
  from .session_policy import Continuity, PolicyConfig, RetryPolicy, SessionPolicy, SessionState
125
143
  from .skills import SkillSummary, SkillTracker
126
144
  from .status import AuthState, ProviderStatus
127
145
  from .stream import ToolTracker, parse_json_object
146
+ from .transcripts import (
147
+ FilePosition,
148
+ FileScan,
149
+ TranscriptFormat,
150
+ TranscriptParser,
151
+ TranscriptRecord,
152
+ TranscriptRoot,
153
+ TranscriptScan,
154
+ parse_timestamp,
155
+ )
128
156
  from .turn import OutputSchema, TurnRequest, TurnResult
129
- from .usage import CostSource, ProviderUsage, TokenUsage, TokenWeights, normalized_usage
157
+ from .usage import (
158
+ CostSource,
159
+ ModelUsage,
160
+ ProviderUsage,
161
+ TokenUsage,
162
+ TokenWeights,
163
+ UsageSpeed,
164
+ merge_model_usage,
165
+ normalized_usage,
166
+ )
130
167
 
131
168
  __all__ = [
132
169
  "AgentEvent",
@@ -157,6 +194,7 @@ __all__ = [
157
194
  "ContinuityError",
158
195
  "Conversation",
159
196
  "ConversationSpec",
197
+ "CostBreakdown",
160
198
  "CostSource",
161
199
  "CredentialKind",
162
200
  "CredentialSource",
@@ -166,6 +204,8 @@ __all__ = [
166
204
  "ExternalCredential",
167
205
  "FailureKind",
168
206
  "FileCredential",
207
+ "FilePosition",
208
+ "FileScan",
169
209
  "FlagsInstallation",
170
210
  "HostAuthGap",
171
211
  "HostAuthUnplannableError",
@@ -183,6 +223,7 @@ __all__ = [
183
223
  "ModelPricing",
184
224
  "ModelSpec",
185
225
  "ModelTable",
226
+ "ModelUsage",
186
227
  "NativeMode",
187
228
  "NativePermissions",
188
229
  "NoRunningTurnError",
@@ -205,7 +246,13 @@ __all__ = [
205
246
  "ProviderTestSupport",
206
247
  "ProviderUsage",
207
248
  "RandomIds",
249
+ "RateCatalog",
250
+ "RateDocumentError",
251
+ "RateEntry",
208
252
  "RateLimitStatus",
253
+ "RateNaming",
254
+ "RateTable",
255
+ "Rates",
209
256
  "RawOutput",
210
257
  "ReapError",
211
258
  "Reasoning",
@@ -242,6 +289,12 @@ __all__ = [
242
289
  "ToolCall",
243
290
  "ToolResult",
244
291
  "ToolTracker",
292
+ "TranscriptFormat",
293
+ "TranscriptParser",
294
+ "TranscriptRecord",
295
+ "TranscriptRoot",
296
+ "TranscriptScan",
297
+ "TranscriptSource",
245
298
  "Transport",
246
299
  "TransportKind",
247
300
  "TurnCancelledError",
@@ -251,6 +304,8 @@ __all__ = [
251
304
  "TurnResult",
252
305
  "TurnTimeoutError",
253
306
  "UsageReport",
307
+ "UsageSpeed",
308
+ "cache_savings_usd",
254
309
  "compact_json",
255
310
  "compose_event_handlers",
256
311
  "cost_usd",
@@ -259,9 +314,13 @@ __all__ = [
259
314
  "install_config_file",
260
315
  "interactive_env",
261
316
  "materialize",
317
+ "merge_model_usage",
262
318
  "normalize",
263
319
  "normalized_usage",
264
320
  "parse_json_object",
321
+ "parse_timestamp",
265
322
  "plan_auth",
266
323
  "prepare_config_home",
324
+ "price_tokens",
325
+ "speed_premium_usd",
267
326
  ]
@@ -20,7 +20,9 @@ if TYPE_CHECKING:
20
20
  from .pricing import ModelPricing, PricingTable
21
21
  from .profile import ProviderProfile
22
22
  from .provider import Provider
23
+ from .rates import RateTable
23
24
  from .status import AuthState, ProviderStatus
25
+ from .transcripts import TranscriptFormat
24
26
  from .usage import TokenUsage
25
27
 
26
28
 
@@ -170,3 +172,40 @@ class ProviderPlugin(Protocol):
170
172
  def test_support(self) -> ProviderTestSupport | None:
171
173
  """Return consumer-test adapters, if provided."""
172
174
  ...
175
+
176
+
177
+ @runtime_checkable
178
+ class RateCatalog(Protocol):
179
+ """Optional: a plugin that ships rates, with speed tiers, for the models it prices.
180
+
181
+ A plugin without it ships none. These are the rates of the pinned table
182
+ shipped in the wheel, which :func:`agentshim.rates.bundled_rates` collects.
183
+ """
184
+
185
+ def known_rates(self) -> RateTable:
186
+ """Rates for the models this provider prices."""
187
+ ...
188
+
189
+
190
+ @runtime_checkable
191
+ class RateNaming(Protocol):
192
+ """Optional: a plugin that knows which flat names a model may be filed under.
193
+
194
+ A provider not implementing it gets :func:`agentshim.core.rates.candidate_names`.
195
+ """
196
+
197
+ def rate_names(self, model: str) -> tuple[str, ...]:
198
+ """Candidate flat names for *model*, most specific first; none if it has no price."""
199
+ ...
200
+
201
+
202
+ @runtime_checkable
203
+ class TranscriptSource(Protocol):
204
+ """Optional: a plugin whose CLI keeps session files agentshim can read for usage.
205
+
206
+ A plugin without it, or answering ``None``, has no readable transcripts.
207
+ """
208
+
209
+ def transcripts(self) -> TranscriptFormat | None:
210
+ """The format of this provider's session files, or ``None`` if it has none readable."""
211
+ ...