@bitkyc08/opencodex 2.14.2 → 2.15.1

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.
@@ -26,6 +26,22 @@ export interface ModelRename {
26
26
  to: string;
27
27
  /** Why the vendor retired it, for the startup warning and future readers. */
28
28
  reason: string;
29
+ /**
30
+ * Drop the retired key from `modelReasoningEffortMap` instead of renaming it.
31
+ *
32
+ * Renaming preserves the VALUE, which is right for records whose values describe the
33
+ * model — a context window or an effort ladder survives a rename — and wrong for the
34
+ * one record whose values are themselves wire ids. An effort map saved as
35
+ * `high -> gemini-3.6-flash-high` would keep naming a dead wire id under the new key,
36
+ * and the adapter maps effort BEFORE resolving CCA routing, so that value arrives as
37
+ * an unrecognised effort and silently degrades to the default tier.
38
+ *
39
+ * Only that one record is dropped. Emptying the others would be worse than the bug:
40
+ * catalog enrichment treats an existing `{}` as "already populated" and will not
41
+ * restore the registry's records, so the migrated user would keep routing correctly
42
+ * but lose the reasoning picker entirely.
43
+ */
44
+ dropReasoningEffortMap?: boolean;
29
45
  }
30
46
 
31
47
  /**
@@ -46,6 +62,22 @@ export const MODEL_RENAMES: readonly ModelRename[] = [
46
62
  to: "qwen3.8-max",
47
63
  reason: "Alibaba shipped Qwen3.8-Max as stable and documents the preview endpoint as liable to be taken offline once preview concludes",
48
64
  },
65
+ // Antigravity Flash generations. Google takes the previous Flash model off Cloud Code
66
+ // Assist almost immediately when the next ships, so a saved 3.6 (or older 3.5) id is a
67
+ // dead selection rather than a merely outdated one. Routing already redirects these ids
68
+ // at request time; this migration repairs the saved config so the picker, the allowlist
69
+ // and the capability maps stop naming a model the backend no longer serves.
70
+ ...(["gemini-3.6-flash", "gemini-3.6-flash-low", "gemini-3.6-flash-medium", "gemini-3.6-flash-high",
71
+ "gemini-3.5-flash-extra-low", "gemini-3.5-flash-low", "gemini-3.5-flash-mid", "gemini-3.5-flash-high",
72
+ "gemini-3-flash-agent"] as const).map(from => ({
73
+ provider: "google-antigravity",
74
+ from,
75
+ to: "gemini-3.7-flash",
76
+ reason: "Google retires the previous Antigravity Flash generation from Cloud Code Assist when its successor ships, so the saved id no longer resolves to a live model",
77
+ // The retired Flash tiers were wire ids, so any saved per-model record keyed by one
78
+ // may also hold one as a value. 3.7 expresses tiers as thinkingLevel names instead.
79
+ dropReasoningEffortMap: true,
80
+ })),
49
81
  ];
50
82
 
51
83
  /** Provider fields that key metadata by model id. */
