openclacky 1.5.19 → 1.5.21
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +95 -0
- data/README.md +19 -1
- data/README_CN.md +1 -1
- data/README_JA.md +1 -1
- data/lib/clacky/agent/chunk_index.rb +8 -1
- data/lib/clacky/agent/feedback.rb +30 -0
- data/lib/clacky/agent/history_navigation.rb +17 -3
- data/lib/clacky/agent/hook_manager.rb +6 -1
- data/lib/clacky/agent/llm_caller.rb +17 -3
- data/lib/clacky/agent/message_compressor_helper.rb +36 -2
- data/lib/clacky/agent/session_serializer.rb +45 -4
- data/lib/clacky/agent.rb +135 -55
- data/lib/clacky/agent_config.rb +82 -4
- data/lib/clacky/billing/platform_billing.rb +10 -5
- data/lib/clacky/brand_config.rb +1 -1
- data/lib/clacky/cli.rb +5 -4
- data/lib/clacky/client.rb +12 -5
- data/lib/clacky/deepseek_web_tools.rb +156 -0
- data/lib/clacky/default_extensions/ext-studio/api/handler.rb +8 -0
- data/lib/clacky/default_extensions/ext-studio/panels/studio/view.js +97 -20
- data/lib/clacky/default_extensions/time_machine/panels/time_machine/view.js +1 -0
- data/lib/clacky/default_skills/onboard/SKILL.md +1 -1
- data/lib/clacky/extension/loader.rb +5 -3
- data/lib/clacky/locales/en.rb +5 -5
- data/lib/clacky/locales/zh.rb +5 -5
- data/lib/clacky/message_format/anthropic.rb +20 -0
- data/lib/clacky/message_format/open_ai.rb +31 -14
- data/lib/clacky/message_history.rb +45 -4
- data/lib/clacky/platform_http_client.rb +6 -2
- data/lib/clacky/providers.rb +38 -138
- data/lib/clacky/search_config.rb +47 -13
- data/lib/clacky/server/browser_manager.rb +35 -5
- data/lib/clacky/server/channel/channel_manager.rb +6 -6
- data/lib/clacky/server/discover.rb +5 -4
- data/lib/clacky/server/http_server.rb +285 -53
- data/lib/clacky/server/model_prices.rb +10 -5
- data/lib/clacky/server/pid_files.rb +25 -0
- data/lib/clacky/server/server_master.rb +9 -3
- data/lib/clacky/server/session_registry.rb +37 -7
- data/lib/clacky/server/web_ui_controller.rb +72 -0
- data/lib/clacky/session_manager.rb +28 -6
- data/lib/clacky/skill.rb +1 -1
- data/lib/clacky/tools/ask_user.rb +4 -1
- data/lib/clacky/tools/base.rb +3 -2
- data/lib/clacky/tools/browser.rb +18 -2
- data/lib/clacky/tools/file_reader.rb +1 -1
- data/lib/clacky/tools/terminal/session_manager.rb +19 -1
- data/lib/clacky/tools/terminal.rb +65 -23
- data/lib/clacky/tools/trash_manager.rb +5 -3
- data/lib/clacky/tools/web_fetch.rb +81 -22
- data/lib/clacky/tools/web_search.rb +45 -4
- data/lib/clacky/ui2/ui_controller.rb +1 -1
- data/lib/clacky/ui_interface.rb +4 -3
- data/lib/clacky/utils/file_processor.rb +51 -0
- data/lib/clacky/utils/model_pricing.rb +242 -39
- data/lib/clacky/version.rb +1 -1
- data/lib/clacky/web/app.css +1158 -249
- data/lib/clacky/web/app.js +82 -13
- data/lib/clacky/web/components/chat-navigator.js +8 -1
- data/lib/clacky/web/components/code-editor.js +6 -2
- data/lib/clacky/web/components/mentions.js +2 -13
- data/lib/clacky/web/components/model-picker.js +92 -97
- data/lib/clacky/web/components/onboard.js +13 -10
- data/lib/clacky/web/components/sidebar.js +6 -2
- data/lib/clacky/web/features/archive/store.js +196 -0
- data/lib/clacky/web/features/archive/view.js +409 -0
- data/lib/clacky/web/features/backup/view.js +17 -7
- data/lib/clacky/web/features/billing/view.js +84 -10
- data/lib/clacky/web/features/channels/view.js +75 -29
- data/lib/clacky/web/features/new-session/store.js +3 -3
- data/lib/clacky/web/features/new-session/view.js +1 -0
- data/lib/clacky/web/features/trash/store.js +14 -11
- data/lib/clacky/web/features/trash/view.js +66 -13
- data/lib/clacky/web/features/workspace/view.js +421 -16
- data/lib/clacky/web/i18n.js +242 -70
- data/lib/clacky/web/index.html +270 -117
- data/lib/clacky/web/projects.js +56 -1
- data/lib/clacky/web/sessions.js +609 -267
- data/lib/clacky/web/settings.js +186 -32
- data/lib/clacky/web/ws-dispatcher.js +33 -21
- data/lib/clacky.rb +4 -2
- metadata +6 -1
|
@@ -139,6 +139,29 @@ module Clacky
|
|
|
139
139
|
}
|
|
140
140
|
},
|
|
141
141
|
|
|
142
|
+
# Claude Haiku 5.5 (released 2026-10-07) — $0.10/MTok input and $0.50/MTok
|
|
143
|
+
# output for prompts up to 100K, then 5x those rates above it. Its
|
|
144
|
+
# breakpoint is the model's own, so the entry declares :tier_threshold and
|
|
145
|
+
# keys its tiered rates as over_100k; every other Claude entry keeps the
|
|
146
|
+
# global 200K tier.
|
|
147
|
+
"claude-haiku-5.5" => {
|
|
148
|
+
input: {
|
|
149
|
+
default: 0.10, # $0.10/MTok for prompts ≤ 100K tokens
|
|
150
|
+
over_100k: 0.50 # $0.50/MTok for prompts > 100K tokens
|
|
151
|
+
},
|
|
152
|
+
output: {
|
|
153
|
+
default: 0.50, # $0.50/MTok for prompts ≤ 100K tokens
|
|
154
|
+
over_100k: 2.50 # $2.50/MTok for prompts > 100K tokens
|
|
155
|
+
},
|
|
156
|
+
cache: {
|
|
157
|
+
write_default: 0.125, # $0.125/MTok cache write (≤ 100K)
|
|
158
|
+
write_over_100k: 0.625, # $0.625/MTok cache write (> 100K)
|
|
159
|
+
read_default: 0.01, # $0.01/MTok cache read (≤ 100K)
|
|
160
|
+
read_over_100k: 0.05 # $0.05/MTok cache read (> 100K)
|
|
161
|
+
},
|
|
162
|
+
tier_threshold: 100_000
|
|
163
|
+
},
|
|
164
|
+
|
|
142
165
|
"claude-haiku-4.5" => {
|
|
143
166
|
input: {
|
|
144
167
|
default: 1.00, # $1/MTok
|
|
@@ -418,20 +441,107 @@ module Clacky
|
|
|
418
441
|
}
|
|
419
442
|
},
|
|
420
443
|
|
|
421
|
-
#
|
|
422
|
-
#
|
|
423
|
-
|
|
444
|
+
# GPT-6.1 Sol served through the openclacky gateway (oc- prefix, TokHub
|
|
445
|
+
# gpt group) — the same model as abs-gpt-6.1-sol, which is served by
|
|
446
|
+
# Bedrock; the two aliases exist because the lanes are priced differently.
|
|
447
|
+
# OpenAI's own card, tiered at 272K prompt tokens (the model's breakpoint,
|
|
448
|
+
# not the global 200K): above it every bucket doubles.
|
|
449
|
+
"oc-gpt-6.1-sol" => {
|
|
424
450
|
input: {
|
|
425
|
-
default:
|
|
426
|
-
|
|
451
|
+
default: 2.00, # $2.00/MTok
|
|
452
|
+
over_272k: 4.00 # $4.00/MTok
|
|
427
453
|
},
|
|
428
454
|
output: {
|
|
429
|
-
default:
|
|
430
|
-
|
|
455
|
+
default: 10.00, # $10.00/MTok
|
|
456
|
+
over_272k: 20.00 # $20.00/MTok
|
|
431
457
|
},
|
|
432
458
|
cache: {
|
|
433
|
-
|
|
434
|
-
|
|
459
|
+
write_default: 2.50, # $2.50/MTok cache write
|
|
460
|
+
write_over_272k: 5.00,
|
|
461
|
+
read_default: 0.10, # $0.10/MTok cache hit
|
|
462
|
+
read_over_272k: 0.20
|
|
463
|
+
},
|
|
464
|
+
tier_threshold: 272_000
|
|
465
|
+
},
|
|
466
|
+
|
|
467
|
+
# GPT-6 Astra served through the openclacky gateway (oc- prefix, same
|
|
468
|
+
# ciyuan gpt group as oc-gpt-6.1-sol, hence the same 272K breakpoint and
|
|
469
|
+
# the same series discount). Its card is much higher than Sol's.
|
|
470
|
+
"oc-gpt-6-astra" => {
|
|
471
|
+
input: {
|
|
472
|
+
default: 10.00, # $10.00/MTok
|
|
473
|
+
over_272k: 20.00 # $20.00/MTok
|
|
474
|
+
},
|
|
475
|
+
output: {
|
|
476
|
+
default: 50.00, # $50.00/MTok
|
|
477
|
+
over_272k: 75.00 # $75.00/MTok
|
|
478
|
+
},
|
|
479
|
+
cache: {
|
|
480
|
+
write_default: 12.50, # $12.50/MTok cache write
|
|
481
|
+
write_over_272k: 25.00,
|
|
482
|
+
read_default: 1.00, # $1.00/MTok cache hit
|
|
483
|
+
read_over_272k: 2.00
|
|
484
|
+
},
|
|
485
|
+
tier_threshold: 272_000
|
|
486
|
+
},
|
|
487
|
+
|
|
488
|
+
# GPT-6 Sol rides the same ciyuan gpt group and 272K breakpoint, and opens
|
|
489
|
+
# at the same $2 / $10 as 6.1 Sol, but its long-context card is its own:
|
|
490
|
+
# output goes to $15 (1.5x, not 2x) while cache reads jump 4x to $0.40.
|
|
491
|
+
"oc-gpt-6-sol" => {
|
|
492
|
+
input: {
|
|
493
|
+
default: 2.00, # $2.00/MTok
|
|
494
|
+
over_272k: 4.00 # $4.00/MTok
|
|
495
|
+
},
|
|
496
|
+
output: {
|
|
497
|
+
default: 10.00, # $10.00/MTok
|
|
498
|
+
over_272k: 15.00 # $15.00/MTok
|
|
499
|
+
},
|
|
500
|
+
cache: {
|
|
501
|
+
write_default: 2.50, # $2.50/MTok cache write
|
|
502
|
+
write_over_272k: 5.00,
|
|
503
|
+
read_default: 0.10, # $0.10/MTok cache hit
|
|
504
|
+
read_over_272k: 0.40
|
|
505
|
+
},
|
|
506
|
+
tier_threshold: 272_000
|
|
507
|
+
},
|
|
508
|
+
|
|
509
|
+
# GPT-6 Luna rides the same ciyuan gpt group and 272K breakpoint as
|
|
510
|
+
# Sol/Astra, but sits at the cheap end: $0.10 in / $0.50 out.
|
|
511
|
+
"oc-gpt-6-luna" => {
|
|
512
|
+
input: {
|
|
513
|
+
default: 0.10, # $0.10/MTok
|
|
514
|
+
over_272k: 0.20 # $0.20/MTok
|
|
515
|
+
},
|
|
516
|
+
output: {
|
|
517
|
+
default: 0.50, # $0.50/MTok
|
|
518
|
+
over_272k: 0.75 # $0.75/MTok
|
|
519
|
+
},
|
|
520
|
+
cache: {
|
|
521
|
+
write_default: 0.125, # $0.125/MTok cache write
|
|
522
|
+
write_over_272k: 0.25,
|
|
523
|
+
read_default: 0.01, # $0.01/MTok cache hit
|
|
524
|
+
read_over_272k: 0.02
|
|
525
|
+
},
|
|
526
|
+
tier_threshold: 272_000
|
|
527
|
+
},
|
|
528
|
+
|
|
529
|
+
# Grok 4.7 served through the openclacky gateway (oc- prefix, TokHub
|
|
530
|
+
# upstream). Official xAI list price; the long-context surcharge xAI
|
|
531
|
+
# applies above 200K prompt tokens is not passed through, so both tiers
|
|
532
|
+
# bill the same here.
|
|
533
|
+
"oc-grok-4.7" => {
|
|
534
|
+
input: {
|
|
535
|
+
default: 2.00, # $2.00/MTok
|
|
536
|
+
over_200k: 2.00
|
|
537
|
+
},
|
|
538
|
+
output: {
|
|
539
|
+
default: 6.00, # $6.00/MTok
|
|
540
|
+
over_200k: 6.00
|
|
541
|
+
},
|
|
542
|
+
cache: {
|
|
543
|
+
write: 2.00, # no separate write charge; bill at miss rate
|
|
544
|
+
read: 0.50 # $0.50/MTok cache hit
|
|
435
545
|
}
|
|
436
546
|
},
|
|
437
547
|
|
|
@@ -498,6 +608,26 @@ module Clacky
|
|
|
498
608
|
cache: { write: 0.06, read: 0.02 }
|
|
499
609
|
},
|
|
500
610
|
|
|
611
|
+
# Google Gemini 4 Argon (GA 2026-10-13, via Vertex AI). Flat pricing,
|
|
612
|
+
# 1M context, 1M output ceiling. Price shown is the current official
|
|
613
|
+
# rate, which doubles on 2026-12-01 ($4.00/$20.00) — update both this
|
|
614
|
+
# table and vertexChatRoutes then. Cache write bills at the input rate:
|
|
615
|
+
# Vertex's OpenAI shim only exposes cache-hit (read) tokens.
|
|
616
|
+
"gemini-4-argon" => {
|
|
617
|
+
input: {
|
|
618
|
+
default: 2.00,
|
|
619
|
+
over_200k: 2.00
|
|
620
|
+
},
|
|
621
|
+
output: {
|
|
622
|
+
default: 10.00,
|
|
623
|
+
over_200k: 10.00
|
|
624
|
+
},
|
|
625
|
+
cache: {
|
|
626
|
+
write: 2.00,
|
|
627
|
+
read: 0.10
|
|
628
|
+
}
|
|
629
|
+
},
|
|
630
|
+
|
|
501
631
|
# Google Gemini 3 series (via Vertex AI). Tiered at 200K input tokens
|
|
502
632
|
# for Pro; Flash has flat pricing.
|
|
503
633
|
"gemini-3.1-pro" => {
|
|
@@ -555,6 +685,8 @@ module Clacky
|
|
|
555
685
|
# through 2026-12-31 before settling at $1.50/$7.50 (list price shown).
|
|
556
686
|
# Cache write billed at input rate (Vertex doesn't expose a separate
|
|
557
687
|
# cache-write charge in the OpenAI shim usage response).
|
|
688
|
+
# No longer offered through the gateway; the entry stays so records
|
|
689
|
+
# billed before the retirement still resolve to a price.
|
|
558
690
|
"gemini-3.7-flash" => {
|
|
559
691
|
input: {
|
|
560
692
|
default: 1.50,
|
|
@@ -923,6 +1055,7 @@ module Clacky
|
|
|
923
1055
|
# rest of this file; normalize_model_name() lowercases incoming model
|
|
924
1056
|
# names before lookup.
|
|
925
1057
|
|
|
1058
|
+
# M2.x is retired on MiniMax's own API but still served via OpenRouter/Ollama — keep these rows.
|
|
926
1059
|
# M2.5 — high-throughput text model, optimised for coding and agent tasks
|
|
927
1060
|
# (40,960-token context window). Listed at Pay-as-You-Go prices.
|
|
928
1061
|
# Source: https://www.minimax.io/models/text (MiniMax-M2.5 product page).
|
|
@@ -932,19 +1065,25 @@ module Clacky
|
|
|
932
1065
|
cache: { write: 0.30, read: 0.03 }
|
|
933
1066
|
},
|
|
934
1067
|
|
|
935
|
-
# M3 (released 2026-
|
|
936
|
-
#
|
|
937
|
-
#
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
1068
|
+
# M3.1-Flash (released 2026-10-19) — flat pricing, 1M context. Source:
|
|
1069
|
+
# https://www.minimax.io/blog/minimax-m31f. No cache-write price is
|
|
1070
|
+
# published; billed at the input rate per this table's convention.
|
|
1071
|
+
"minimax-m3.1-flash" => {
|
|
1072
|
+
input: { default: 0.15, over_200k: 0.15 },
|
|
1073
|
+
output: { default: 0.60, over_200k: 0.60 },
|
|
1074
|
+
cache: { write: 0.15, read: 0.015 }
|
|
1075
|
+
},
|
|
1076
|
+
|
|
1077
|
+
# M3 — tiered at 512K input tokens; cache write billed at the input rate.
|
|
1078
|
+
# Source: https://platform.minimax.io/docs/guides/pricing-paygo (Standard).
|
|
944
1079
|
"minimax-m3" => {
|
|
945
|
-
input: { default: 0.
|
|
946
|
-
output: { default:
|
|
947
|
-
cache: {
|
|
1080
|
+
input: { default: 0.30, over_512k: 0.60 },
|
|
1081
|
+
output: { default: 1.20, over_512k: 2.40 },
|
|
1082
|
+
cache: {
|
|
1083
|
+
write_default: 0.30, write_over_512k: 0.60,
|
|
1084
|
+
read_default: 0.06, read_over_512k: 0.12
|
|
1085
|
+
},
|
|
1086
|
+
tier_threshold: 512_000
|
|
948
1087
|
},
|
|
949
1088
|
|
|
950
1089
|
# M2.7 — text-only model (204,800-token context window). Listed at
|
|
@@ -1058,27 +1197,75 @@ module Clacky
|
|
|
1058
1197
|
# platform-served "abs-claude-*" and a BYOK "claude-*" normalise to the
|
|
1059
1198
|
# same PRICING_TABLE entry, so discounting the table itself would silently
|
|
1060
1199
|
# cut the price for customers who bring their own credentials. The "oc-*"
|
|
1061
|
-
# aliases exist only on the platform side, so their rules stay
|
|
1062
|
-
# the BYOK ids leaning on the same list price.
|
|
1200
|
+
# and "or-*" aliases exist only on the platform side, so their rules stay
|
|
1201
|
+
# narrower than the BYOK ids leaning on the same list price.
|
|
1202
|
+
#
|
|
1203
|
+
# Rates follow what the ciyuan upstream bills us. Claude (cc-max group)
|
|
1204
|
+
# costs 0.368x of list and Grok 4.7 (grok group) about 0.086x, so both
|
|
1205
|
+
# carry a deep cut; Kimi K3 (self-hosted tier) costs 0.6x and covers 10%,
|
|
1206
|
+
# while GLM still arrives at 0.8x under its own group and covers only 5%.
|
|
1207
|
+
# Those four are "channel" discounts: they exist because a third-party
|
|
1208
|
+
# channel serves the model below list, which is what the picker tooltip
|
|
1209
|
+
# tells the user. The "or-*" lane is different - it is Google's own Vertex
|
|
1210
|
+
# endpoint, billed at list, and its 20% launch promo lives in the
|
|
1211
|
+
# gateway's VERTEX_DISCOUNT knob, which this table cannot read, so the two
|
|
1212
|
+
# are kept in sync by hand. Vertex promos carry reason "promo" so the UI
|
|
1213
|
+
# explains them as a limited-time offer instead of claiming the model is
|
|
1214
|
+
# served through a third party.
|
|
1063
1215
|
# The gateway mirrors this list - see seriesDiscount in llm_proxy.
|
|
1064
1216
|
DISCOUNT_RULES = [
|
|
1065
|
-
{ match: /\Aabs-claude-/,
|
|
1066
|
-
{ match: /\Aoc-glm-/,
|
|
1067
|
-
{ match: /\Aoc-kimi-/,
|
|
1068
|
-
{ match: /\Aoc-
|
|
1217
|
+
{ match: /\Aabs-claude-/, rate: 0.6, reason: "channel" }, # Claude via ciyuan cc-max - 40% off
|
|
1218
|
+
{ match: /\Aoc-glm-/, rate: 0.95, reason: "channel" }, # GLM via ciyuan glm - 5% off
|
|
1219
|
+
{ match: /\Aoc-kimi-/, rate: 0.9, reason: "channel" }, # Kimi K3 via ciyuan - 10% off
|
|
1220
|
+
{ match: /\Aoc-grok-/, rate: 0.3, reason: "channel" }, # Grok 4.7 via ciyuan grok - 70% off
|
|
1221
|
+
{ match: /\Aoc-gpt-/, rate: 0.3, reason: "channel" }, # GPT-6.1 Sol via ciyuan gpt - 70% off
|
|
1222
|
+
{ match: /\Aor-(gemini|veo)-/, rate: 0.8, reason: "promo" } # Vertex Gemini/Veo launch promo - 20% off
|
|
1223
|
+
].freeze
|
|
1224
|
+
|
|
1225
|
+
# Lanes sold above the rates in PRICING_TABLE. Bedrock GPT is the only
|
|
1226
|
+
# one: it bills at OpenAI list (Global CRIS carries no premium), so its
|
|
1227
|
+
# 20% is a pricing decision on top of the standard 5% processing fee -
|
|
1228
|
+
# mirrored by bedrockOpenAIMarkup in llm_proxy. BYOK callers hit Bedrock
|
|
1229
|
+
# under their own account and keep the list price, so only the "abs-"
|
|
1230
|
+
# alias matches.
|
|
1231
|
+
MARKUP_RULES = [
|
|
1232
|
+
{ match: /\Aabs-gpt-/, rate: 1.2 }
|
|
1069
1233
|
].freeze
|
|
1070
1234
|
|
|
1071
1235
|
class << self
|
|
1236
|
+
# Matching promotion for a model alias, or nil when none applies.
|
|
1237
|
+
# rate - multiplier applied to the list price
|
|
1238
|
+
# reason - "channel" when a third-party channel feeds the model below
|
|
1239
|
+
# list, "promo" when the vendor's own endpoint is discounted
|
|
1240
|
+
def discount_info(model)
|
|
1241
|
+
name = model.to_s.downcase
|
|
1242
|
+
return nil if name.empty?
|
|
1243
|
+
|
|
1244
|
+
rule = DISCOUNT_RULES.find { |r| r[:match].match?(name) }
|
|
1245
|
+
rule ? { rate: rule[:rate], reason: rule[:reason] } : nil
|
|
1246
|
+
end
|
|
1247
|
+
|
|
1072
1248
|
# Multiplier applied to the final price for a model alias: 1.0 when no
|
|
1073
1249
|
# promotion applies, otherwise the matching rule's rate.
|
|
1074
1250
|
def discount_rate(model)
|
|
1251
|
+
info = discount_info(model)
|
|
1252
|
+
info ? info[:rate] : 1.0
|
|
1253
|
+
end
|
|
1254
|
+
|
|
1255
|
+
# Multiplier applied to the list price by the lane serving this alias.
|
|
1256
|
+
def markup_rate(model)
|
|
1075
1257
|
name = model.to_s.downcase
|
|
1076
1258
|
return 1.0 if name.empty?
|
|
1077
1259
|
|
|
1078
|
-
rule =
|
|
1260
|
+
rule = MARKUP_RULES.find { |r| r[:match].match?(name) }
|
|
1079
1261
|
rule ? rule[:rate] : 1.0
|
|
1080
1262
|
end
|
|
1081
1263
|
|
|
1264
|
+
# What a token actually costs us: promotion and lane markup combined.
|
|
1265
|
+
def effective_rate(model)
|
|
1266
|
+
discount_rate(model) * markup_rate(model)
|
|
1267
|
+
end
|
|
1268
|
+
|
|
1082
1269
|
# Calculate cost for the given model and usage
|
|
1083
1270
|
#
|
|
1084
1271
|
# @param model [String] Model identifier
|
|
@@ -1109,21 +1296,26 @@ module Clacky
|
|
|
1109
1296
|
cache_write_tokens = usage[:cache_creation_input_tokens] || 0
|
|
1110
1297
|
cache_read_tokens = usage[:cache_read_input_tokens] || 0
|
|
1111
1298
|
|
|
1112
|
-
# Determine
|
|
1299
|
+
# Determine which tier applies. Haiku 5.5 breaks at 100K instead of the
|
|
1300
|
+
# global 200K, so an entry may declare :tier_threshold and key its
|
|
1301
|
+
# tiered rates as over_<n>k (100_000 → :over_100k) — any breakpoint
|
|
1302
|
+
# works without touching this method.
|
|
1113
1303
|
# Note: prompt_tokens includes cache_read_tokens but NOT cache_write_tokens
|
|
1114
1304
|
# cache_write_tokens are additional tokens that were written to cache
|
|
1305
|
+
threshold = pricing[:tier_threshold] || TIERED_PRICING_THRESHOLD
|
|
1306
|
+
tier_key = pricing[:tier_threshold] ? :"over_#{threshold / 1000}k" : :over_200k
|
|
1115
1307
|
total_input_tokens = prompt_tokens + cache_write_tokens
|
|
1116
|
-
over_threshold = total_input_tokens >
|
|
1308
|
+
over_threshold = total_input_tokens > threshold
|
|
1117
1309
|
|
|
1118
1310
|
# Calculate regular input cost (non-cached tokens)
|
|
1119
1311
|
# prompt_tokens already includes cache_read_tokens, so we need to subtract them
|
|
1120
1312
|
# cache_write_tokens are not part of prompt_tokens, so they're handled separately in cache_cost
|
|
1121
1313
|
regular_input_tokens = prompt_tokens - cache_read_tokens
|
|
1122
|
-
input_rate = over_threshold ? pricing[:input][
|
|
1314
|
+
input_rate = over_threshold ? pricing[:input][tier_key] : pricing[:input][:default]
|
|
1123
1315
|
input_cost = (regular_input_tokens / 1_000_000.0) * input_rate
|
|
1124
1316
|
|
|
1125
1317
|
# Calculate output cost
|
|
1126
|
-
output_rate = over_threshold ? pricing[:output][
|
|
1318
|
+
output_rate = over_threshold ? pricing[:output][tier_key] : pricing[:output][:default]
|
|
1127
1319
|
output_cost = (completion_tokens / 1_000_000.0) * output_rate
|
|
1128
1320
|
|
|
1129
1321
|
# Calculate cache costs
|
|
@@ -1131,13 +1323,14 @@ module Clacky
|
|
|
1131
1323
|
pricing: pricing,
|
|
1132
1324
|
cache_write_tokens: cache_write_tokens,
|
|
1133
1325
|
cache_read_tokens: cache_read_tokens,
|
|
1134
|
-
over_threshold: over_threshold
|
|
1326
|
+
over_threshold: over_threshold,
|
|
1327
|
+
tier_key: tier_key
|
|
1135
1328
|
)
|
|
1136
1329
|
|
|
1137
1330
|
# Promotions are keyed on the requested alias, so apply them last: the
|
|
1138
1331
|
# table above holds list prices shared with BYOK callers.
|
|
1139
1332
|
{
|
|
1140
|
-
cost: (input_cost + output_cost + cache_cost) *
|
|
1333
|
+
cost: (input_cost + output_cost + cache_cost) * effective_rate(model),
|
|
1141
1334
|
source: source
|
|
1142
1335
|
}
|
|
1143
1336
|
end
|
|
@@ -1222,6 +1415,10 @@ module Clacky
|
|
|
1222
1415
|
"claude-opus-4.5"
|
|
1223
1416
|
when /claude.*sonnet.*4[.-]?[5-9]/i
|
|
1224
1417
|
"claude-sonnet-4.5"
|
|
1418
|
+
# Claude Haiku 5.5 (released 2026-10-07) keeps its own breakpoint (100K)
|
|
1419
|
+
# and its own rates, so it must not fall through to the 4.x branch below.
|
|
1420
|
+
when /claude.*haiku-5[.-]5/i
|
|
1421
|
+
"claude-haiku-5.5"
|
|
1225
1422
|
when /claude.*haiku.*4[.-]?[5-9]/i
|
|
1226
1423
|
"claude-haiku-4.5"
|
|
1227
1424
|
when /claude-3-5-sonnet-20241022/i
|
|
@@ -1298,6 +1495,8 @@ module Clacky
|
|
|
1298
1495
|
"glm-4.7"
|
|
1299
1496
|
# MiniMax — model ids in providers.rb use capitalised "MiniMax-M*"
|
|
1300
1497
|
# but we match case-insensitively and map to the lowercased table key.
|
|
1498
|
+
when /^minimax-m3[.]1-flash$/i
|
|
1499
|
+
"minimax-m3.1-flash"
|
|
1301
1500
|
when /^minimax-m3$/i
|
|
1302
1501
|
"minimax-m3"
|
|
1303
1502
|
when /^minimax-m2\.7$/i
|
|
@@ -1331,6 +1530,8 @@ module Clacky
|
|
|
1331
1530
|
|
|
1332
1531
|
# Google Gemini 3 series. Match the platform aliases (or-gemini-*)
|
|
1333
1532
|
# and the bare upstream ids returned by Vertex.
|
|
1533
|
+
when /^or-gemini-4-argon$/i, /^gemini-4-argon$/i
|
|
1534
|
+
"gemini-4-argon"
|
|
1334
1535
|
when /^or-gemini-3-1-pro$/i, /^gemini-3\.1-pro(-preview)?$/i
|
|
1335
1536
|
"gemini-3.1-pro"
|
|
1336
1537
|
when /^or-gemini-3-5-flash$/i, /^gemini-3\.5-flash$/i, /^gemini-3-flash(-preview)?$/i
|
|
@@ -1382,7 +1583,7 @@ module Clacky
|
|
|
1382
1583
|
end
|
|
1383
1584
|
|
|
1384
1585
|
# Calculate cache-related costs
|
|
1385
|
-
def calculate_cache_cost(pricing:, cache_write_tokens:, cache_read_tokens:, over_threshold:)
|
|
1586
|
+
def calculate_cache_cost(pricing:, cache_write_tokens:, cache_read_tokens:, over_threshold:, tier_key: :over_200k)
|
|
1386
1587
|
cache_cost = 0.0
|
|
1387
1588
|
|
|
1388
1589
|
# Cache write cost
|
|
@@ -1391,8 +1592,9 @@ module Clacky
|
|
|
1391
1592
|
# Simple pricing (Opus 4.5, Haiku 4.5)
|
|
1392
1593
|
pricing[:cache][:write]
|
|
1393
1594
|
elsif over_threshold
|
|
1394
|
-
# Tiered pricing (Sonnet 4.5
|
|
1395
|
-
|
|
1595
|
+
# Tiered pricing (Sonnet 4.5 and friends at 200K,
|
|
1596
|
+
# Haiku 5.5 at 100K)
|
|
1597
|
+
pricing[:cache][:"write_#{tier_key}"]
|
|
1396
1598
|
else
|
|
1397
1599
|
pricing[:cache][:write_default]
|
|
1398
1600
|
end
|
|
@@ -1406,8 +1608,9 @@ module Clacky
|
|
|
1406
1608
|
# Simple pricing (Opus 4.5, Haiku 4.5)
|
|
1407
1609
|
pricing[:cache][:read]
|
|
1408
1610
|
elsif over_threshold
|
|
1409
|
-
# Tiered pricing (Sonnet 4.5
|
|
1410
|
-
|
|
1611
|
+
# Tiered pricing (Sonnet 4.5 and friends at 200K,
|
|
1612
|
+
# Haiku 5.5 at 100K)
|
|
1613
|
+
pricing[:cache][:"read_#{tier_key}"]
|
|
1411
1614
|
else
|
|
1412
1615
|
pricing[:cache][:read_default]
|
|
1413
1616
|
end
|
data/lib/clacky/version.rb
CHANGED