summaryrefslogtreecommitdiffhomepage
path: root/.rules/plan/06-15-pricing-zero.md
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-04-30 20:24:33 +0900
committerAdam Malczewski <[email protected]>2026-04-30 20:24:33 +0900
commit262aa7395c50b449ce0a897f28b1e33c319f5dc7 (patch)
tree2ccc7c7f6402e76aea6b8788046215e82650fdfc /.rules/plan/06-15-pricing-zero.md
parent1e7a273bda744f93f230d21df895b54d2a81ce15 (diff)
downloaddispatch-adapter-minimax-main.tar.gz
dispatch-adapter-minimax-main.zip
add plan to updateHEADmain
Diffstat (limited to '.rules/plan/06-15-pricing-zero.md')
-rw-r--r--.rules/plan/06-15-pricing-zero.md161
1 files changed, 161 insertions, 0 deletions
diff --git a/.rules/plan/06-15-pricing-zero.md b/.rules/plan/06-15-pricing-zero.md
new file mode 100644
index 0000000..a7ee195
--- /dev/null
+++ b/.rules/plan/06-15-pricing-zero.md
@@ -0,0 +1,161 @@
+# Phase 06 — Pricing zero
+
+**Estimated time:** ~15 minutes
+**Touches:** `lib/dispatch/adapter/minimax/pricing_table.rb`,
+`lib/dispatch/adapter/minimax/data/claude_pricing.json` (or whatever the
+JSON data file is named after phase 01),
+`lib/dispatch/adapter/minimax/response_builder.rb` (cost calculation).
+
+## Goal
+
+Token Plan is request-quota, not per-token. Setting per-token rates would
+mislead callers. Instead, keep the `Usage#cost` field for API stability
+but always populate it as `0.0`.
+
+`PricingTable` becomes a stub: it answers `context_window` /
+`max_output_tokens` / `lookup` correctly for known MiniMax models, but
+`lookup` returns a `ModelPricing` whose four `*_per_mtok` fields are all
+zero.
+
+## Steps
+
+### 1. Replace the pricing JSON data file
+
+The current data file (likely
+`lib/dispatch/adapter/minimax/data/claude_pricing.json`) contains
+Anthropic per-MTok rates. Replace it with a MiniMax catalog containing
+zeros for every cost field. RENAME the file to
+`lib/dispatch/adapter/minimax/data/minimax_pricing.json`.
+
+```json
+{
+ "MiniMax-M2.7": {
+ "context_window": 204800,
+ "max_output_tokens": 16384,
+ "input_per_mtok": 0.0,
+ "output_per_mtok": 0.0,
+ "cache_read_per_mtok": 0.0,
+ "cache_write_per_mtok": 0.0
+ },
+ "MiniMax-M2.7-highspeed": {
+ "context_window": 204800,
+ "max_output_tokens": 16384,
+ "input_per_mtok": 0.0,
+ "output_per_mtok": 0.0,
+ "cache_read_per_mtok": 0.0,
+ "cache_write_per_mtok": 0.0
+ },
+ "MiniMax-M2.5": {
+ "context_window": 204800,
+ "max_output_tokens": 16384,
+ "input_per_mtok": 0.0,
+ "output_per_mtok": 0.0,
+ "cache_read_per_mtok": 0.0,
+ "cache_write_per_mtok": 0.0
+ },
+ "MiniMax-M2.5-highspeed": {
+ "context_window": 204800,
+ "max_output_tokens": 16384,
+ "input_per_mtok": 0.0,
+ "output_per_mtok": 0.0,
+ "cache_read_per_mtok": 0.0,
+ "cache_write_per_mtok": 0.0
+ },
+ "MiniMax-M2.1": {
+ "context_window": 204800,
+ "max_output_tokens": 16384,
+ "input_per_mtok": 0.0,
+ "output_per_mtok": 0.0,
+ "cache_read_per_mtok": 0.0,
+ "cache_write_per_mtok": 0.0
+ },
+ "MiniMax-M2.1-highspeed": {
+ "context_window": 204800,
+ "max_output_tokens": 16384,
+ "input_per_mtok": 0.0,
+ "output_per_mtok": 0.0,
+ "cache_read_per_mtok": 0.0,
+ "cache_write_per_mtok": 0.0
+ },
+ "MiniMax-M2": {
+ "context_window": 204800,
+ "max_output_tokens": 16384,
+ "input_per_mtok": 0.0,
+ "output_per_mtok": 0.0,
+ "cache_read_per_mtok": 0.0,
+ "cache_write_per_mtok": 0.0
+ }
+}
+```
+
+`max_output_tokens` is set to 16,384 because MiniMax's documented
+`max_tokens` field caps generation; the figure is a conservative default
+(the Anthropic SDK request shape uses `max_tokens` and MiniMax accepts up
+to whatever the model supports; we'll let MiniMax bound it server-side
+for anything larger).
+
+### 2. Update `lib/dispatch/adapter/minimax/pricing_table.rb`
+
+- Change `DATA_PATH` to point at the new filename:
+ `File.expand_path("data/minimax_pricing.json", __dir__)`.
+- Leave the four module-level helper methods (`lookup`, `context_window`,
+ `max_output_tokens`, `known_ids`) UNCHANGED. They will return correct
+ values from the new zeroed JSON.
+
+### 3. Confirm `Usage#cost` plumbing
+
+In `lib/dispatch/adapter/minimax/response_builder.rb`, find the
+`build_usage` method (and / or `build_usage_cost` if separate). The
+existing logic computes cost as `(input_tokens * input_per_mtok / 1M) +
+…`. With every `*_per_mtok` field zero, this naturally evaluates to 0.0
+— no logic change is needed.
+
+DO NOT short-circuit cost to a hardcoded `0.0`. Let it flow through the
+existing arithmetic so that if a future MiniMax pricing model is
+populated, the same plumbing will Just Work.
+
+If the existing code calls `pricing.input_per_mtok * input_tokens` and
+`pricing` can be `nil` for unknown models, ensure it gracefully returns
+`0.0` (not `nil`) when `pricing` is nil. Add a guard if missing:
+
+```ruby
+return UsageCost.new(input_cost: 0.0, output_cost: 0.0,
+ cache_read_cost: 0.0, cache_write_cost: 0.0,
+ total_cost: 0.0) if pricing.nil?
+```
+
+(Field names should match whatever `Dispatch::Adapter::UsageCost`
+actually exposes — check the interface gem if uncertain.)
+
+### 4. Delete or update specs that asserted on real prices
+
+If `spec/dispatch/adapter/minimax/pricing_table_spec.rb` has examples
+that expect non-zero values for Anthropic models, those examples will
+fail after this phase. Update them to reflect MiniMax's zero rates and
+the seven new model IDs. The full retarget is in phase 16, but minor
+adjustments here to keep the spec passing are fine — DO NOT weaken
+or skip examples; either rewrite them correctly now or expect their
+failures to be fixed in phase 16.
+
+If you choose to defer to phase 16, ensure the failures are clearly
+attributable to "expected Anthropic prices, got zero" (not a load error,
+not a syntax error, not a NoMethodError).
+
+## Acceptance criteria
+
+- The JSON data file is named `minimax_pricing.json` and lives under
+ `lib/dispatch/adapter/minimax/data/`.
+- `claude_pricing.json` does NOT exist.
+- `PricingTable.known_ids` returns exactly the 7 MiniMax model IDs.
+- `PricingTable.context_window("MiniMax-M2.7")` returns `204_800`.
+- `PricingTable.lookup("MiniMax-M2.7").input_per_mtok` is `0.0`.
+- `PricingTable.lookup("nonexistent-model")` returns `nil`.
+- `bundle exec rubocop --autocorrect-all` exits 0.
+
+## Verification
+
+Run `run_tests` with `project_path=reference/dispatch-adapter-minimax`.
+Rubocop must be clean. The `pricing_table_spec.rb` failures are
+acceptable as long as they only stem from old Anthropic price assertions
+(retargeted in phase 16). Any failure NOT of that shape must be fixed
+before calling `ask_for_next_plan`.