@gajae-code/ai 0.18.12 → 0.19.0
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.
- package/CHANGELOG.md +35 -0
- package/dist/types/auth-storage.d.ts +18 -5
- package/dist/types/model-pricing.d.ts +8 -0
- package/dist/types/model-thinking.d.ts +11 -0
- package/dist/types/provider-models/google.d.ts +2 -0
- package/dist/types/providers/amazon-bedrock.d.ts +17 -2
- package/dist/types/providers/anthropic.d.ts +15 -0
- package/dist/types/providers/google-gemini-headers.d.ts +1 -1
- package/dist/types/utils/discovery/antigravity.d.ts +5 -1
- package/dist/types/utils/oauth/glm-zcode.d.ts +0 -30
- package/package.json +3 -3
- package/src/auth-storage.ts +261 -52
- package/src/model-pricing.d.ts +8 -0
- package/src/model-pricing.ts +87 -0
- package/src/model-thinking.d.ts +11 -0
- package/src/model-thinking.ts +60 -5
- package/src/models.json +245 -0
- package/src/models.ts +10 -3
- package/src/provider-models/google.ts +4 -0
- package/src/providers/amazon-bedrock.d.ts +17 -2
- package/src/providers/amazon-bedrock.ts +56 -5
- package/src/providers/anthropic.d.ts +15 -0
- package/src/providers/anthropic.ts +91 -14
- package/src/providers/google-gemini-headers.d.ts +1 -1
- package/src/providers/google-gemini-headers.ts +6 -6
- package/src/providers/transform-messages.ts +32 -1
- package/src/stream.ts +4 -4
- package/src/utils/discovery/antigravity.ts +69 -26
- package/src/utils/oauth/glm-zcode.d.ts +0 -30
- package/src/utils/oauth/glm-zcode.ts +15 -4
- package/src/utils/oauth/openai-codex.ts +41 -6
- package/src/utils/proxy.ts +35 -6
package/src/model-thinking.d.ts
CHANGED
|
@@ -87,12 +87,23 @@ export declare function mapEffortToAnthropicAdaptiveEffort<TApi extends Api>(mod
|
|
|
87
87
|
* - Thinking content is omitted by default (needs display: "summarized")
|
|
88
88
|
*/
|
|
89
89
|
export declare function hasOpus47ApiRestrictions(modelId: string): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Haiku 5+ enables adaptive thinking when the `thinking` field is omitted.
|
|
92
|
+
* An explicit user-facing Off choice must therefore send `type: "disabled"`.
|
|
93
|
+
*/
|
|
94
|
+
export declare function requiresAnthropicThinkingDisableWhenOff(modelId: string): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Haiku 5+ and Opus 4.7+ reject sampling parameters on the Anthropic Messages API.
|
|
97
|
+
* https://platform.claude.com/docs/en/models/haiku-5-5/migration-guide#remove-sampling-parameters
|
|
98
|
+
*/
|
|
99
|
+
export declare function hasAnthropicModelSamplingRestrictions(modelId: string): boolean;
|
|
90
100
|
/**
|
|
91
101
|
* Adaptive thinking `display` is supported starting with Anthropic Opus 4.7.
|
|
92
102
|
* Older adaptive-thinking models (Opus 4.6, Sonnet 4.6+) reject the field.
|
|
93
103
|
* Fable (5+) postdates Opus 4.7, accepts `display`, and defaults it to
|
|
94
104
|
* "omitted" — thinking tokens are billed but no content streams back — so it
|
|
95
105
|
* must opt in like Opus 4.7+ (issue #2791).
|
|
106
|
+
* Haiku 5+ also accepts `display` and defaults it to "omitted".
|
|
96
107
|
*
|
|
97
108
|
* Shares `hasOpus47ApiRestrictions` version parsing on purpose: the two
|
|
98
109
|
* predicates describe the same API generation, and a private `claude-opus-(\d+)-(\d+)`
|
package/src/model-thinking.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
isCodexGpt56Tier,
|
|
6
6
|
isCodexProductTransport,
|
|
7
7
|
} from "./context-cap-policy";
|
|
8
|
-
import { applyOpenAIModelPricing } from "./model-pricing";
|
|
8
|
+
import { applyAnthropicModelPricing, applyOpenAIModelPricing } from "./model-pricing";
|
|
9
9
|
import {
|
|
10
10
|
isAuditedOpenAIReasoningTransport,
|
|
11
11
|
parseDirectXaiReasoningEffortGeneration,
|
|
@@ -56,6 +56,17 @@ const DEFAULT_REASONING_EFFORTS_WITH_XHIGH_AND_MAX: readonly Effort[] = [
|
|
|
56
56
|
Effort.XHigh,
|
|
57
57
|
Effort.Max,
|
|
58
58
|
];
|
|
59
|
+
// Haiku 5.5 supports low, medium, high, xhigh, and max on both Anthropic
|
|
60
|
+
// Messages and Bedrock Converse; neither contract lists minimal.
|
|
61
|
+
// https://platform.claude.com/docs/en/build-with-claude/effort#effort-levels
|
|
62
|
+
// https://docs.aws.amazon.com/bedrock/latest/userguide/model-card-anthropic-claude-haiku-5-5.html
|
|
63
|
+
const ANTHROPIC_HAIKU_5_5_EFFORTS: readonly Effort[] = [
|
|
64
|
+
Effort.Low,
|
|
65
|
+
Effort.Medium,
|
|
66
|
+
Effort.High,
|
|
67
|
+
Effort.XHigh,
|
|
68
|
+
Effort.Max,
|
|
69
|
+
];
|
|
59
70
|
const GEMINI_3_PRO_EFFORTS: readonly Effort[] = [Effort.Low, Effort.High];
|
|
60
71
|
const GEMINI_3_FLASH_EFFORTS: readonly Effort[] = [Effort.Minimal, Effort.Low, Effort.Medium, Effort.High];
|
|
61
72
|
// Gemini 3.7 Flash dropped `minimal`; the official API returns an error for it.
|
|
@@ -96,7 +107,7 @@ type SemVer = {
|
|
|
96
107
|
};
|
|
97
108
|
|
|
98
109
|
type GeminiKind = "pro" | "flash" | "argon";
|
|
99
|
-
type AnthropicKind = "opus" | "sonnet" | "fable";
|
|
110
|
+
type AnthropicKind = "opus" | "sonnet" | "fable" | "haiku";
|
|
100
111
|
type OpenAIVariant =
|
|
101
112
|
| "astra"
|
|
102
113
|
| "base"
|
|
@@ -538,12 +549,34 @@ export function hasOpus47ApiRestrictions(modelId: string): boolean {
|
|
|
538
549
|
return semverGte(parsed.version, "4.7") && parsed.kind === "opus";
|
|
539
550
|
}
|
|
540
551
|
|
|
552
|
+
function isAnthropicHaikuAdaptiveModel(modelId: string): boolean {
|
|
553
|
+
const parsed = parseAnthropicModel(getCanonicalModelId(modelId));
|
|
554
|
+
return parsed?.kind === "haiku" && semverGte(parsed.version, "5.0");
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Haiku 5+ enables adaptive thinking when the `thinking` field is omitted.
|
|
559
|
+
* An explicit user-facing Off choice must therefore send `type: "disabled"`.
|
|
560
|
+
*/
|
|
561
|
+
export function requiresAnthropicThinkingDisableWhenOff(modelId: string): boolean {
|
|
562
|
+
return isAnthropicHaikuAdaptiveModel(modelId);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Haiku 5+ and Opus 4.7+ reject sampling parameters on the Anthropic Messages API.
|
|
567
|
+
* https://platform.claude.com/docs/en/models/haiku-5-5/migration-guide#remove-sampling-parameters
|
|
568
|
+
*/
|
|
569
|
+
export function hasAnthropicModelSamplingRestrictions(modelId: string): boolean {
|
|
570
|
+
return hasOpus47ApiRestrictions(modelId) || isAnthropicHaikuAdaptiveModel(modelId);
|
|
571
|
+
}
|
|
572
|
+
|
|
541
573
|
/**
|
|
542
574
|
* Adaptive thinking `display` is supported starting with Anthropic Opus 4.7.
|
|
543
575
|
* Older adaptive-thinking models (Opus 4.6, Sonnet 4.6+) reject the field.
|
|
544
576
|
* Fable (5+) postdates Opus 4.7, accepts `display`, and defaults it to
|
|
545
577
|
* "omitted" — thinking tokens are billed but no content streams back — so it
|
|
546
578
|
* must opt in like Opus 4.7+ (issue #2791).
|
|
579
|
+
* Haiku 5+ also accepts `display` and defaults it to "omitted".
|
|
547
580
|
*
|
|
548
581
|
* Shares `hasOpus47ApiRestrictions` version parsing on purpose: the two
|
|
549
582
|
* predicates describe the same API generation, and a private `claude-opus-(\d+)-(\d+)`
|
|
@@ -554,7 +587,7 @@ export function hasOpus47ApiRestrictions(modelId: string): boolean {
|
|
|
554
587
|
*/
|
|
555
588
|
export function supportsAnthropicAdaptiveThinkingDisplay(modelId: string): boolean {
|
|
556
589
|
if (/claude-fable-\d/.test(modelId)) return true;
|
|
557
|
-
return hasOpus47ApiRestrictions(modelId);
|
|
590
|
+
return hasOpus47ApiRestrictions(modelId) || isAnthropicHaikuAdaptiveModel(modelId);
|
|
558
591
|
}
|
|
559
592
|
|
|
560
593
|
function anthropicModelHasRealXHighEffort<TApi extends Api>(model: ApiModel<TApi>): boolean {
|
|
@@ -576,6 +609,7 @@ function anthropicModelHasRealXHighEffort<TApi extends Api>(model: ApiModel<TApi
|
|
|
576
609
|
|
|
577
610
|
function applyGeneratedModelPolicy(model: ApiModel<Api>): void {
|
|
578
611
|
applyOpenAIModelPricing(model);
|
|
612
|
+
applyAnthropicModelPricing(model);
|
|
579
613
|
const copilotLimits = model.provider === "github-copilot" ? COPILOT_GENERATED_LIMITS[model.id] : undefined;
|
|
580
614
|
if (copilotLimits) {
|
|
581
615
|
model.contextWindow = copilotLimits.contextWindow;
|
|
@@ -879,6 +913,19 @@ function inferDefaultEffort<TApi extends Api>(model: ApiModel<TApi>, parsedModel
|
|
|
879
913
|
if (model.provider === "omlx") {
|
|
880
914
|
return Effort.Medium;
|
|
881
915
|
}
|
|
916
|
+
if (
|
|
917
|
+
parsedModel.family === "anthropic" &&
|
|
918
|
+
parsedModel.kind === "haiku" &&
|
|
919
|
+
((model.provider === "anthropic" &&
|
|
920
|
+
model.api === "anthropic-messages" &&
|
|
921
|
+
semverGte(parsedModel.version, "5.0")) ||
|
|
922
|
+
(model.provider === "amazon-bedrock" &&
|
|
923
|
+
model.api === "bedrock-converse-stream" &&
|
|
924
|
+
semverGte(parsedModel.version, "5.5")))
|
|
925
|
+
) {
|
|
926
|
+
// Haiku 5.5 defaults to medium adaptive effort instead of the global high.
|
|
927
|
+
return Effort.Medium;
|
|
928
|
+
}
|
|
882
929
|
return undefined;
|
|
883
930
|
}
|
|
884
931
|
|
|
@@ -1027,6 +1074,9 @@ function inferAnthropicSupportedEfforts<TApi extends Api>(
|
|
|
1027
1074
|
(model.api === "anthropic-messages" || model.api === "bedrock-converse-stream") &&
|
|
1028
1075
|
semverGte(parsedModel.version, "4.6")
|
|
1029
1076
|
) {
|
|
1077
|
+
if (parsedModel.kind === "haiku" && semverGte(parsedModel.version, "5.5")) {
|
|
1078
|
+
return ANTHROPIC_HAIKU_5_5_EFFORTS;
|
|
1079
|
+
}
|
|
1030
1080
|
if (parsedModel.kind === "fable") {
|
|
1031
1081
|
// Fable exposes Anthropic's Messages-only xhigh preset; Bedrock
|
|
1032
1082
|
// Converse lacks it (same split as Opus 4.7+ below).
|
|
@@ -1105,7 +1155,7 @@ function inferThinkingControlMode<TApi extends Api>(
|
|
|
1105
1155
|
if (parsedModel.family === "anthropic") {
|
|
1106
1156
|
if (
|
|
1107
1157
|
semverGte(parsedModel.version, "4.6") &&
|
|
1108
|
-
(parsedModel.kind === "opus" || parsedModel.kind === "fable")
|
|
1158
|
+
(parsedModel.kind === "opus" || parsedModel.kind === "fable" || parsedModel.kind === "haiku")
|
|
1109
1159
|
) {
|
|
1110
1160
|
return "anthropic-adaptive";
|
|
1111
1161
|
}
|
|
@@ -1146,7 +1196,7 @@ function parseGeminiModel(modelId: string): GeminiModel | null {
|
|
|
1146
1196
|
}
|
|
1147
1197
|
|
|
1148
1198
|
function parseAnthropicModel(modelId: string): AnthropicModel | null {
|
|
1149
|
-
const match = /claude-(opus|sonnet|fable)-(\d{1,2}(?:[.-]\d{1,2}){0,2})\b/.exec(modelId);
|
|
1199
|
+
const match = /claude-(opus|sonnet|fable|haiku)-(\d{1,2}(?:[.-]\d{1,2}){0,2})\b/.exec(modelId);
|
|
1150
1200
|
if (!match) {
|
|
1151
1201
|
return null;
|
|
1152
1202
|
}
|
|
@@ -1154,6 +1204,11 @@ function parseAnthropicModel(modelId: string): AnthropicModel | null {
|
|
|
1154
1204
|
if (!version) {
|
|
1155
1205
|
return null;
|
|
1156
1206
|
}
|
|
1207
|
+
// Haiku is recognized from generation 5 only. Haiku 4.5 predates the
|
|
1208
|
+
// adaptive-thinking policy and keeps the generic (unparsed) budget ladder.
|
|
1209
|
+
if (match[1] === "haiku" && !semverGte(version, "5.0")) {
|
|
1210
|
+
return null;
|
|
1211
|
+
}
|
|
1157
1212
|
return { family: "anthropic", kind: match[1] as AnthropicKind, version };
|
|
1158
1213
|
}
|
|
1159
1214
|
|
package/src/models.json
CHANGED
|
@@ -779,6 +779,41 @@
|
|
|
779
779
|
"mode": "anthropic-adaptive"
|
|
780
780
|
}
|
|
781
781
|
},
|
|
782
|
+
"anthropic.claude-haiku-5-5": {
|
|
783
|
+
"api": "bedrock-converse-stream",
|
|
784
|
+
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
|
785
|
+
"contextWindow": 1000000,
|
|
786
|
+
"cost": {
|
|
787
|
+
"cacheRead": 0.01,
|
|
788
|
+
"cacheWrite": 0.125,
|
|
789
|
+
"input": 0.1,
|
|
790
|
+
"output": 0.5
|
|
791
|
+
},
|
|
792
|
+
"id": "anthropic.claude-haiku-5-5",
|
|
793
|
+
"input": [
|
|
794
|
+
"text",
|
|
795
|
+
"image"
|
|
796
|
+
],
|
|
797
|
+
"longContextPricing": {
|
|
798
|
+
"cost": {
|
|
799
|
+
"cacheRead": 0.05,
|
|
800
|
+
"cacheWrite": 0.625,
|
|
801
|
+
"input": 0.5,
|
|
802
|
+
"output": 2.5
|
|
803
|
+
},
|
|
804
|
+
"threshold": 100000
|
|
805
|
+
},
|
|
806
|
+
"maxTokens": 128000,
|
|
807
|
+
"name": "Anthropic Haiku 5.5",
|
|
808
|
+
"provider": "amazon-bedrock",
|
|
809
|
+
"reasoning": true,
|
|
810
|
+
"thinking": {
|
|
811
|
+
"defaultLevel": "medium",
|
|
812
|
+
"maxLevel": "max",
|
|
813
|
+
"minLevel": "low",
|
|
814
|
+
"mode": "anthropic-adaptive"
|
|
815
|
+
}
|
|
816
|
+
},
|
|
782
817
|
"anthropic.claude-opus-4-6-v1": {
|
|
783
818
|
"api": "bedrock-converse-stream",
|
|
784
819
|
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
|
@@ -1098,6 +1133,41 @@
|
|
|
1098
1133
|
"mode": "budget"
|
|
1099
1134
|
}
|
|
1100
1135
|
},
|
|
1136
|
+
"au.anthropic.claude-haiku-5-5": {
|
|
1137
|
+
"api": "bedrock-converse-stream",
|
|
1138
|
+
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
|
1139
|
+
"contextWindow": 1000000,
|
|
1140
|
+
"cost": {
|
|
1141
|
+
"cacheRead": 0.011,
|
|
1142
|
+
"cacheWrite": 0.1375,
|
|
1143
|
+
"input": 0.11,
|
|
1144
|
+
"output": 0.55
|
|
1145
|
+
},
|
|
1146
|
+
"id": "au.anthropic.claude-haiku-5-5",
|
|
1147
|
+
"input": [
|
|
1148
|
+
"text",
|
|
1149
|
+
"image"
|
|
1150
|
+
],
|
|
1151
|
+
"longContextPricing": {
|
|
1152
|
+
"cost": {
|
|
1153
|
+
"cacheRead": 0.055,
|
|
1154
|
+
"cacheWrite": 0.6875,
|
|
1155
|
+
"input": 0.55,
|
|
1156
|
+
"output": 2.75
|
|
1157
|
+
},
|
|
1158
|
+
"threshold": 100000
|
|
1159
|
+
},
|
|
1160
|
+
"maxTokens": 128000,
|
|
1161
|
+
"name": "Anthropic Haiku 5.5 (AU)",
|
|
1162
|
+
"provider": "amazon-bedrock",
|
|
1163
|
+
"reasoning": true,
|
|
1164
|
+
"thinking": {
|
|
1165
|
+
"defaultLevel": "medium",
|
|
1166
|
+
"maxLevel": "max",
|
|
1167
|
+
"minLevel": "low",
|
|
1168
|
+
"mode": "anthropic-adaptive"
|
|
1169
|
+
}
|
|
1170
|
+
},
|
|
1101
1171
|
"au.anthropic.claude-opus-4-6-v1": {
|
|
1102
1172
|
"api": "bedrock-converse-stream",
|
|
1103
1173
|
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
|
@@ -1787,6 +1857,41 @@
|
|
|
1787
1857
|
"mode": "budget"
|
|
1788
1858
|
}
|
|
1789
1859
|
},
|
|
1860
|
+
"eu.anthropic.claude-haiku-5-5": {
|
|
1861
|
+
"api": "bedrock-converse-stream",
|
|
1862
|
+
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
|
1863
|
+
"contextWindow": 1000000,
|
|
1864
|
+
"cost": {
|
|
1865
|
+
"cacheRead": 0.011,
|
|
1866
|
+
"cacheWrite": 0.1375,
|
|
1867
|
+
"input": 0.11,
|
|
1868
|
+
"output": 0.55
|
|
1869
|
+
},
|
|
1870
|
+
"id": "eu.anthropic.claude-haiku-5-5",
|
|
1871
|
+
"input": [
|
|
1872
|
+
"text",
|
|
1873
|
+
"image"
|
|
1874
|
+
],
|
|
1875
|
+
"longContextPricing": {
|
|
1876
|
+
"cost": {
|
|
1877
|
+
"cacheRead": 0.055,
|
|
1878
|
+
"cacheWrite": 0.6875,
|
|
1879
|
+
"input": 0.55,
|
|
1880
|
+
"output": 2.75
|
|
1881
|
+
},
|
|
1882
|
+
"threshold": 100000
|
|
1883
|
+
},
|
|
1884
|
+
"maxTokens": 128000,
|
|
1885
|
+
"name": "Anthropic Haiku 5.5 (EU)",
|
|
1886
|
+
"provider": "amazon-bedrock",
|
|
1887
|
+
"reasoning": true,
|
|
1888
|
+
"thinking": {
|
|
1889
|
+
"defaultLevel": "medium",
|
|
1890
|
+
"maxLevel": "max",
|
|
1891
|
+
"minLevel": "low",
|
|
1892
|
+
"mode": "anthropic-adaptive"
|
|
1893
|
+
}
|
|
1894
|
+
},
|
|
1790
1895
|
"eu.anthropic.claude-opus-4-1-20250805-v1:0": {
|
|
1791
1896
|
"api": "bedrock-converse-stream",
|
|
1792
1897
|
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
|
@@ -2267,6 +2372,41 @@
|
|
|
2267
2372
|
"mode": "budget"
|
|
2268
2373
|
}
|
|
2269
2374
|
},
|
|
2375
|
+
"global.anthropic.claude-haiku-5-5": {
|
|
2376
|
+
"api": "bedrock-converse-stream",
|
|
2377
|
+
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
|
2378
|
+
"contextWindow": 1000000,
|
|
2379
|
+
"cost": {
|
|
2380
|
+
"cacheRead": 0.01,
|
|
2381
|
+
"cacheWrite": 0.125,
|
|
2382
|
+
"input": 0.1,
|
|
2383
|
+
"output": 0.5
|
|
2384
|
+
},
|
|
2385
|
+
"id": "global.anthropic.claude-haiku-5-5",
|
|
2386
|
+
"input": [
|
|
2387
|
+
"text",
|
|
2388
|
+
"image"
|
|
2389
|
+
],
|
|
2390
|
+
"longContextPricing": {
|
|
2391
|
+
"cost": {
|
|
2392
|
+
"cacheRead": 0.05,
|
|
2393
|
+
"cacheWrite": 0.625,
|
|
2394
|
+
"input": 0.5,
|
|
2395
|
+
"output": 2.5
|
|
2396
|
+
},
|
|
2397
|
+
"threshold": 100000
|
|
2398
|
+
},
|
|
2399
|
+
"maxTokens": 128000,
|
|
2400
|
+
"name": "Anthropic Haiku 5.5 (Global)",
|
|
2401
|
+
"provider": "amazon-bedrock",
|
|
2402
|
+
"reasoning": true,
|
|
2403
|
+
"thinking": {
|
|
2404
|
+
"defaultLevel": "medium",
|
|
2405
|
+
"maxLevel": "max",
|
|
2406
|
+
"minLevel": "low",
|
|
2407
|
+
"mode": "anthropic-adaptive"
|
|
2408
|
+
}
|
|
2409
|
+
},
|
|
2270
2410
|
"global.anthropic.claude-opus-4-5-20251101-v1:0": {
|
|
2271
2411
|
"api": "bedrock-converse-stream",
|
|
2272
2412
|
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
|
@@ -3124,6 +3264,41 @@
|
|
|
3124
3264
|
"mode": "budget"
|
|
3125
3265
|
}
|
|
3126
3266
|
},
|
|
3267
|
+
"jp.anthropic.claude-haiku-5-5": {
|
|
3268
|
+
"api": "bedrock-converse-stream",
|
|
3269
|
+
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
|
3270
|
+
"contextWindow": 1000000,
|
|
3271
|
+
"cost": {
|
|
3272
|
+
"cacheRead": 0.011,
|
|
3273
|
+
"cacheWrite": 0.1375,
|
|
3274
|
+
"input": 0.11,
|
|
3275
|
+
"output": 0.55
|
|
3276
|
+
},
|
|
3277
|
+
"id": "jp.anthropic.claude-haiku-5-5",
|
|
3278
|
+
"input": [
|
|
3279
|
+
"text",
|
|
3280
|
+
"image"
|
|
3281
|
+
],
|
|
3282
|
+
"longContextPricing": {
|
|
3283
|
+
"cost": {
|
|
3284
|
+
"cacheRead": 0.055,
|
|
3285
|
+
"cacheWrite": 0.6875,
|
|
3286
|
+
"input": 0.55,
|
|
3287
|
+
"output": 2.75
|
|
3288
|
+
},
|
|
3289
|
+
"threshold": 100000
|
|
3290
|
+
},
|
|
3291
|
+
"maxTokens": 128000,
|
|
3292
|
+
"name": "Anthropic Haiku 5.5 (JP)",
|
|
3293
|
+
"provider": "amazon-bedrock",
|
|
3294
|
+
"reasoning": true,
|
|
3295
|
+
"thinking": {
|
|
3296
|
+
"defaultLevel": "medium",
|
|
3297
|
+
"maxLevel": "max",
|
|
3298
|
+
"minLevel": "low",
|
|
3299
|
+
"mode": "anthropic-adaptive"
|
|
3300
|
+
}
|
|
3301
|
+
},
|
|
3127
3302
|
"jp.anthropic.claude-opus-4-7": {
|
|
3128
3303
|
"api": "bedrock-converse-stream",
|
|
3129
3304
|
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
|
@@ -4573,6 +4748,41 @@
|
|
|
4573
4748
|
"mode": "budget"
|
|
4574
4749
|
}
|
|
4575
4750
|
},
|
|
4751
|
+
"us.anthropic.claude-haiku-5-5": {
|
|
4752
|
+
"api": "bedrock-converse-stream",
|
|
4753
|
+
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
|
4754
|
+
"contextWindow": 1000000,
|
|
4755
|
+
"cost": {
|
|
4756
|
+
"cacheRead": 0.011,
|
|
4757
|
+
"cacheWrite": 0.1375,
|
|
4758
|
+
"input": 0.11,
|
|
4759
|
+
"output": 0.55
|
|
4760
|
+
},
|
|
4761
|
+
"id": "us.anthropic.claude-haiku-5-5",
|
|
4762
|
+
"input": [
|
|
4763
|
+
"text",
|
|
4764
|
+
"image"
|
|
4765
|
+
],
|
|
4766
|
+
"longContextPricing": {
|
|
4767
|
+
"cost": {
|
|
4768
|
+
"cacheRead": 0.055,
|
|
4769
|
+
"cacheWrite": 0.6875,
|
|
4770
|
+
"input": 0.55,
|
|
4771
|
+
"output": 2.75
|
|
4772
|
+
},
|
|
4773
|
+
"threshold": 100000
|
|
4774
|
+
},
|
|
4775
|
+
"maxTokens": 128000,
|
|
4776
|
+
"name": "Anthropic Haiku 5.5 (US)",
|
|
4777
|
+
"provider": "amazon-bedrock",
|
|
4778
|
+
"reasoning": true,
|
|
4779
|
+
"thinking": {
|
|
4780
|
+
"defaultLevel": "medium",
|
|
4781
|
+
"maxLevel": "max",
|
|
4782
|
+
"minLevel": "low",
|
|
4783
|
+
"mode": "anthropic-adaptive"
|
|
4784
|
+
}
|
|
4785
|
+
},
|
|
4576
4786
|
"us.anthropic.claude-opus-4-1-20250805-v1:0": {
|
|
4577
4787
|
"api": "bedrock-converse-stream",
|
|
4578
4788
|
"baseUrl": "https://bedrock-runtime.us-east-1.amazonaws.com",
|
|
@@ -5782,6 +5992,41 @@
|
|
|
5782
5992
|
"mode": "budget"
|
|
5783
5993
|
}
|
|
5784
5994
|
},
|
|
5995
|
+
"claude-haiku-5-5": {
|
|
5996
|
+
"api": "anthropic-messages",
|
|
5997
|
+
"baseUrl": "https://api.anthropic.com",
|
|
5998
|
+
"contextWindow": 1000000,
|
|
5999
|
+
"cost": {
|
|
6000
|
+
"cacheRead": 0.01,
|
|
6001
|
+
"cacheWrite": 0.125,
|
|
6002
|
+
"input": 0.1,
|
|
6003
|
+
"output": 0.5
|
|
6004
|
+
},
|
|
6005
|
+
"id": "claude-haiku-5-5",
|
|
6006
|
+
"input": [
|
|
6007
|
+
"text",
|
|
6008
|
+
"image"
|
|
6009
|
+
],
|
|
6010
|
+
"longContextPricing": {
|
|
6011
|
+
"cost": {
|
|
6012
|
+
"cacheRead": 0.05,
|
|
6013
|
+
"cacheWrite": 0.625,
|
|
6014
|
+
"input": 0.5,
|
|
6015
|
+
"output": 2.5
|
|
6016
|
+
},
|
|
6017
|
+
"threshold": 100000
|
|
6018
|
+
},
|
|
6019
|
+
"maxTokens": 128000,
|
|
6020
|
+
"name": "Anthropic Haiku 5.5",
|
|
6021
|
+
"provider": "anthropic",
|
|
6022
|
+
"reasoning": true,
|
|
6023
|
+
"thinking": {
|
|
6024
|
+
"defaultLevel": "medium",
|
|
6025
|
+
"maxLevel": "max",
|
|
6026
|
+
"minLevel": "low",
|
|
6027
|
+
"mode": "anthropic-adaptive"
|
|
6028
|
+
}
|
|
6029
|
+
},
|
|
5785
6030
|
"claude-opus-4-0": {
|
|
5786
6031
|
"api": "anthropic-messages",
|
|
5787
6032
|
"baseUrl": "https://api.anthropic.com",
|
package/src/models.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { registerProviderSafetyStopModel } from "./adapter-internals/provider-safety-stop";
|
|
3
|
-
import { getOpenAIModelCost } from "./model-pricing";
|
|
3
|
+
import { getAnthropicCacheWriteOneHourRate, getAnthropicModelCost, getOpenAIModelCost } from "./model-pricing";
|
|
4
4
|
import { isRetiredModelKey } from "./model-retirements";
|
|
5
5
|
import { applyGeneratedModelPolicies, enrichModelThinking } from "./model-thinking";
|
|
6
6
|
// `with { type: "file" }` is embedded by `bun build --compile` and resolves to
|
|
@@ -105,11 +105,18 @@ export function getBundledModels(provider: GeneratedProvider): Model<Api>[] {
|
|
|
105
105
|
|
|
106
106
|
export function calculateCost<TApi extends Api>(model: Model<TApi>, usage: Usage): Usage["cost"] {
|
|
107
107
|
const inputTokens = usage.input + usage.cacheRead + usage.cacheWrite;
|
|
108
|
-
const pricing = getOpenAIModelCost(model, inputTokens) ?? model.cost;
|
|
108
|
+
const pricing = getAnthropicModelCost(model, inputTokens) ?? getOpenAIModelCost(model, inputTokens) ?? model.cost;
|
|
109
109
|
usage.cost.input = (pricing.input / 1000000) * usage.input;
|
|
110
110
|
usage.cost.output = (pricing.output / 1000000) * usage.output;
|
|
111
111
|
usage.cost.cacheRead = (pricing.cacheRead / 1000000) * usage.cacheRead;
|
|
112
|
-
|
|
112
|
+
const oneHourRate = getAnthropicCacheWriteOneHourRate(model, inputTokens);
|
|
113
|
+
// Bill the response's 1-hour cache-write tokens at the 1-hour rate; everything else
|
|
114
|
+
// (5-minute writes and any unattributed remainder) uses the model's cacheWrite rate.
|
|
115
|
+
const oneHourTokens =
|
|
116
|
+
oneHourRate === undefined ? 0 : Math.min(Math.max(usage.cttl?.ephemeral1h ?? 0, 0), usage.cacheWrite);
|
|
117
|
+
usage.cost.cacheWrite =
|
|
118
|
+
(pricing.cacheWrite / 1000000) * (usage.cacheWrite - oneHourTokens) +
|
|
119
|
+
((oneHourRate ?? 0) / 1000000) * oneHourTokens;
|
|
113
120
|
usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
|
|
114
121
|
return usage.cost;
|
|
115
122
|
}
|
|
@@ -14,11 +14,13 @@ export interface GoogleVertexModelManagerConfig {
|
|
|
14
14
|
export interface GoogleAntigravityModelManagerConfig {
|
|
15
15
|
oauthToken?: string;
|
|
16
16
|
endpoint?: string;
|
|
17
|
+
project?: string;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export interface GoogleGeminiCliModelManagerConfig {
|
|
20
21
|
oauthToken?: string;
|
|
21
22
|
endpoint?: string;
|
|
23
|
+
project?: string;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
const CLOUD_CODE_ASSIST_ENDPOINT = "https://cloudcode-pa.googleapis.com";
|
|
@@ -58,6 +60,7 @@ export function googleAntigravityModelManagerOptions(
|
|
|
58
60
|
fetchAntigravityDiscoveryModels({
|
|
59
61
|
token,
|
|
60
62
|
endpoint: config?.endpoint,
|
|
63
|
+
project: config?.project,
|
|
61
64
|
userAgent: ua,
|
|
62
65
|
}),
|
|
63
66
|
}
|
|
@@ -80,6 +83,7 @@ export function googleGeminiCliModelManagerOptions(
|
|
|
80
83
|
const models = await fetchAntigravityDiscoveryModels({
|
|
81
84
|
token,
|
|
82
85
|
endpoint,
|
|
86
|
+
project: config?.project,
|
|
83
87
|
targetProvider: "google-gemini-cli",
|
|
84
88
|
userAgent: ua,
|
|
85
89
|
});
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { parseBedrockClaudeGeneration } from "../bedrock-claude-cache-policy";
|
|
10
10
|
import type { Effort } from "../model-thinking";
|
|
11
|
-
import type { Model, StreamFunction, StreamOptions, ThinkingBudgets, Tool, ToolChoice } from "../types";
|
|
11
|
+
import type { AssistantMessage, CacheRetention, Model, StreamFunction, StreamOptions, ThinkingBudgets, Tool, ToolChoice } from "../types";
|
|
12
12
|
export type BedrockThinkingDisplay = "summarized" | "omitted";
|
|
13
13
|
export interface BedrockOptions extends StreamOptions {
|
|
14
14
|
region?: string;
|
|
@@ -51,7 +51,18 @@ interface WireToolConfig {
|
|
|
51
51
|
tools: WireToolSpec[];
|
|
52
52
|
toolChoice?: WireToolChoice;
|
|
53
53
|
}
|
|
54
|
+
interface MetadataEvent {
|
|
55
|
+
usage?: {
|
|
56
|
+
inputTokens?: number;
|
|
57
|
+
outputTokens?: number;
|
|
58
|
+
cacheReadInputTokens?: number;
|
|
59
|
+
cacheWriteInputTokens?: number;
|
|
60
|
+
totalTokens?: number;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
54
63
|
export declare const streamBedrock: StreamFunction<"bedrock-converse-stream">;
|
|
64
|
+
/** Exported for unit tests of the usage-to-cost path. */
|
|
65
|
+
export declare function handleMetadata(event: MetadataEvent, model: Model<"bedrock-converse-stream">, output: AssistantMessage, cacheRetention: CacheRetention): void;
|
|
55
66
|
/**
|
|
56
67
|
* Check if the model supports prompt caching.
|
|
57
68
|
* Supported: Claude 3.5 Haiku, Claude 3.7 Sonnet, and every later Claude
|
|
@@ -71,5 +82,9 @@ export declare function stripBedrockForcedToolChoiceForRetry<T extends {
|
|
|
71
82
|
toolConfig?: {
|
|
72
83
|
toolChoice?: unknown;
|
|
73
84
|
};
|
|
74
|
-
|
|
85
|
+
additionalModelRequestFields?: Record<string, unknown>;
|
|
86
|
+
}>(body: T, thinking?: {
|
|
87
|
+
forced: Record<string, unknown> | undefined;
|
|
88
|
+
restored: Record<string, unknown>;
|
|
89
|
+
}): T;
|
|
75
90
|
export declare function convertToolConfig(tools: Tool[] | undefined, toolChoice: BedrockOptions["toolChoice"]): WireToolConfig | undefined;
|
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
import { $credentialEnv, $env, $flag, extractHttpStatusFromError, fetchWithRetry } from "@gajae-code/utils";
|
|
11
11
|
import { assertAwsRegionLabel } from "../adapter-internals/aws-region";
|
|
12
12
|
import { parseBedrockClaudeGeneration, supportsBedrockClaudePromptCaching } from "../bedrock-claude-cache-policy";
|
|
13
|
+
import { getAnthropicCacheWriteOneHourRate } from "../model-pricing";
|
|
13
14
|
import type { Effort } from "../model-thinking";
|
|
14
15
|
import {
|
|
15
16
|
mapEffortToAnthropicAdaptiveEffort,
|
|
16
17
|
requireSupportedEffort,
|
|
18
|
+
requiresAnthropicThinkingDisableWhenOff,
|
|
17
19
|
supportsAnthropicAdaptiveThinkingDisplay as supportsAdaptiveThinkingDisplay,
|
|
18
20
|
} from "../model-thinking";
|
|
19
21
|
import { calculateCost } from "../models";
|
|
@@ -213,12 +215,30 @@ export const streamBedrock: StreamFunction<"bedrock-converse-stream"> = (
|
|
|
213
215
|
const resolvedToolChoice = resolveToolChoice(model, options.toolChoice);
|
|
214
216
|
const toolConfig = convertToolConfig(context.tools, resolvedToolChoice.resolvedChoice);
|
|
215
217
|
let additionalModelRequestFields = buildAdditionalModelRequestFields(model, options);
|
|
218
|
+
// Selected reasoning fields before forced-tool normalization, restored if the forced
|
|
219
|
+
// tool choice is later dropped on retry (Haiku 5+ only; see below).
|
|
220
|
+
let unforcedModelRequestFields: Record<string, unknown> | undefined;
|
|
216
221
|
|
|
217
222
|
// Bedrock rejects thinking + forced tool_choice ("any" or specific tool).
|
|
218
223
|
// When the resolved tool_choice forces tool use, disable thinking to avoid API errors.
|
|
219
224
|
if (toolConfig?.toolChoice && additionalModelRequestFields) {
|
|
220
225
|
const tc = toolConfig.toolChoice;
|
|
221
|
-
if (tc.any || tc.tool)
|
|
226
|
+
if ((tc.any || tc.tool) && requiresAnthropicThinkingDisableWhenOff(model.id)) {
|
|
227
|
+
// Haiku 5+ enables adaptive thinking when the field is omitted, which a forced
|
|
228
|
+
// tool choice rejects, and applies the effort to tool-call arguments too: send an
|
|
229
|
+
// explicit `disabled` and keep the selected effort (capped at `high` while
|
|
230
|
+
// thinking is disabled).
|
|
231
|
+
const effort = (additionalModelRequestFields.output_config as { effort?: string } | undefined)?.effort;
|
|
232
|
+
unforcedModelRequestFields = additionalModelRequestFields;
|
|
233
|
+
additionalModelRequestFields = {
|
|
234
|
+
thinking: { type: "disabled" },
|
|
235
|
+
...(effort
|
|
236
|
+
? { output_config: { effort: effort === "xhigh" || effort === "max" ? "high" : effort } }
|
|
237
|
+
: {}),
|
|
238
|
+
};
|
|
239
|
+
} else if (tc.any || tc.tool) {
|
|
240
|
+
additionalModelRequestFields = undefined;
|
|
241
|
+
}
|
|
222
242
|
}
|
|
223
243
|
|
|
224
244
|
let commandInput: ConverseStreamRequest = {
|
|
@@ -307,7 +327,12 @@ export const streamBedrock: StreamFunction<"bedrock-converse-stream"> = (
|
|
|
307
327
|
reason,
|
|
308
328
|
registryKey: resolvedToolChoice.registryKey,
|
|
309
329
|
});
|
|
310
|
-
stripBedrockForcedToolChoiceForRetry(
|
|
330
|
+
stripBedrockForcedToolChoiceForRetry(
|
|
331
|
+
commandInput,
|
|
332
|
+
unforcedModelRequestFields
|
|
333
|
+
? { forced: additionalModelRequestFields, restored: unforcedModelRequestFields }
|
|
334
|
+
: undefined,
|
|
335
|
+
);
|
|
311
336
|
const retryBodyText = JSON.stringify(commandInput);
|
|
312
337
|
const retryBody = new TextEncoder().encode(retryBodyText);
|
|
313
338
|
if (rawRequestDump) rawRequestDump.body = commandInput;
|
|
@@ -429,7 +454,7 @@ export const streamBedrock: StreamFunction<"bedrock-converse-stream"> = (
|
|
|
429
454
|
break;
|
|
430
455
|
}
|
|
431
456
|
case "metadata": {
|
|
432
|
-
handleMetadata(payload as MetadataEvent, model, output);
|
|
457
|
+
handleMetadata(payload as MetadataEvent, model, output, cacheRetention);
|
|
433
458
|
break;
|
|
434
459
|
}
|
|
435
460
|
default:
|
|
@@ -580,13 +605,28 @@ function handleContentBlockDelta(
|
|
|
580
605
|
}
|
|
581
606
|
}
|
|
582
607
|
|
|
583
|
-
|
|
608
|
+
/** Exported for unit tests of the usage-to-cost path. */
|
|
609
|
+
export function handleMetadata(
|
|
610
|
+
event: MetadataEvent,
|
|
611
|
+
model: Model<"bedrock-converse-stream">,
|
|
612
|
+
output: AssistantMessage,
|
|
613
|
+
cacheRetention: CacheRetention,
|
|
614
|
+
): void {
|
|
584
615
|
if (event.usage) {
|
|
585
616
|
output.usage.input = event.usage.inputTokens || 0;
|
|
586
617
|
output.usage.output = event.usage.outputTokens || 0;
|
|
587
618
|
output.usage.cacheRead = event.usage.cacheReadInputTokens || 0;
|
|
588
619
|
output.usage.cacheWrite = event.usage.cacheWriteInputTokens || 0;
|
|
589
620
|
output.usage.totalTokens = event.usage.totalTokens || output.usage.input + output.usage.output;
|
|
621
|
+
// Converse reports aggregate cache writes only. Where 1-hour writes have their own rate
|
|
622
|
+
// (Haiku 5.5), the request's `ttl: "1h"` cache points mean every write was 1-hour.
|
|
623
|
+
if (
|
|
624
|
+
cacheRetention === "long" &&
|
|
625
|
+
output.usage.cacheWrite > 0 &&
|
|
626
|
+
getAnthropicCacheWriteOneHourRate(model, 0) !== undefined
|
|
627
|
+
) {
|
|
628
|
+
output.usage.cttl = { ephemeral1h: output.usage.cacheWrite };
|
|
629
|
+
}
|
|
590
630
|
calculateCost(model, output.usage);
|
|
591
631
|
}
|
|
592
632
|
}
|
|
@@ -829,10 +869,18 @@ function convertMessages(
|
|
|
829
869
|
return result;
|
|
830
870
|
}
|
|
831
871
|
|
|
832
|
-
export function stripBedrockForcedToolChoiceForRetry<
|
|
872
|
+
export function stripBedrockForcedToolChoiceForRetry<
|
|
873
|
+
T extends { toolConfig?: { toolChoice?: unknown }; additionalModelRequestFields?: Record<string, unknown> },
|
|
874
|
+
>(body: T, thinking?: { forced: Record<string, unknown> | undefined; restored: Record<string, unknown> }): T {
|
|
833
875
|
if (body.toolConfig) {
|
|
834
876
|
body.toolConfig = { ...body.toolConfig, toolChoice: undefined };
|
|
835
877
|
}
|
|
878
|
+
// The forced request replaced the selected thinking fields with a disabled block; with the
|
|
879
|
+
// forced constraint gone, put the selected reasoning back. A payload the caller replaced via
|
|
880
|
+
// onPayload (not the object this provider sent) is left untouched.
|
|
881
|
+
if (thinking && body.additionalModelRequestFields === thinking.forced) {
|
|
882
|
+
body.additionalModelRequestFields = thinking.restored;
|
|
883
|
+
}
|
|
836
884
|
return body;
|
|
837
885
|
}
|
|
838
886
|
|
|
@@ -888,6 +936,9 @@ function buildAdditionalModelRequestFields(
|
|
|
888
936
|
options: BedrockOptions,
|
|
889
937
|
): Record<string, unknown> | undefined {
|
|
890
938
|
const reasoning = options.reasoning;
|
|
939
|
+
if (requiresAnthropicThinkingDisableWhenOff(model.id) && (!reasoning || !model.reasoning)) {
|
|
940
|
+
return { thinking: { type: "disabled" } };
|
|
941
|
+
}
|
|
891
942
|
if (!reasoning || !model.reasoning) return undefined;
|
|
892
943
|
|
|
893
944
|
const mode = model.thinking?.mode;
|