@@ -61,6 +93,12 @@ const MODEL_KEYED_RECORDS = [
61
93
  /** Provider fields that are flat lists of model ids. */
62
94
  const MODEL_ID_LISTS = [
63
95
  "models",
96
+ // A retired id left here is worse than a stale label: `filterCatalogModels` treats
97
+ // `selectedModels` as an exact-match allowlist, so a user who allowlisted only the
98
+ // retired model gets NO replacement row at all — the model silently vanishes from
99
+ // their catalog instead of being renamed. OAuth reconciliation does not cover this
100
+ // field, so the rename has to.
101
+ "selectedModels",
64
102
  "noVisionModels",
65
103
  "noReasoningModels",
66
104
  "noTemperatureModels",
@@ -102,6 +140,19 @@ function renameInRecord(value: unknown, from: string, to: string): Record<string
102
140
  return next;
103
141
  }
104
142
 
143
+ /** Drop the retired key entirely, leaving any entry already saved under the new id. */
144
+ function dropFromRecord(value: unknown, from: string): Record<string, unknown> | null {
145
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
146
+ const record = value as Record<string, unknown>;
147
+ if (!(from in record)) return null;
148
+ const next: Record<string, unknown> = {};
149
+ for (const [key, entry] of Object.entries(record)) {
150
+ if (key === from) continue;
151
+ next[key] = entry;
152
+ }
153
+ return next;
154
+ }
155
+
105
156
  /**
106
157
  * `provider/model` rows in the top-level `disabledModels` list.
107
158
  *
@@ -179,7 +230,9 @@ export function projectModelRenames(
179
230
  touched = true;
180
231
  }
181
232
  for (const field of MODEL_KEYED_RECORDS) {
182
- const next = renameInRecord(row[field], rename.from, rename.to);
233
+ const next = rename.dropReasoningEffortMap && field === "modelReasoningEffortMap"
234
+ ? dropFromRecord(row[field], rename.from)
235
+ : renameInRecord(row[field], rename.from, rename.to);
183
236
  if (!next) continue;
184
237
  row[field] = next;
185
238
  touched = true;
@@ -280,8 +280,30 @@ export type ProviderConfigSeed = Pick<
280
280
  const ANTHROPIC_MODELS = ["claude-fable-5", "claude-sonnet-5", "claude-opus-5", "claude-opus-4-8", "claude-opus-4-7", "claude-opus-4-6", "claude-sonnet-4-6", "claude-haiku-4-5"];
281
281
  const ANTHROPIC_MODEL_CONTEXT_WINDOWS: Record<string, number> = { "claude-sonnet-5": 1_000_000, "claude-fable-5": 1_000_000, "claude-opus-5": 1_000_000, "claude-opus-4-8": 1_000_000, "claude-opus-4-7": 1_000_000, "claude-opus-4-6": 1_000_000, "claude-sonnet-4-6": 1_000_000, "claude-haiku-4-5": 200_000 };
282
282
 
283
+ // 260814 GLM-5.3 is registered pre-emptively alongside 5.2 everywhere 5.2 appears. Z.AI's
284
+ // devpack "How to Switch Models" page (docs.z.ai/devpack/latest-model) lists glm-5.3 and
285
+ // glm-5.3[1m] as Coding Plan ids on the unchanged endpoints; the capability and pricing
286
+ // tables were not published yet, so every 5.3 row mirrors its 5.2 sibling until they settle.
287
+ // The non-Z.AI providers below are speculative on purpose: they carry 5.2 today and are
288
+ // expected to pick 5.3 up on their usual lag. Providers whose live /v1/models discovery is
289
+ // enabled self-correct on the next successful fetch; static ones need a follow-up refresh.
290
+ const ZAI_GLM_53_MODELS = ["glm-5.3", "glm-5.3[1m]"];
283
291
  const ZAI_GLM_52_MODELS = ["glm-5.2", "glm-5.2[1m]"];
292
+ const ZAI_GLM_5X_MODELS = [...ZAI_GLM_53_MODELS, ...ZAI_GLM_52_MODELS];
284
293
  const ZAI_GLM_52_REASONING_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
294
+ /**
295
+ * GLM-5.3 does NOT share 5.2's five-tier ladder. docs.z.ai/devpack/latest-model folds every
296
+ * incoming effort into three effective tiers — low/minimal/light -> low, medium/high -> high,
297
+ * xhigh/max/ultra -> max — with max as both the default and the unknown-value fallback.
298
+ * Advertising five levels would publish two picker rows that are indistinguishable on the wire,
299
+ * so only the effective tiers are exposed (same treatment Cursor and Baseten already give GLM).
300
+ */
301
+ const ZAI_GLM_53_REASONING_EFFORTS = ["low", "high", "max"];
302
+ /** Per-model ladders for the Coding Plan rows: 5.3 gets its three effective tiers, 5.2 keeps five. */
303
+ const ZAI_GLM_5X_REASONING_EFFORTS: Record<string, string[]> = {
304
+ ...Object.fromEntries(ZAI_GLM_53_MODELS.map(id => [id, ZAI_GLM_53_REASONING_EFFORTS])),
305
+ ...Object.fromEntries(ZAI_GLM_52_MODELS.map(id => [id, ZAI_GLM_52_REASONING_EFFORTS])),
306
+ };
285
307
  // 260710 MiniMax models and context windows: Tier-2 evidence in
286
308
  // devlog/_plan/260710_provider_hardening/002_research_cn.md.
287
309
  const MINIMAX_MODELS = [
@@ -387,13 +409,13 @@ const OPENCODE_GO_THINKING_TOGGLE_MODELS = [
387
409
  * images through the proxy's vision sidecar (src/codex/catalog/provider-fetch.ts), a claim nobody
388
410
  * has verified for BigModel-hosted GLM.
389
411
  */
390
- const ZHIPU_BIGMODEL_TEXT_MODELS = ["glm-4.6", "glm-4.7", "glm-4.7-flash", "glm-5", "glm-5.1"];
412
+ const ZHIPU_BIGMODEL_TEXT_MODELS = ["glm-4.6", "glm-4.7", "glm-4.7-flash", "glm-5", "glm-5.1", "glm-5.2", "glm-5.3"];
391
413
  const ZHIPU_BIGMODEL_MODELS = [...ZHIPU_BIGMODEL_TEXT_MODELS, "glm-4.6v"];
392
414
  const ZHIPU_BIGMODEL_INPUT_MODALITIES: Record<string, string[]> = {
393
415
  ...Object.fromEntries(ZHIPU_BIGMODEL_TEXT_MODELS.map(id => [id, ["text"]])),
394
416
  "glm-4.6v": ["text", "image"],
395
417
  };
396
- const ZHIPU_BIGMODEL_THINKING_TOGGLE_MODELS = ["glm-4.6", "glm-4.7", "glm-5", "glm-5.1"];
418
+ const ZHIPU_BIGMODEL_THINKING_TOGGLE_MODELS = ["glm-4.6", "glm-4.7", "glm-5", "glm-5.1", "glm-5.2", "glm-5.3"];
397
419
  const THINKING_BUDGET_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
398
420
  // Qwen3.8-Max is the first Qwen3.x model with official direct `reasoning_effort` support.
399
421
  // Evidence: https://qwen.ai/blog?id=qwen3.8
@@ -491,7 +513,7 @@ const deepseekReasoningMapFor = (modelId: string): Record<string, string> =>
491
513
  // https://help.aliyun.com/en/model-studio/token-plan-quickstart
492
514
  const ALIBABA_TOKEN_PLAN_MODELS = [
493
515
  "qwen3.8-max", "qwen3.7-max", "qwen3.7-plus", "qwen3.6-flash",
494
- "glm-5.2", "deepseek-v4-pro",
516
+ "glm-5.3", "glm-5.2", "deepseek-v4-pro",
495
517
  ];
496
518
  const ALIBABA_TOKEN_PLAN_QWEN_MODELS = [
497
519
  "qwen3.8-max", "qwen3.7-max", "qwen3.7-plus", "qwen3.6-flash",
@@ -501,6 +523,7 @@ const ALIBABA_TOKEN_PLAN_INPUT_MODALITIES: Record<string, string[]> = {
501
523
  "qwen3.7-max": ["text", "image"],
502
524
  "qwen3.7-plus": ["text", "image"],
503
525
  "qwen3.6-flash": ["text", "image"],
526
+ "glm-5.3": ["text"],
504
527
  "glm-5.2": ["text"],
505
528
  "deepseek-v4-pro": ["text"],
506
529
  };
@@ -513,7 +536,7 @@ const ALIBABA_INTL_TOKEN_PLAN_MODELS = [
513
536
  "qwen3.8-max", "qwen3.7-max", "qwen3.7-plus", "qwen3.6-plus", "qwen3.6-flash",
514
537
  "deepseek-v4-pro", "deepseek-v4-flash", "deepseek-v3.2",
515
538
  "kimi-k2.7-code", "kimi-k2.6", "kimi-k2.5",
516
- "glm-5.2", "glm-5.1", "glm-5",
539
+ "glm-5.3", "glm-5.2", "glm-5.1", "glm-5",
517
540
  "MiniMax-M2.5",
518
541
  ];
519
542
  const ALIBABA_INTL_TOKEN_PLAN_QWEN_MODELS = [
@@ -547,6 +570,8 @@ const VOLCENGINE_ARK_MODELS = [
547
570
  "deepseek-v4-pro-260425",
548
571
  "deepseek-v4-flash-260425",
549
572
  "deepseek-v3-2-251201",
573
+ // No glm-5-3 row: Ark pins date-stamped snapshot ids (glm-5-2-260617) that cannot be
574
+ // guessed ahead of the vendor publishing them. Add it once /api/v3/models lists one.
550
575
  "glm-5-2-260617",
551
576
  "glm-4-7-251222",
552
577
  ];
@@ -560,6 +585,7 @@ const VOLCENGINE_CODING_PLAN_MODELS = [
560
585
  "doubao-seed-2.0-code",
561
586
  "deepseek-v4-pro",
562
587
  "deepseek-v4-flash",
588
+ "glm-5.3",
563
589
  "glm-5.2",
564
590
  "kimi-k2.6",
565
591
  "minimax-m3",
@@ -567,6 +593,7 @@ const VOLCENGINE_CODING_PLAN_MODELS = [
567
593
  const VOLCENGINE_AGENT_PLAN_MODELS = [
568
594
  "deepseek-v4-pro",
569
595
  "deepseek-v4-flash",
596
+ "glm-5.3",
570
597
  "glm-5.2",
571
598
  "kimi-k2.6",
572
599
  "minimax-m3",
@@ -584,6 +611,7 @@ const VOLCENGINE_PLAN_TEXT_ONLY_MODELS = [
584
611
  "doubao-seed-2.0-code",
585
612
  "deepseek-v4-pro",
586
613
  "deepseek-v4-flash",
614
+ "glm-5.3",
587
615
  "glm-5.2",
588
616
  "doubao-seed-2.0-pro",
589
617
  ];
@@ -599,6 +627,7 @@ const ALIBABA_INTL_TOKEN_PLAN_INPUT_MODALITIES: Record<string, string[]> = {
599
627
  "kimi-k2.7-code": ["text", "image"],
600
628
  "kimi-k2.6": ["text", "image"],
601
629
  "kimi-k2.5": ["text", "image"],
630
+ "glm-5.3": ["text"],
602
631
  "glm-5.2": ["text"],
603
632
  "glm-5.1": ["text"],
604
633
  "glm-5": ["text"],
@@ -722,7 +751,7 @@ const NVIDIA_NIM_NO_VISION_MODELS = [
722
751
  "nvidia/nemotron-3-ultra-550b-a55b", "nvidia/nemotron-mini-4b-instruct",
723
752
  "nvidia/nvidia-nemotron-nano-9b-v2",
724
753
  "openai/gpt-oss-120b", "openai/gpt-oss-20b",
725
- "poolside/laguna-xs-2.1", "z-ai/glm-5.2",
754
+ "poolside/laguna-xs-2.1", "z-ai/glm-5.3", "z-ai/glm-5.2",
726
755
  ];
727
756
  const KIMI_CODING_MODEL_CONTEXT_WINDOWS: Record<string, number> = Object.fromEntries(
728
757
  KIMI_CODING_MODELS.map(id => [id, id === "k3[1m]" ? KIMI_K3_1M_CONTEXT_WINDOW : KIMI_K3_STANDARD_CONTEXT_WINDOW]),
@@ -731,6 +760,7 @@ const KIMI_CODING_MODEL_INPUT_MODALITIES = Object.fromEntries(
731
760
  KIMI_CODING_K3_MODELS.map(id => [id, ["text", "image"]]),
732
761
  );
733
762
  const NEURALWATT_REASONING_HISTORY_MODELS = [
763
+ "glm-5.3", "glm-5.3-short",
734
764
  "glm-5.2", "glm-5.2-short",
735
765
  "kimi-k2.6", "kimi-k2.7-code",
736
766
  "qwen3.5-397b", "qwen3.6-35b",
@@ -749,6 +779,9 @@ const BASETEN_MODEL_REASONING_EFFORTS: Record<string, string[]> = {
749
779
  "thinkingmachines/inkling": BASETEN_FULL_REASONING_EFFORTS,
750
780
  "openai/gpt-oss-120b": BASETEN_FULL_REASONING_EFFORTS,
751
781
  "moonshotai/Kimi-K3": ["low", "high", "max"],
782
+ // 260814: GLM-5.3 honours low/high/max upstream, unlike 5.2's high/max on Baseten.
783
+ "zai-org/GLM-5.3": ["low", "high", "max"],
784
+ "zai-org/GLM-5.3-Fast": ["low", "high", "max"],
752
785
  "zai-org/GLM-5.2": ["high", "max"],
753
786
  "zai-org/GLM-5.2-Fast": ["high", "max"],
754
787
  };
@@ -757,6 +790,8 @@ const BASETEN_MODEL_REASONING_EFFORT_MAP: Record<string, Record<string, string>>
757
790
  "thinkingmachines/inkling": { none: "none", minimal: "minimal" },
758
791
  "openai/gpt-oss-120b": { none: "none", minimal: "minimal" },
759
792
  "moonshotai/Kimi-K3": { none: "none" },
793
+ "zai-org/GLM-5.3": { none: "none" },
794
+ "zai-org/GLM-5.3-Fast": { none: "none" },
760
795
  "zai-org/GLM-5.2": { none: "none" },
761
796
  "zai-org/GLM-5.2-Fast": { none: "none" },
762
797
  };
@@ -805,6 +840,7 @@ const DIGITALOCEAN_CHAT_COMPLETION_MODELS = [
805
840
  "nemotron-3-nano-omni",
806
841
  "nemotron-nano-12b-v2-vl",
807
842
  "mimo-v2.5-pro",
843
+ "glm-5.3",
808
844
  "glm-5.2",
809
845
  "glm-5.1",
810
846
  "glm-5",
@@ -812,6 +848,7 @@ const DIGITALOCEAN_CHAT_COMPLETION_MODELS = [
812
848
  "meta-llama/Meta-Llama-3.1-8B-Instruct",
813
849
  ] as const;
814
850
  const SCALEWAY_SERVERLESS_CHAT_MODELS = [
851
+ "glm-5.3",
815
852
  "glm-5.2",
816
853
  // gpt-oss-120b is intentionally omitted: Scaleway requires Responses API for tool calling,
817
854
  // while this preset routes Codex agent tools through Chat Completions.
@@ -832,17 +869,22 @@ const UMANS_MODELS = [
832
869
  "umans-coder",
833
870
  "umans-kimi-k2.7",
834
871
  "umans-flash",
872
+ "umans-glm-5.3",
835
873
  "umans-glm-5.2",
836
874
  "umans-glm-5.1",
837
875
  "umans-qwen3.6-35b-a3b",
838
876
  ];
839
877
  const UMANS_REASONING_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
840
878
  const UMANS_GLM_REASONING_EFFORTS = ["high", "xhigh", "max"];
841
- const UMANS_TEXT_ONLY_MODELS = ["umans-glm-5.2", "umans-glm-5.1"];
879
+ // 260814: Z.AI folds GLM-5.3 efforts into low/high/max, so `low` is a real tier here and
880
+ // `xhigh` is not distinct from `max` (docs.z.ai/devpack/latest-model).
881
+ const UMANS_GLM_53_REASONING_EFFORTS = ["low", "high", "max"];
882
+ const UMANS_TEXT_ONLY_MODELS = ["umans-glm-5.3", "umans-glm-5.2", "umans-glm-5.1"];
842
883
  const UMANS_MODEL_CONTEXT_WINDOWS: Record<string, number> = {
843
884
  "umans-coder": 262_144,
844
885
  "umans-kimi-k2.7": 262_144,
845
886
  "umans-flash": 262_144,
887
+ "umans-glm-5.3": 405_504,
846
888
  "umans-glm-5.2": 405_504,
847
889
  "umans-glm-5.1": 202_752,
848
890
  "umans-qwen3.6-35b-a3b": 262_144,
@@ -851,6 +893,7 @@ const UMANS_MODEL_INPUT_MODALITIES: Record<string, string[]> = Object.fromEntrie
851
893
  UMANS_MODELS.map(id => [id, UMANS_TEXT_ONLY_MODELS.includes(id) ? ["text"] : ["text", "image"]]),
852
894
  );
853
895
  const CLINE_PASS_MODELS = [
896
+ "cline-pass/glm-5.3",
854
897
  "cline-pass/glm-5.2",
855
898
  "cline-pass/kimi-k3",
856
899
  "cline-pass/kimi-k2.7-code",
@@ -864,6 +907,7 @@ const CLINE_PASS_MODELS = [
864
907
  "cline-pass/qwen3.7-plus",
865
908
  ];
866
909
  const CLINE_PASS_MODEL_CONTEXT_WINDOWS: Record<string, number> = {
910
+ "cline-pass/glm-5.3": 1_048_576,
867
911
  "cline-pass/glm-5.2": 1_048_576,
868
912
  "cline-pass/kimi-k3": 1_048_576,
869
913
  "cline-pass/kimi-k2.7-code": 262_144,
@@ -1177,6 +1221,7 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
1177
1221
  "umans-coder": UMANS_REASONING_EFFORTS,
1178
1222
  "umans-kimi-k2.7": UMANS_REASONING_EFFORTS,
1179
1223
  "umans-flash": UMANS_REASONING_EFFORTS,
1224
+ "umans-glm-5.3": UMANS_GLM_53_REASONING_EFFORTS,
1180
1225
  "umans-glm-5.2": UMANS_GLM_REASONING_EFFORTS,
1181
1226
  "umans-glm-5.1": UMANS_GLM_REASONING_EFFORTS,
1182
1227
  "umans-qwen3.6-35b-a3b": UMANS_REASONING_EFFORTS,
@@ -1200,6 +1245,7 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
1200
1245
  modelContextWindows: { "kimi-k3": KIMI_K3_STANDARD_CONTEXT_WINDOW },
1201
1246
  modelInputModalities: { "kimi-k3": ["text", "image"] },
1202
1247
  modelReasoningEfforts: {
1248
+ "glm-5.3": ZAI_GLM_53_REASONING_EFFORTS,
1203
1249
  "glm-5.2": ZAI_GLM_52_REASONING_EFFORTS,
1204
1250
  "kimi-k3": KIMI_CODING_K3_REASONING_EFFORTS,
1205
1251
  "kimi-k2.7-code": [],
@@ -1217,6 +1263,7 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
1217
1263
  ...Object.fromEntries(DEEPSEEK_THINKING_MODELS.map(id => [id, deepseekReasoningMapFor(id)])),
1218
1264
  },
1219
1265
  modelSupportsReasoningSummaries: {
1266
+ "glm-5.3": true,
1220
1267
  "glm-5.2": true,
1221
1268
  "glm-5.1": true,
1222
1269
  "glm-5": true,
@@ -1229,7 +1276,7 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
1229
1276
  // every model listed here (and the catalog advertises image input on their behalf).
1230
1277
  // Kimi K2.7 Code accepts text+image+video: do NOT list it here.
1231
1278
  noVisionModels: [
1232
- "glm-5.2", "glm-5", "glm-5.1",
1279
+ "glm-5.3", "glm-5.2", "glm-5", "glm-5.1",
1233
1280
  "deepseek-v4-flash", "deepseek-v4-pro",
1234
1281
  "mimo-v2-pro", "mimo-v2.5-pro",
1235
1282
  "minimax-m2.5", "minimax-m2.7",
@@ -1240,7 +1287,7 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
1240
1287
  noPenaltyModels: ["kimi-k3", "kimi-k2.7-code", "kimi-k2.7-code-highspeed"],
1241
1288
  autoToolChoiceOnlyModels: ["kimi-k2.7-code", "kimi-k2.7-code-highspeed"],
1242
1289
  // Issue #78: DeepSeek V4 thinking mode requires reasoning_content replay on tool-call turns.
1243
- preserveReasoningContentModels: ["glm-5.2", "kimi-k3", "kimi-k2.7-code", "kimi-k2.7-code-highspeed", ...DEEPSEEK_THINKING_MODELS],
1290
+ preserveReasoningContentModels: ["glm-5.3", "glm-5.2", "kimi-k3", "kimi-k2.7-code", "kimi-k2.7-code-highspeed", ...DEEPSEEK_THINKING_MODELS],
1244
1291
  },
1245
1292
  {
1246
1293
  id: "neuralwatt",
@@ -1249,10 +1296,13 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
1249
1296
  baseUrl: "https://api.neuralwatt.com/v1",
1250
1297
  authKind: "key",
1251
1298
  dashboardUrl: "https://portal.neuralwatt.com",
1252
- defaultModel: "glm-5.2",
1299
+ defaultModel: "glm-5.3",
1253
1300
  // 2026-07-10 live /v1/models: K2.5 rows were removed and GLM-5.2 short variants added.
1301
+ // 260814: the glm-5.3 quartet is speculative; live discovery is authoritative and drops
1302
+ // any id Neuralwatt has not published yet.
1254
1303
  // Evidence: devlog/_plan/260710_provider_hardening/003_research_aggregators.md and https://api.neuralwatt.com/v1/models.
1255
1304
  models: [
1305
+ "glm-5.3", "glm-5.3-fast", "glm-5.3-short", "glm-5.3-short-fast",
1256
1306
  "glm-5.2", "glm-5.2-fast", "glm-5.2-short", "glm-5.2-short-fast",
1257
1307
  "kimi-k2.6", "kimi-k2.6-fast",
1258
1308
  "kimi-k2.7-code",
@@ -1260,6 +1310,10 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
1260
1310
  ],
1261
1311
  // Neuralwatt's /v1/models metadata is authoritative; these static hints are the offline fallback.
1262
1312
  modelReasoningEfforts: {
1313
+ "glm-5.3": ZAI_GLM_53_REASONING_EFFORTS,
1314
+ "glm-5.3-fast": [],
1315
+ "glm-5.3-short": ZAI_GLM_53_REASONING_EFFORTS,
1316
+ "glm-5.3-short-fast": [],
1263
1317
  "glm-5.2": ZAI_GLM_52_REASONING_EFFORTS,
1264
1318
  "glm-5.2-fast": [],
1265
1319
  "glm-5.2-short": ZAI_GLM_52_REASONING_EFFORTS,
@@ -1275,8 +1329,8 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
1275
1329
  "qwen3.6-35b-fast": [],
1276
1330
  },
1277
1331
  thinkingBudgetModels: THINKING_BUDGET_MODELS,
1278
- noReasoningModels: ["glm-5.2-fast", "glm-5.2-short-fast", "kimi-k2.6-fast", "qwen3.5-397b-fast", "qwen3.6-35b-fast"],
1279
- noVisionModels: ["glm-5.2", "glm-5.2-fast", "glm-5.2-short", "glm-5.2-short-fast", "qwen3.5-397b", "qwen3.5-397b-fast"],
1332
+ noReasoningModels: ["glm-5.3-fast", "glm-5.3-short-fast", "glm-5.2-fast", "glm-5.2-short-fast", "kimi-k2.6-fast", "qwen3.5-397b-fast", "qwen3.6-35b-fast"],
1333
+ noVisionModels: ["glm-5.3", "glm-5.3-fast", "glm-5.3-short", "glm-5.3-short-fast", "glm-5.2", "glm-5.2-fast", "glm-5.2-short", "glm-5.2-short-fast", "qwen3.5-397b", "qwen3.5-397b-fast"],
1280
1334
  noTemperatureModels: ["kimi-k2.7-code"],
1281
1335
  noTopPModels: ["kimi-k2.7-code"],
1282
1336
  noPenaltyModels: ["kimi-k2.7-code"],
@@ -1397,7 +1451,7 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
1397
1451
  // 2026-07-10: defaultModel is frozen pending Vertex-specific Tier-2 evidence; Gemini API
1398
1452
  // evidence from ai.google.dev does not establish Vertex publisher availability.
1399
1453
  { id: "google-vertex", label: "Google Vertex AI", adapter: "google", baseUrl: "https://aiplatform.googleapis.com", authKind: "key", dashboardUrl: "https://console.cloud.google.com/vertex-ai", defaultModel: "gemini-3-pro", googleMode: "vertex", jawcodeBundle: "google", extraMetadataAliases: ["gemini-vertex"] },
1400
- { id: "google-antigravity", label: "Google Antigravity", adapter: "google", baseUrl: "https://daily-cloudcode-pa.googleapis.com", authKind: "oauth", dashboardUrl: "https://antigravity.google", models: ANTIGRAVITY_MODELS, liveModels: true, defaultModel: "gemini-3.6-flash", modelContextWindows: ANTIGRAVITY_MODEL_CONTEXT_WINDOWS, modelInputModalities: ANTIGRAVITY_MODEL_INPUT_MODALITIES, modelReasoningEfforts: ANTIGRAVITY_MODEL_EFFORTS, googleMode: "cloud-code-assist", jawcodeBundle: "google", extraMetadataAliases: ["antigravity", "gemini-antigravity"] },
1454
+ { id: "google-antigravity", label: "Google Antigravity", adapter: "google", baseUrl: "https://daily-cloudcode-pa.googleapis.com", authKind: "oauth", dashboardUrl: "https://antigravity.google", models: ANTIGRAVITY_MODELS, liveModels: true, defaultModel: "gemini-3.7-flash", modelContextWindows: ANTIGRAVITY_MODEL_CONTEXT_WINDOWS, modelInputModalities: ANTIGRAVITY_MODEL_INPUT_MODALITIES, modelReasoningEfforts: ANTIGRAVITY_MODEL_EFFORTS, googleMode: "cloud-code-assist", jawcodeBundle: "google", extraMetadataAliases: ["antigravity", "gemini-antigravity"] },
1401
1455
  { id: "azure-openai", label: "Azure OpenAI", adapter: "azure-openai", baseUrl: "https://{resource}.openai.azure.com/openai", authKind: "key", featured: true, dashboardUrl: "https://portal.azure.com" },
1402
1456
  { id: "ollama", label: "Ollama (local)", adapter: "openai-chat", baseUrl: "http://localhost:11434/v1", authKind: "local", allowPrivateNetworkByDefault: true, allowBaseUrlOverride: true, featured: true, note: "Local — key usually blank" },
1403
1457
  { id: "vllm", label: "vLLM (local)", adapter: "openai-chat", baseUrl: "http://localhost:8000/v1", authKind: "local", allowPrivateNetworkByDefault: true, allowBaseUrlOverride: true, featured: true, note: "Local — key usually blank" },
@@ -1917,18 +1971,20 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
1917
1971
  { id: "venice", label: "Venice", baseUrl: "https://api.venice.ai/api/v1", adapter: "openai-chat", authKind: "key", dashboardUrl: "https://venice.ai/settings/api" },
1918
1972
  // 260710 GLM-5.2 context and path-specific ids: Tier-2 evidence in
1919
1973
  // devlog/_plan/260710_provider_hardening/002_research_cn.md.
1974
+ // 260814: glm-5.3 / glm-5.3[1m] added per docs.z.ai/devpack/latest-model, which lists them as
1975
+ // Coding Plan ids on this same endpoint. Capabilities mirror 5.2 until Z.AI publishes tables.
1920
1976
  {
1921
1977
  id: "zai", label: "Z.AI — GLM Coding Plan", baseUrl: "https://api.z.ai/api/coding/paas/v4", adapter: "openai-chat", authKind: "key",
1922
- dashboardUrl: "https://z.ai/manage-apikey/apikey-list", defaultModel: "glm-5.2",
1923
- note: "GLM-5.2 coding subscription",
1924
- models: ["glm-5.2", "glm-5.2[1m]", "glm-5.1", "glm-5", "glm-4.6"],
1925
- modelContextWindows: { "glm-5.2": 1_000_000, "glm-5.2[1m]": 1_000_000 },
1978
+ dashboardUrl: "https://z.ai/manage-apikey/apikey-list", defaultModel: "glm-5.3",
1979
+ note: "GLM-5.3 coding subscription",
1980
+ models: ["glm-5.3", "glm-5.3[1m]", "glm-5.2", "glm-5.2[1m]", "glm-5.1", "glm-5", "glm-4.6"],
1981
+ modelContextWindows: { "glm-5.3": 1_000_000, "glm-5.3[1m]": 1_000_000, "glm-5.2": 1_000_000, "glm-5.2[1m]": 1_000_000 },
1926
1982
  // Z.AI's OpenAI path returns 400 code 1211 for bracketed model ids.
1927
1983
  modelSuffixBracketStrip: true,
1928
- noVisionModels: ZAI_GLM_52_MODELS,
1929
- modelReasoningEfforts: Object.fromEntries(ZAI_GLM_52_MODELS.map(id => [id, ZAI_GLM_52_REASONING_EFFORTS])),
1930
- modelSupportsReasoningSummaries: Object.fromEntries(ZAI_GLM_52_MODELS.map(id => [id, true])),
1931
- preserveReasoningContentModels: ZAI_GLM_52_MODELS,
1984
+ noVisionModels: ZAI_GLM_5X_MODELS,
1985
+ modelReasoningEfforts: ZAI_GLM_5X_REASONING_EFFORTS,
1986
+ modelSupportsReasoningSummaries: Object.fromEntries(ZAI_GLM_5X_MODELS.map(id => [id, true])),
1987
+ preserveReasoningContentModels: ZAI_GLM_5X_MODELS,
1932
1988
  },
1933
1989
  // Zhipu's domestic BigModel platform: OpenAI-compatible pay-as-you-go on open.bigmodel.cn — a
1934
1990
  // different host and billing product from the `zai` coding-plan subscription above.
@@ -1999,15 +2055,15 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
1999
2055
  adapter: "openai-chat",
2000
2056
  authKind: "key",
2001
2057
  dashboardUrl: "https://bigmodel.cn/console/usercenter/apikeys",
2002
- defaultModel: "glm-5.2",
2003
- models: ["glm-5.2", "glm-5.2[1m]", "glm-5.1", "glm-5", "glm-4.6"],
2058
+ defaultModel: "glm-5.3",
2059
+ models: ["glm-5.3", "glm-5.3[1m]", "glm-5.2", "glm-5.2[1m]", "glm-5.1", "glm-5", "glm-4.6"],
2004
2060
  jawcodeBundle: "zai",
2005
- modelContextWindows: { "glm-5.2": 1_000_000, "glm-5.2[1m]": 1_000_000 },
2061
+ modelContextWindows: { "glm-5.3": 1_000_000, "glm-5.3[1m]": 1_000_000, "glm-5.2": 1_000_000, "glm-5.2[1m]": 1_000_000 },
2006
2062
  modelSuffixBracketStrip: true,
2007
- noVisionModels: ZAI_GLM_52_MODELS,
2008
- modelReasoningEfforts: Object.fromEntries(ZAI_GLM_52_MODELS.map(id => [id, ZAI_GLM_52_REASONING_EFFORTS])),
2009
- modelSupportsReasoningSummaries: Object.fromEntries(ZAI_GLM_52_MODELS.map(id => [id, true])),
2010
- preserveReasoningContentModels: ZAI_GLM_52_MODELS,
2063
+ noVisionModels: ZAI_GLM_5X_MODELS,
2064
+ modelReasoningEfforts: ZAI_GLM_5X_REASONING_EFFORTS,
2065
+ modelSupportsReasoningSummaries: Object.fromEntries(ZAI_GLM_5X_MODELS.map(id => [id, true])),
2066
+ preserveReasoningContentModels: ZAI_GLM_5X_MODELS,
2011
2067
  // No liveModels: the same reasoning as the pay-as-you-go row — an unverified live claim
2012
2068
  // yields an empty picker at runtime.
2013
2069
  note: "Domestic BigModel Coding Plan endpoint (open.bigmodel.cn)",
@@ -2146,11 +2202,12 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
2146
2202
  modelInputModalities: ALIBABA_TOKEN_PLAN_INPUT_MODALITIES,
2147
2203
  modelContextWindows: {
2148
2204
  "qwen3.8-max": 983_616, "qwen3.7-max": 1_000_000, "qwen3.7-plus": 1_000_000,
2149
- "qwen3.6-flash": 1_000_000, "glm-5.2": 1_000_000, "deepseek-v4-pro": 1_000_000,
2205
+ "qwen3.6-flash": 1_000_000, "glm-5.3": 1_000_000, "glm-5.2": 1_000_000, "deepseek-v4-pro": 1_000_000,
2150
2206
  },
2151
2207
  modelReasoningEfforts: {
2152
2208
  ...Object.fromEntries(ALIBABA_TOKEN_PLAN_QWEN_MODELS.map(id => [id, THINKING_BUDGET_EFFORTS])),
2153
2209
  "qwen3.8-max": QWEN38_REASONING_EFFORTS,
2210
+ "glm-5.3": ZAI_GLM_53_REASONING_EFFORTS,
2154
2211
  "glm-5.2": ZAI_GLM_52_REASONING_EFFORTS,
2155
2212
  "deepseek-v4-pro": deepseekThinkingEffortsFor("deepseek-v4-pro"),
2156
2213
  },
@@ -2158,8 +2215,8 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
2158
2215
  modelReasoningEffortMap: { "deepseek-v4-pro": deepseekReasoningMapFor("deepseek-v4-pro") },
2159
2216
  directReasoningEffortModels: ["qwen3.8-max"],
2160
2217
  thinkingBudgetModels: ALIBABA_TOKEN_PLAN_QWEN_MODELS.filter(id => id !== "qwen3.8-max"),
2161
- preserveReasoningContentModels: ["glm-5.2", "deepseek-v4-pro", "qwen3.8-max", "qwen3.7-max", "qwen3.7-plus", "qwen3.6-flash"],
2162
- noVisionModels: ["glm-5.2", "deepseek-v4-pro"],
2218
+ preserveReasoningContentModels: ["glm-5.3", "glm-5.2", "deepseek-v4-pro", "qwen3.8-max", "qwen3.7-max", "qwen3.7-plus", "qwen3.6-flash"],
2219
+ noVisionModels: ["glm-5.3", "glm-5.2", "deepseek-v4-pro"],
2163
2220
  },
2164
2221
  {
2165
2222
  id: "alibaba-token-plan-intl",
@@ -2181,12 +2238,13 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
2181
2238
  "qwen3.7-max": 1_000_000, "qwen3.7-plus": 1_000_000, "qwen3.6-plus": 1_000_000, "qwen3.6-flash": 1_000_000,
2182
2239
  "deepseek-v4-pro": 1_000_000, "deepseek-v4-flash": 1_000_000, "deepseek-v3.2": 131_072,
2183
2240
  "kimi-k2.7-code": 262_144, "kimi-k2.6": 262_144, "kimi-k2.5": 262_144,
2184
- "glm-5.2": 1_000_000, "glm-5.1": 1_000_000, "glm-5": 1_000_000,
2241
+ "glm-5.3": 1_000_000, "glm-5.2": 1_000_000, "glm-5.1": 1_000_000, "glm-5": 1_000_000,
2185
2242
  "MiniMax-M2.5": 204_800,
2186
2243
  },
2187
2244
  modelReasoningEfforts: {
2188
2245
  ...Object.fromEntries(ALIBABA_INTL_TOKEN_PLAN_QWEN_MODELS.map(id => [id, THINKING_BUDGET_EFFORTS])),
2189
2246
  "qwen3.8-max": QWEN38_REASONING_EFFORTS,
2247
+ "glm-5.3": ZAI_GLM_53_REASONING_EFFORTS,
2190
2248
  "glm-5.2": ZAI_GLM_52_REASONING_EFFORTS,
2191
2249
  "deepseek-v4-pro": deepseekThinkingEffortsFor("deepseek-v4-pro"),
2192
2250
  "deepseek-v4-flash": deepseekThinkingEffortsFor("deepseek-v4-flash"),
@@ -2197,8 +2255,8 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
2197
2255
  },
2198
2256
  directReasoningEffortModels: ["qwen3.8-max"],
2199
2257
  thinkingBudgetModels: ALIBABA_INTL_TOKEN_PLAN_QWEN_MODELS.filter(id => id !== "qwen3.8-max"),
2200
- preserveReasoningContentModels: ["glm-5.2", "deepseek-v4-pro", "deepseek-v4-flash", "qwen3.8-max", "qwen3.7-max", "qwen3.7-plus", "qwen3.6-plus", "qwen3.6-flash"],
2201
- noVisionModels: ["deepseek-v4-pro", "deepseek-v4-flash", "deepseek-v3.2", "glm-5.2", "glm-5.1", "glm-5", "MiniMax-M2.5"],
2258
+ preserveReasoningContentModels: ["glm-5.3", "glm-5.2", "deepseek-v4-pro", "deepseek-v4-flash", "qwen3.8-max", "qwen3.7-max", "qwen3.7-plus", "qwen3.6-plus", "qwen3.6-flash"],
2259
+ noVisionModels: ["deepseek-v4-pro", "deepseek-v4-flash", "deepseek-v3.2", "glm-5.3", "glm-5.2", "glm-5.1", "glm-5", "MiniMax-M2.5"],
2202
2260
  noReasoningModels: ["kimi-k2.7-code", "kimi-k2.6", "kimi-k2.5", "deepseek-v3.2", "glm-5.1", "glm-5", "MiniMax-M2.5"],
2203
2261
  modelDefaultReasoningEfforts: { "qwen3.8-max": "xhigh" },
2204
2262
  },
@@ -2230,10 +2288,10 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
2230
2288
  authKind: "key",
2231
2289
  dashboardUrl: "https://ollama.com/settings/keys",
2232
2290
  // Live IDs verified 2026-07-10; qwen3-coder:480b retires 2026-07-15.
2233
- models: ["glm-5.2", "deepseek-v4-pro", "qwen3-coder:480b", "gpt-oss:120b", "kimi-k2.6", "minimax-m3", "qwen3.5:397b", "gemma4:31b"],
2234
- defaultModel: "glm-5.2",
2291
+ models: ["glm-5.3", "glm-5.2", "deepseek-v4-pro", "qwen3-coder:480b", "gpt-oss:120b", "kimi-k2.6", "minimax-m3", "qwen3.5:397b", "gemma4:31b"],
2292
+ defaultModel: "glm-5.3",
2235
2293
  noVisionModels: [
2236
- "glm-5.2", "glm-5.1", "glm-5", "glm-4.7",
2294
+ "glm-5.3", "glm-5.2", "glm-5.1", "glm-5", "glm-4.7",
2237
2295
  "minimax-m2.7", "minimax-m2.5", "minimax-m2.1",
2238
2296
  "nemotron-3-ultra", "nemotron-3-super",
2239
2297
  "deepseek-v4-pro", "deepseek-v4-flash",
@@ -2406,6 +2464,7 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [
2406
2464
  "@cf/qwen/qwq-32b",
2407
2465
  "@cf/deepseek-ai/deepseek-r1-distill-qwen-32b",
2408
2466
  "@cf/moonshotai/kimi-k2.7-code",
2467
+ "@cf/zai-org/glm-5.3",
2409
2468
  "@cf/zai-org/glm-5.2",
2410
2469
  "@cf/mistralai/mistral-small-3.1-24b-instruct",
2411
2470
  ],
@@ -52,6 +52,10 @@ const DAYBREAK_RED: Cost4 = { input: 12.5, output: 75, cacheRead: 1.25, cacheWri
52
52
  const GPT56_TERRA: Cost4 = { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 2.5 };
53
53
  const GPT56_LUNA: Cost4 = { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 };
54
54
  const GEMINI_36_FLASH: Cost4 = { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 0 };
55
+ // Gemini 3.7 Flash launch promotion: Google publishes $0.75 in / $3.75 out per 1M
56
+ // through 2026-12-31, stepping up to $1.50 / $7.50 on 2027-01-01. Revisit this row
57
+ // then — the promotional rate is dated on the pricing page, not open-ended.
58
+ const GEMINI_37_FLASH: Cost4 = { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 };
55
59
  const MINIMAX_M21_HIGHSPEED: Cost4 = { input: 0.6, output: 2.4, cacheRead: 0.03, cacheWrite: 0.375 };
56
60
  const KIMI_K3: Cost4 = { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3 };
57
61
  const KIMI_K27_CODE: Cost4 = { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0.95 };
@@ -70,6 +74,7 @@ const CLAUDE_OPUS_5_DERIVED_SOURCE =
70
74
  const ANTHROPIC_PRICING = "https://platform.claude.com/docs/en/about-claude/pricing (official; 5m cache-write tier)";
71
75
 
72
76
  const GEMINI_PRICING = "https://ai.google.dev/gemini-api/docs/pricing (2026-07-22); cacheWrite=0: storage is billed per-hour, not per-token";
77
+ const GEMINI_37_PRICING = "https://ai.google.dev/gemini-api/docs/pricing (2026-08-14); promotional rate through 2026-12-31, rises to 1.50/7.50 on 2027-01-01; cacheWrite=0: storage is billed per-hour, not per-token";
73
78
  const MINIMAX_PRICING = "https://platform.minimax.io/docs/guides/pricing-paygo";
74
79
  const OPENAI_GPT56_PRICING = "https://developers.openai.com/api/docs/pricing";
75
80
  const DEEPSEEK_PRICING = "https://api-docs.deepseek.com/quick_start/pricing-details-usd; V4 Flash alias transition scheduled 2026-07-24 — re-verify after";
@@ -102,6 +107,12 @@ export const EXPECTED_PRICE_OVERLAYS: readonly ExpectedPriceOverlay[] = [
102
107
  // Google Antigravity effort-suffix variants — derived from the verified base-model
103
108
  // price (Google does not publish per-suffix prices; Agent inference bills at the
104
109
  // base model's standard rate per the official Billing FAQ).
110
+ // 3.7 Flash rides CCA, whose billing equivalence to the Developer API list price is
111
+ // not published, so this is `verified-derived` rather than `verified`: the number is
112
+ // proven, the claim that Antigravity charges it is inferred.
113
+ { provider: "google-antigravity", modelId: "gemini-3.7-flash", cost4: GEMINI_37_FLASH, source: `derived: Gemini 3.7 Flash promotional rate through 2026-12-31 ${GEMINI_37_PRICING}`, verifiedAt: "2026-08-14", status: "verified-derived" },
114
+ // Retained after the 3.6 retirement: historical usage.jsonl rows still carry these
115
+ // ids, and dropping the row would silently zero the cost of requests already made.
105
116
  { provider: "google-antigravity", modelId: "gemini-3.6-flash", cost4: GEMINI_36_FLASH, source: `collapsed base ID ${GEMINI_PRICING}`, verifiedAt: "2026-07-22", status: "verified" },
106
117
  { provider: "google-antigravity", modelId: "gemini-3.1-pro", cost4: GEMINI_31_PRO, source: `collapsed base ID ${GEMINI_PRICING}`, verifiedAt: "2026-07-22", status: "verified" },
107
118
  // OpenAI GPT-5.6 `-pro` virtual selections. The virtual resolver keeps the SELECTED id in
@@ -130,6 +141,8 @@ export const EXPECTED_PRICE_OVERLAYS: readonly ExpectedPriceOverlay[] = [
130
141
  { provider: "google-antigravity", modelId: "gemini-3-flash-agent", cost4: GEMINI_36_FLASH, source: `compat alias -> gemini-3.6-flash-high ${GEMINI_PRICING}`, verifiedAt: "2026-07-22", status: "verified-derived" },
131
142
  // Direct Google Gemini API current model (verified — published table).
132
143
  { provider: "google", modelId: "gemini-3.6-flash", cost4: GEMINI_36_FLASH, source: GEMINI_PRICING, verifiedAt: "2026-07-22", status: "verified" },
144
+ // Developer API row: the price IS published for this surface, so `verified`.
145
+ { provider: "google", modelId: "gemini-3.7-flash", cost4: GEMINI_37_FLASH, source: GEMINI_37_PRICING, verifiedAt: "2026-08-14", status: "verified" },
133
146
  { provider: "google-antigravity", modelId: "gemini-3.1-pro-preview", cost4: GEMINI_31_PRO, source: GEMINI_PRICING, verifiedAt: "2026-07-20", status: "verified" },
134
147
  // Antigravity-bundled third-party models — derived from the underlying vendor's
135
148
  // official API price (Antigravity itself bills via subscription quota).