@oh-my-pi/pi-ai 14.1.2 → 14.2.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.
- package/CHANGELOG.md +57 -2
- package/package.json +5 -3
- package/src/auth-storage.ts +18 -6
- package/src/model-thinking.ts +48 -2
- package/src/models.json +2608 -388
- package/src/provider-models/openai-compat.ts +97 -224
- package/src/providers/amazon-bedrock.ts +103 -34
- package/src/providers/anthropic.ts +44 -22
- package/src/providers/azure-openai-responses.ts +4 -4
- package/src/providers/cursor.ts +18 -12
- package/src/providers/gitlab-duo.ts +2 -21
- package/src/providers/kimi.ts +2 -22
- package/src/providers/openai-codex-responses.ts +194 -23
- package/src/providers/openai-completions.ts +22 -13
- package/src/providers/openai-responses-shared.ts +143 -18
- package/src/providers/openai-responses.ts +91 -15
- package/src/providers/shared/error-message.ts +21 -0
- package/src/providers/synthetic.ts +2 -22
- package/src/stream.ts +1 -7
- package/src/types.ts +34 -0
- package/src/usage/kimi.ts +1 -11
- package/src/usage/openai-codex.ts +1 -11
- package/src/usage/shared.ts +10 -0
- package/src/utils/anthropic-auth.ts +1 -7
- package/src/utils/foundry.ts +8 -0
- package/src/utils/http-inspector.ts +9 -2
- package/src/utils/idle-iterator.ts +29 -54
- package/src/utils/oauth/api-key-login.ts +87 -0
- package/src/utils/oauth/cerebras.ts +15 -58
- package/src/utils/oauth/google-antigravity.ts +11 -86
- package/src/utils/oauth/google-gemini-cli.ts +11 -89
- package/src/utils/oauth/google-oauth-shared.ts +110 -0
- package/src/utils/oauth/moonshot.ts +15 -58
- package/src/utils/oauth/nanogpt.ts +14 -50
- package/src/utils/oauth/openai-codex.ts +3 -3
- package/src/utils/oauth/synthetic.ts +15 -59
- package/src/utils/oauth/together.ts +15 -58
- package/src/utils/oauth/zenmux.ts +14 -50
- package/src/utils/retry.ts +77 -0
- package/src/utils/schema/CONSTRAINTS.md +1 -0
- package/src/utils/schema/strict-mode.ts +10 -0
- package/src/utils/tool-choice.ts +7 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [14.2.1] - 2026-04-24
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Fixed OpenAI Codex Spark OAuth selection to require a verified ChatGPT Pro account instead of falling back to Plus or unknown-plan accounts.
|
|
10
|
+
|
|
11
|
+
## [14.2.0] - 2026-04-23
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Added `gpt-5.5` to the built-in model catalog for both OpenAI Responses (`openai`) and local `litellm` (`openai-completions`) providers
|
|
16
|
+
- Added `gpt-image-2` to the `litellm` built-in model catalog
|
|
17
|
+
- Added `isCopilotTransientModelError()` and `callWithCopilotModelRetry()` helpers in `utils/retry` that detect GitHub Copilot's intermittent `HTTP 400 model_not_supported` responses for preview models (`gpt-5.3-codex`, `gpt-5.4`, `gpt-5.4-mini`, ...) and retry the request up to three times with backoff. OpenAI Responses, OpenAI Completions, and Anthropic provider paths now participate in this retry when the model is served through Copilot.
|
|
18
|
+
- Added OpenAI Responses custom-tool grammar support for Codex-style `apply_patch` calls, including freeform streaming, history replay, and forced tool-choice mapping to the custom wire name.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Updated built-in model metadata with revised `contextWindow`, `maxTokens`, and pricing values for existing entries
|
|
23
|
+
- Changed generated model policies to assign `applyPatchToolType: "freeform"` for first-party GPT-5 OpenAI Responses and Codex models, so regenerated `models.json` preserves the `apply_patch` custom-tool metadata.
|
|
24
|
+
- Renamed `rewriteCopilotAuthError` to `rewriteCopilotError` and extended it to rewrite `HTTP 400 model_not_supported` after retries are exhausted with guidance about Copilot's OAuth-client-specific rollout gap (see opencode#13313).
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- Fixed Amazon Bedrock proxy handling to honor lowercase `http_proxy`, `https_proxy`, and `all_proxy` environment variables when using HTTP/1 fallback
|
|
29
|
+
- Fixed Amazon Bedrock streaming behind corporate HTTP proxies by using a proxy-aware HTTP/1 transport when `HTTPS_PROXY`, `HTTP_PROXY`, or `ALL_PROXY` is configured, including AWS SSO credential calls.
|
|
30
|
+
- Fixed Amazon Bedrock requests to retry once with HTTP/1 when the AWS SDK's default HTTP/2 transport fails before streaming begins.
|
|
31
|
+
- Fixed OpenAI Responses streaming to display thinking tokens from local providers (llama.cpp, etc.) that send raw `reasoning_text.delta` events and empty `summary` arrays in `output_item.done`. Previously, thinking content was silently dropped during streaming while non-streaming mode worked correctly.
|
|
32
|
+
- Synced the bundled OpenCode Go catalog with the current docs so `kimi-k2.6`, `mimo-v2.5`, and `mimo-v2.5-pro` appear in offline/default model lists.
|
|
33
|
+
|
|
34
|
+
## [14.1.3] - 2026-04-17
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- Preserved user-provided `session_id` and `x-client-request-id` headers in OpenAI Responses requests instead of overriding them with automatic session-derived values
|
|
39
|
+
- Stopped sending `session_id` and `x-client-request-id` headers for OpenAI Responses requests when `cacheRetention` is set to `none`
|
|
40
|
+
- Fixed direct OpenAI Responses requests to send `session_id` and `x-client-request-id` from the same session-derived value as `prompt_cache_key`, improving prompt cache affinity for append-only sessions
|
|
5
41
|
## [14.1.1] - 2026-04-14
|
|
6
42
|
|
|
7
43
|
### Added
|
|
@@ -21,6 +57,7 @@
|
|
|
21
57
|
- Fixed strict tool schema enforcement to preserve `additionalProperties: false` and required keys for reused nested object schemas, preventing invalid `todo_write` function schemas in Codex/OpenAI requests
|
|
22
58
|
|
|
23
59
|
## [14.1.0] - 2026-04-11
|
|
60
|
+
|
|
24
61
|
### Added
|
|
25
62
|
|
|
26
63
|
- Added `accountId` to usage report metadata
|
|
@@ -37,6 +74,7 @@
|
|
|
37
74
|
## [14.0.5] - 2026-04-11
|
|
38
75
|
|
|
39
76
|
### Changed
|
|
77
|
+
|
|
40
78
|
- Replaced GitHub Copilot authentication from VSCode extension impersonation to the opencode OAuth flow, eliminating TOS concerns. Existing users will need to re-authenticate once with `/login github-copilot`.
|
|
41
79
|
- Simplified Copilot token handling: GitHub OAuth token is used directly for all API requests (no JWT exchange or refresh cycle).
|
|
42
80
|
- Changed GitHub Copilot API base URL from `api.individual.githubcopilot.com` to `api.githubcopilot.com`.
|
|
@@ -48,6 +86,7 @@
|
|
|
48
86
|
- Fixed GitHub Copilot `/models` discovery to unwrap structured OAuth credentials before sending the bearer token, preserving dynamic catalog refresh for OAuth-backed callers.
|
|
49
87
|
|
|
50
88
|
### Removed
|
|
89
|
+
|
|
51
90
|
- Removed Copilot JWT proxy-ep base URL resolution (no longer needed with opencode auth).
|
|
52
91
|
|
|
53
92
|
## [14.0.3] - 2026-04-09
|
|
@@ -57,6 +96,7 @@
|
|
|
57
96
|
- Fixed Ollama discovery cache normalization so cached models upgrade to the OpenAI Responses transport after the provider change
|
|
58
97
|
|
|
59
98
|
## [14.0.0] - 2026-04-08
|
|
99
|
+
|
|
60
100
|
### Breaking Changes
|
|
61
101
|
|
|
62
102
|
- Removed `coerceNullStrings` function and its automatic null-string coercion behavior from JSON parsing
|
|
@@ -79,6 +119,7 @@
|
|
|
79
119
|
- Fixed Anthropic streaming to suppress transient SDK console errors for malformed SSE keep-alive frames so the TUI only shows surfaced provider errors
|
|
80
120
|
|
|
81
121
|
- Added environment-based credential fallback for the OpenAI Codex provider.
|
|
122
|
+
|
|
82
123
|
## [13.17.6] - 2026-04-01
|
|
83
124
|
|
|
84
125
|
### Fixed
|
|
@@ -86,6 +127,7 @@
|
|
|
86
127
|
- Fixed Anthropic first-event timeouts to exclude stream connection setup from the watchdog, preserve timeout-specific retry classification after local aborts, and reset retry state cleanly between attempts
|
|
87
128
|
|
|
88
129
|
## [13.17.5] - 2026-04-01
|
|
130
|
+
|
|
89
131
|
### Changed
|
|
90
132
|
|
|
91
133
|
- Increased default first-event timeout from 15s to 45s to better accommodate longer request setup times
|
|
@@ -124,6 +166,7 @@
|
|
|
124
166
|
- Added Vercel AI Gateway to `/login` providers for interactive API key setup
|
|
125
167
|
|
|
126
168
|
### Fixed
|
|
169
|
+
|
|
127
170
|
- Fixed `omp commit` failing with HTTP 400 errors when using reasoning-enabled models on OpenAI-compatible endpoints that don't support the `developer` role (e.g., GitHub Copilot, custom proxies). Now falls back to `system` role when `developer` is unsupported.
|
|
128
171
|
|
|
129
172
|
## [13.17.0] - 2026-03-30
|
|
@@ -148,6 +191,7 @@
|
|
|
148
191
|
- Fixed normalizeAnthropicBaseUrl returning empty string instead of undefined when baseUrl is empty
|
|
149
192
|
|
|
150
193
|
## [13.16.4] - 2026-03-28
|
|
194
|
+
|
|
151
195
|
### Added
|
|
152
196
|
|
|
153
197
|
- Added support for Groq Compound and Compound Mini models with extended context window (131K tokens) and configurable thinking levels
|
|
@@ -168,6 +212,7 @@
|
|
|
168
212
|
- Updated OpenRouter Claude 3.5 Sonnet pricing: input from 0.45 to 0.42, cache read from 0.225 to 0.21
|
|
169
213
|
|
|
170
214
|
## [13.16.3] - 2026-03-28
|
|
215
|
+
|
|
171
216
|
### Changed
|
|
172
217
|
|
|
173
218
|
- Modified OAuth credential saving to preserve unrelated identities instead of replacing all credentials for a provider
|
|
@@ -193,6 +238,7 @@
|
|
|
193
238
|
- Fixed `parseRateLimitReason` not recognizing "usage limit" in Codex error messages, causing incorrect fallback to `UNKNOWN` classification instead of `QUOTA_EXHAUSTED`
|
|
194
239
|
|
|
195
240
|
## [13.14.2] - 2026-03-21
|
|
241
|
+
|
|
196
242
|
### Changed
|
|
197
243
|
|
|
198
244
|
- Updated thinking configuration format from `levels` array to `minLevel` and `maxLevel` properties for improved clarity
|
|
@@ -215,13 +261,14 @@
|
|
|
215
261
|
- Added bundled GPT-5.4 mini model metadata for OpenAI, OpenAI Codex, and GitHub Copilot, including low-to-xhigh thinking support and GitHub Copilot premium multiplier metadata
|
|
216
262
|
- Added bundled GPT-5.4 nano model metadata for OpenAI and OpenAI Codex, including low-to-xhigh thinking support
|
|
217
263
|
|
|
218
|
-
|
|
219
264
|
## [13.13.2] - 2026-03-18
|
|
265
|
+
|
|
220
266
|
### Changed
|
|
221
267
|
|
|
222
268
|
- Modified tool result handling for aborted assistant messages to preserve existing tool results when already recorded, instead of always replacing them with synthetic 'aborted' results
|
|
223
269
|
|
|
224
270
|
## [13.13.0] - 2026-03-18
|
|
271
|
+
|
|
225
272
|
### Changed
|
|
226
273
|
|
|
227
274
|
- Changed tool argument validation to always normalize optional null values before type coercion, ensuring consistent handling of LLM-generated 'null' strings
|
|
@@ -232,6 +279,7 @@
|
|
|
232
279
|
- Improved type safety of `validateToolCall` and `validateToolArguments` functions by returning properly typed `ToolCall["arguments"]` instead of `any`
|
|
233
280
|
|
|
234
281
|
## [13.12.9] - 2026-03-17
|
|
282
|
+
|
|
235
283
|
### Changed
|
|
236
284
|
|
|
237
285
|
- Extracted OpenAI compatibility detection and resolution logic into dedicated `openai-completions-compat` module for improved maintainability and reusability
|
|
@@ -281,6 +329,7 @@
|
|
|
281
329
|
- Fixed auth schema V0-to-V1 migration crash when the V0 table lacks a `disabled` column
|
|
282
330
|
|
|
283
331
|
## [13.11.0] - 2026-03-12
|
|
332
|
+
|
|
284
333
|
### Added
|
|
285
334
|
|
|
286
335
|
- Added support for Parallel AI provider with API key authentication
|
|
@@ -296,6 +345,7 @@
|
|
|
296
345
|
- Improved retry logic to handle HTTP/2 stream errors and internal_error responses from Anthropic API
|
|
297
346
|
|
|
298
347
|
## [13.9.16] - 2026-03-10
|
|
348
|
+
|
|
299
349
|
### Added
|
|
300
350
|
|
|
301
351
|
- Support for `onPayload` callback to replace provider request payloads before sending, enabling request interception and modification
|
|
@@ -318,11 +368,13 @@
|
|
|
318
368
|
- Fixed handling of malformed JSON messages in websocket streams to trigger immediate fallback to SSE without retry attempts
|
|
319
369
|
|
|
320
370
|
## [13.9.13] - 2026-03-10
|
|
371
|
+
|
|
321
372
|
### Added
|
|
322
373
|
|
|
323
374
|
- Added `isSpecialServiceTier` utility function to validate OpenAI service tier values
|
|
324
375
|
|
|
325
376
|
## [13.9.12] - 2026-03-09
|
|
377
|
+
|
|
326
378
|
### Added
|
|
327
379
|
|
|
328
380
|
- Added Tavily web search provider support with API key authentication
|
|
@@ -355,11 +407,13 @@
|
|
|
355
407
|
- Fixed auth storage to preserve newer recorded schema versions when opened by older binaries
|
|
356
408
|
|
|
357
409
|
## [13.9.8] - 2026-03-08
|
|
410
|
+
|
|
358
411
|
### Fixed
|
|
359
412
|
|
|
360
413
|
- Fixed WebSocket stream fallback logic to safely replay buffered output over SSE when WebSocket fails after partial content has been streamed
|
|
361
414
|
|
|
362
415
|
## [13.9.4] - 2026-03-07
|
|
416
|
+
|
|
363
417
|
### Changed
|
|
364
418
|
|
|
365
419
|
- Simplified API key credential storage to always replace existing credentials on re-login instead of accumulating multiple keys
|
|
@@ -372,6 +426,7 @@
|
|
|
372
426
|
- Fixed Cerebras model compatibility by preventing `stream_options` usage requests in chat completions
|
|
373
427
|
|
|
374
428
|
## [13.9.3] - 2026-03-07
|
|
429
|
+
|
|
375
430
|
### Breaking Changes
|
|
376
431
|
|
|
377
432
|
- Changed `reasoning` parameter from `ThinkingLevel | undefined` to `Effort | undefined` in `SimpleStreamOptions`; 'off' is no longer valid (omit the field instead)
|
|
@@ -2042,4 +2097,4 @@ _Dedicated to Peter's shoulder ([@steipete](https://twitter.com/steipete))_
|
|
|
2042
2097
|
|
|
2043
2098
|
## [0.9.4] - 2025-11-26
|
|
2044
2099
|
|
|
2045
|
-
Initial release with multi-provider LLM support.
|
|
2100
|
+
Initial release with multi-provider LLM support.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-ai",
|
|
4
|
-
"version": "14.1
|
|
4
|
+
"version": "14.2.1",
|
|
5
5
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
6
6
|
"homepage": "https://github.com/can1357/oh-my-pi",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -43,16 +43,18 @@
|
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@anthropic-ai/sdk": "^0.78",
|
|
45
45
|
"@aws-sdk/client-bedrock-runtime": "^3",
|
|
46
|
+
"@aws-sdk/credential-provider-node": "^3",
|
|
46
47
|
"@bufbuild/protobuf": "^2.11",
|
|
47
48
|
"@google/genai": "^1.43",
|
|
48
|
-
"@oh-my-pi/pi-natives": "14.1
|
|
49
|
-
"@oh-my-pi/pi-utils": "14.1
|
|
49
|
+
"@oh-my-pi/pi-natives": "14.2.1",
|
|
50
|
+
"@oh-my-pi/pi-utils": "14.2.1",
|
|
50
51
|
"@sinclair/typebox": "^0.34",
|
|
51
52
|
"@smithy/node-http-handler": "^4.4",
|
|
52
53
|
"ajv": "^8.18",
|
|
53
54
|
"ajv-formats": "^3.0",
|
|
54
55
|
"openai": "^6.25",
|
|
55
56
|
"partial-json": "^0.1",
|
|
57
|
+
"proxy-agent": "^6.5",
|
|
56
58
|
"zod": "4.3.6"
|
|
57
59
|
},
|
|
58
60
|
"devDependencies": {
|
package/src/auth-storage.ts
CHANGED
|
@@ -208,6 +208,10 @@ function getOpenAICodexPlanPriority(report: UsageReport | null): number {
|
|
|
208
208
|
return planType.includes("pro") ? 0 : 2;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
+
function hasOpenAICodexProPlan(report: UsageReport | null): boolean {
|
|
212
|
+
return getUsagePlanType(report)?.includes("pro") === true;
|
|
213
|
+
}
|
|
214
|
+
|
|
211
215
|
function resolveDefaultUsageProvider(provider: Provider): UsageProvider | undefined {
|
|
212
216
|
return DEFAULT_USAGE_PROVIDER_MAP.get(provider);
|
|
213
217
|
}
|
|
@@ -1656,14 +1660,14 @@ export class AuthStorage {
|
|
|
1656
1660
|
const providerKey = this.#getProviderTypeKey(provider, "oauth");
|
|
1657
1661
|
const order = this.#getCredentialOrder(providerKey, sessionId, credentials.length);
|
|
1658
1662
|
const strategy = this.#rankingStrategyResolver?.(provider);
|
|
1659
|
-
const
|
|
1663
|
+
const requiresProModel = requiresOpenAICodexProModel(provider, options?.modelId);
|
|
1664
|
+
const checkUsage = strategy !== undefined && (credentials.length > 1 || requiresProModel);
|
|
1660
1665
|
const sessionCredential = this.#getSessionCredential(provider, sessionId);
|
|
1661
1666
|
const sessionPreferredIndex = sessionCredential?.type === "oauth" ? sessionCredential.index : undefined;
|
|
1662
1667
|
// Skip ranking only when the session already has a working preferred credential — re-ranking
|
|
1663
1668
|
// mid-session causes account switches that cold-start the server-side prompt cache. New sessions
|
|
1664
1669
|
// (no preference) and sessions whose preferred is blocked still rank, so we pick the account
|
|
1665
1670
|
// with the most headroom proactively and fall back intelligently when rate-limited.
|
|
1666
|
-
const requiresProModel = requiresOpenAICodexProModel(provider, options?.modelId);
|
|
1667
1671
|
const sessionPreferredIsAvailable =
|
|
1668
1672
|
sessionPreferredIndex !== undefined && !this.#isCredentialBlocked(providerKey, sessionPreferredIndex);
|
|
1669
1673
|
const shouldRank = checkUsage && (!sessionPreferredIsAvailable || requiresProModel);
|
|
@@ -1777,10 +1781,11 @@ export class AuthStorage {
|
|
|
1777
1781
|
return undefined;
|
|
1778
1782
|
}
|
|
1779
1783
|
|
|
1784
|
+
const requiresProModel = requiresOpenAICodexProModel(provider, options?.modelId);
|
|
1780
1785
|
let usage: UsageReport | null = null;
|
|
1781
1786
|
let usageChecked = false;
|
|
1782
1787
|
|
|
1783
|
-
if (checkUsage && !allowBlocked) {
|
|
1788
|
+
if ((checkUsage && !allowBlocked) || requiresProModel) {
|
|
1784
1789
|
if (usagePrechecked) {
|
|
1785
1790
|
usage = prefetchedUsage;
|
|
1786
1791
|
usageChecked = true;
|
|
@@ -1791,7 +1796,10 @@ export class AuthStorage {
|
|
|
1791
1796
|
});
|
|
1792
1797
|
usageChecked = true;
|
|
1793
1798
|
}
|
|
1794
|
-
if (
|
|
1799
|
+
if (requiresProModel && !hasOpenAICodexProPlan(usage)) {
|
|
1800
|
+
return undefined;
|
|
1801
|
+
}
|
|
1802
|
+
if (checkUsage && !allowBlocked && usage && this.#isUsageLimitReached(usage)) {
|
|
1795
1803
|
const resetAtMs = this.#getUsageResetAtMs(usage, Date.now());
|
|
1796
1804
|
this.#markCredentialBlocked(
|
|
1797
1805
|
providerKey,
|
|
@@ -1829,15 +1837,19 @@ export class AuthStorage {
|
|
|
1829
1837
|
enterpriseUrl: result.newCredentials.enterpriseUrl ?? selection.credential.enterpriseUrl,
|
|
1830
1838
|
};
|
|
1831
1839
|
this.#replaceCredentialAt(provider, selection.index, updated);
|
|
1832
|
-
if (checkUsage && !allowBlocked) {
|
|
1840
|
+
if ((checkUsage && !allowBlocked) || requiresProModel) {
|
|
1833
1841
|
const sameAccount = selection.credential.accountId === updated.accountId;
|
|
1834
1842
|
if (!usageChecked || !sameAccount) {
|
|
1835
1843
|
usage = await this.#getUsageReport(provider, updated, {
|
|
1836
1844
|
...options,
|
|
1837
1845
|
timeoutMs: this.#usageRequestTimeoutMs,
|
|
1838
1846
|
});
|
|
1847
|
+
usageChecked = true;
|
|
1848
|
+
}
|
|
1849
|
+
if (requiresProModel && !hasOpenAICodexProPlan(usage)) {
|
|
1850
|
+
return undefined;
|
|
1839
1851
|
}
|
|
1840
|
-
if (usage && this.#isUsageLimitReached(usage)) {
|
|
1852
|
+
if (checkUsage && !allowBlocked && usage && this.#isUsageLimitReached(usage)) {
|
|
1841
1853
|
const resetAtMs = this.#getUsageResetAtMs(usage, Date.now());
|
|
1842
1854
|
this.#markCredentialBlocked(
|
|
1843
1855
|
providerKey,
|
package/src/model-thinking.ts
CHANGED
|
@@ -48,6 +48,14 @@ const CODEX_GPT_5_4_PRIORITY_BY_VARIANT: Partial<Record<OpenAIVariant, number>>
|
|
|
48
48
|
nano: 2,
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
+
const COPILOT_GENERATED_LIMITS: Record<string, { contextWindow: number; maxTokens: number }> = {
|
|
52
|
+
"claude-opus-4.6": { contextWindow: 168000, maxTokens: 32000 },
|
|
53
|
+
"gpt-5.2": { contextWindow: 272000, maxTokens: 128000 },
|
|
54
|
+
"gpt-5.4": { contextWindow: 272000, maxTokens: 128000 },
|
|
55
|
+
"gpt-5.4-mini": { contextWindow: 272000, maxTokens: 128000 },
|
|
56
|
+
"grok-code-fast-1": { contextWindow: 192000, maxTokens: 64000 },
|
|
57
|
+
};
|
|
58
|
+
|
|
51
59
|
interface GeminiModel {
|
|
52
60
|
family: "gemini";
|
|
53
61
|
kind: GeminiKind;
|
|
@@ -258,7 +266,7 @@ export function mapEffortToGoogleThinkingLevel<TApi extends Api>(
|
|
|
258
266
|
export function mapEffortToAnthropicAdaptiveEffort<TApi extends Api>(
|
|
259
267
|
model: ApiModel<TApi>,
|
|
260
268
|
effort: Effort,
|
|
261
|
-
): "low" | "medium" | "high" | "max" {
|
|
269
|
+
): "low" | "medium" | "high" | "xhigh" | "max" {
|
|
262
270
|
switch (requireSupportedEffort(model, effort)) {
|
|
263
271
|
case Effort.Minimal:
|
|
264
272
|
case Effort.Low:
|
|
@@ -268,12 +276,34 @@ export function mapEffortToAnthropicAdaptiveEffort<TApi extends Api>(
|
|
|
268
276
|
case Effort.High:
|
|
269
277
|
return "high";
|
|
270
278
|
case Effort.XHigh:
|
|
271
|
-
|
|
279
|
+
// Opus 4.7+ introduced a distinct "xhigh" effort level (between "high" and "max").
|
|
280
|
+
// The Anthropic docs scope this to the Messages API only, so Bedrock Converse and
|
|
281
|
+
// older adaptive-thinking Opus 4.6 models keep the legacy "max" alias.
|
|
282
|
+
return anthropicModelHasRealXHighEffort(model) ? "xhigh" : "max";
|
|
272
283
|
}
|
|
273
284
|
}
|
|
274
285
|
|
|
286
|
+
function anthropicModelHasRealXHighEffort<TApi extends Api>(model: ApiModel<TApi>): boolean {
|
|
287
|
+
if (model.api !== "anthropic-messages") return false;
|
|
288
|
+
const parsedModel = parseKnownModel(model.id);
|
|
289
|
+
if (parsedModel.family !== "anthropic" || parsedModel.kind !== "opus") return false;
|
|
290
|
+
return semverGte(parsedModel.version, "4.7");
|
|
291
|
+
}
|
|
292
|
+
|
|
275
293
|
function applyGeneratedModelPolicy(model: ApiModel<Api>): void {
|
|
294
|
+
const copilotLimits = model.provider === "github-copilot" ? COPILOT_GENERATED_LIMITS[model.id] : undefined;
|
|
295
|
+
if (copilotLimits) {
|
|
296
|
+
model.contextWindow = copilotLimits.contextWindow;
|
|
297
|
+
model.maxTokens = copilotLimits.maxTokens;
|
|
298
|
+
}
|
|
299
|
+
|
|
276
300
|
const parsedModel = parseKnownModel(model.id);
|
|
301
|
+
const applyPatchToolType = inferGeneratedApplyPatchToolType(model, parsedModel);
|
|
302
|
+
if (applyPatchToolType) {
|
|
303
|
+
model.applyPatchToolType = applyPatchToolType;
|
|
304
|
+
} else {
|
|
305
|
+
delete model.applyPatchToolType;
|
|
306
|
+
}
|
|
277
307
|
if (parsedModel.family === "anthropic") {
|
|
278
308
|
applyAnthropicCatalogPolicy(model, parsedModel);
|
|
279
309
|
}
|
|
@@ -298,6 +328,22 @@ function applyAnthropicCatalogPolicy(model: ApiModel<Api>, parsedModel: Anthropi
|
|
|
298
328
|
}
|
|
299
329
|
}
|
|
300
330
|
|
|
331
|
+
function inferGeneratedApplyPatchToolType(
|
|
332
|
+
model: ApiModel<Api>,
|
|
333
|
+
parsedModel: ParsedModel,
|
|
334
|
+
): ApiModel<Api>["applyPatchToolType"] {
|
|
335
|
+
if (parsedModel.family !== "openai" || parsedModel.version.major !== 5) {
|
|
336
|
+
return undefined;
|
|
337
|
+
}
|
|
338
|
+
if (model.provider === "openai" && model.api === "openai-responses") {
|
|
339
|
+
return "freeform";
|
|
340
|
+
}
|
|
341
|
+
if (model.provider === "openai-codex" && model.api === "openai-codex-responses") {
|
|
342
|
+
return "freeform";
|
|
343
|
+
}
|
|
344
|
+
return undefined;
|
|
345
|
+
}
|
|
346
|
+
|
|
301
347
|
function applyOpenAICatalogPolicy(model: ApiModel<Api>, parsedModel: OpenAIModel): void {
|
|
302
348
|
// Codex models: 400K figure includes output budget; input window is 272K.
|
|
303
349
|
if (parsedModel.variant.startsWith("codex") && parsedModel.variant !== "codex-spark") {
|