@oh-my-pi/pi-catalog 18.12.5 → 18.13.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 +55 -0
- package/dist/types/compat/anthropic.d.ts +20 -0
- package/dist/types/compat/behavior.d.ts +2 -0
- package/dist/types/compat/catalog-policy.d.ts +2 -2
- package/dist/types/compat/collapse.d.ts +10 -0
- package/dist/types/compat/factory-droid.d.ts +2 -0
- package/dist/types/compat/prompt-cache-persistent.d.ts +7 -0
- package/dist/types/compat/resolve.d.ts +2 -2
- package/dist/types/compat/types.d.ts +2 -0
- package/dist/types/discovery/antigravity.d.ts +7 -2
- package/dist/types/discovery/devin.d.ts +1 -1
- package/dist/types/provider-models/google.d.ts +2 -0
- package/dist/types/provider-models/openai-compat.d.ts +7 -2
- package/dist/types/types.d.ts +58 -3
- package/dist/types/wire/devin.d.ts +2 -2
- package/dist/types/wire/gemini-headers.d.ts +41 -22
- package/dist/types/wire/xiaomi-token-plan.d.ts +2 -0
- package/package.json +4 -4
- package/src/build.ts +47 -1
- package/src/compat/anthropic.ts +47 -0
- package/src/compat/axes.ts +17 -3
- package/src/compat/behavior.ts +5 -0
- package/src/compat/catalog-policy.ts +10 -8
- package/src/compat/collapse.ts +63 -2
- package/src/compat/factory-droid.ts +3 -0
- package/src/compat/prompt-cache-persistent.ts +12 -0
- package/src/compat/resolve.ts +7 -5
- package/src/compat/rules/README.md +15 -5
- package/src/compat/rules/auth/google-antigravity.kdl +2 -1
- package/src/compat/rules/auth/llama.cpp.kdl +1 -1
- package/src/compat/rules/auth/xiaomi-token-plan-ams.kdl +1 -1
- package/src/compat/rules/auth/xiaomi-token-plan-cn.kdl +1 -1
- package/src/compat/rules/auth/xiaomi-token-plan-sgp.kdl +1 -1
- package/src/compat/rules/classes/anthropic.kdl +6 -1
- package/src/compat/rules/classes/minimax.kdl +10 -0
- package/src/compat/rules/providers/anthropic.kdl +15 -1
- package/src/compat/rules/providers/deepseek.kdl +13 -10
- package/src/compat/rules/providers/factory-droid.kdl +48 -0
- package/src/compat/rules/providers/google-antigravity.kdl +7 -0
- package/src/compat/rules/providers/kimi-code.kdl +4 -0
- package/src/compat/rules/providers/muse-code.kdl +1 -1
- package/src/compat/rules/providers/openai-codex.kdl +7 -4
- package/src/compat/rules/providers/openai.kdl +22 -2
- package/src/compat/rules/providers/opencode-go.kdl +38 -3
- package/src/compat/rules/providers/opencode-zen.kdl +7 -0
- package/src/compat/rules/providers/xiaomi-token-plan-ams.kdl +1 -1
- package/src/compat/rules/providers/xiaomi-token-plan-cn.kdl +1 -1
- package/src/compat/rules/providers/xiaomi-token-plan-sgp.kdl +1 -1
- package/src/compat/rules/providers/xiaomi.kdl +1 -1
- package/src/compat/rules/providers/yolo-auto.kdl +33 -37
- package/src/compat/rules/runtime/behavior.kdl +20 -10
- package/src/compat/rules/taxonomy/qwen.kdl +1 -1
- package/src/compat/rules.json +1 -1
- package/src/compat/types.ts +2 -0
- package/src/discovery/antigravity.ts +41 -6
- package/src/discovery/cursor.ts +0 -6
- package/src/discovery/devin.ts +9 -3
- package/src/discovery/factory-droid.ts +38 -6
- package/src/model-cache.ts +4 -2
- package/src/models.json +1 -1
- package/src/provider-models/cache-provider-id.ts +5 -2
- package/src/provider-models/google.ts +13 -1
- package/src/provider-models/openai-compat.ts +42 -12
- package/src/types.ts +63 -1
- package/src/wire/devin.ts +2 -2
- package/src/wire/gemini-headers.ts +68 -24
- package/src/wire/xiaomi-token-plan.ts +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,61 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.13.0] - 2026-10-26
|
|
6
|
+
|
|
7
|
+
### Breaking Changes
|
|
8
|
+
|
|
9
|
+
- Renamed the `task-sibling-prompt-cache` axis to `shared-prompt-cache` (catalog field `sharedPromptCache`); it now also covers forks and explicit prompt-cache keys ([#16988](https://github.com/can1357/oh-my-pi/pull/16988) by [@rafalopilowski1](https://github.com/rafalopilowski1))
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Added the `requiresThinkingPresence` model compat (KDL `requires-thinking-presence`) for Anthropic-compatible endpoints that reject a thinking-mode request whose current turn has an assistant message without a `thinking` block ([#16739](https://github.com/can1357/oh-my-pi/pull/16739) by [@lz37](https://github.com/lz37))
|
|
14
|
+
- Added `resolveAnthropicApiVersion()`: Anthropic model discovery sends API version 2026-10-21 to the official API when `PI_ANTHROPIC_API_VERSION=2026-10-21` is set ([#16706](https://github.com/can1357/oh-my-pi/pull/16706) by [@H4vC](https://github.com/H4vC))
|
|
15
|
+
- OpenCode Go `muse-spark-1.3-contributor`, `muse-spark-1.2-contributor`, `gpt-5.6-luna`, `gpt-6-luna`, `grok-4.6` (Responses) and `deepseek-v4-pro`, `omen-alpha` (Completions) opt into shared prompt caching; lanes that warmed under any key stay off ([#16988](https://github.com/can1357/oh-my-pi/pull/16988) by [@rafalopilowski1](https://github.com/rafalopilowski1))
|
|
16
|
+
- Added `CatalogPolicyInputs` so catalog-policy lookups accept a reduced model view ([#16988](https://github.com/can1357/oh-my-pi/pull/16988) by [@rafalopilowski1](https://github.com/rafalopilowski1))
|
|
17
|
+
- Added a catalog conformance test that fails the build when a `bundle="always"` seed row is missing from the bundled `models.json`, so a stale-snapshot regeneration can no longer silently drop an engine the way `web/deepseek` was lost in 18.12.2 ([#16610](https://github.com/can1357/oh-my-pi/issues/16610), [#17053](https://github.com/can1357/oh-my-pi/pull/17053) by [@ouyangjiahong26](https://github.com/ouyangjiahong26))
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- llama.cpp login instructions now list both default local base URLs (`http://127.0.0.1:8080`, then `http://127.0.0.1:9931`) ([#16675](https://github.com/can1357/oh-my-pi/pull/16675) by [@bartbroere](https://github.com/bartbroere))
|
|
22
|
+
- Devin requests now identify as Devin CLI 3000.11.205, the current stable release, instead of 3000.11.3 ([#16906](https://github.com/can1357/oh-my-pi/pull/16906) by [@will-bogusz](https://github.com/will-bogusz))
|
|
23
|
+
- Google Antigravity login now uses PKCE and requests the `aicode` scope like the official client; existing logins keep working, and the new scope applies at the next `/login` ([#17012](https://github.com/can1357/oh-my-pi/pull/17012) by [@apoc](https://github.com/apoc))
|
|
24
|
+
- Antigravity requests identify as client 2.26.0 when the release manifest is unreachable (previously 2.19.1), and model discovery sends the account's project like the official client ([#17012](https://github.com/can1357/oh-my-pi/pull/17012) by [@apoc](https://github.com/apoc))
|
|
25
|
+
- Antigravity's `User-Agent` now reports the native Antigravity build for the host OS (Linux `linux`/`amd64`, Windows `windows`/`amd64`) instead of always claiming macOS `darwin`/`arm64` ([#17012](https://github.com/can1357/oh-my-pi/pull/17012) by [@apoc](https://github.com/apoc))
|
|
26
|
+
- Antigravity model discovery now keeps each account's per-tier `model_enum`, output cap and thinking level or budget, and the bundled Antigravity models carry them for offline use; cached Antigravity model lists are refreshed once so they pick them up ([#17012](https://github.com/can1357/oh-my-pi/pull/17012) by [@apoc](https://github.com/apoc))
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- Fixed OpenCode Go `gemini-4-argon` requests failing with an unsupported protocol; discovered models now use native Gemini routing and low, medium, or high thinking ([#17031](https://github.com/can1357/oh-my-pi/issues/17031))
|
|
31
|
+
- Fixed DeepSeek V4 Pro cost estimates using Flash rates after September 14 despite Pro billing remaining unchanged ([#16875](https://github.com/can1357/oh-my-pi/issues/16875)).
|
|
32
|
+
- Anthropic refusal fallbacks from Claude Opus 5.5, Opus 5 and Sonnet 5.5 to their documented target models (Opus 4.8 and Opus 5, Opus 4.8, and Sonnet 5) now redeem fallback credit: the retry is no longer billed as a full cache write, and it is no longer skipped when the conversation holds signed thinking ([#17034](https://github.com/can1357/oh-my-pi/pull/17034) by [@sjawhar](https://github.com/sjawhar))
|
|
33
|
+
- Fixed Step 5 Preview reasoning choices on OpenCode Go and Zen to offer only low, medium, and high ([#14987](https://github.com/can1357/oh-my-pi/issues/14987), [#16669](https://github.com/can1357/oh-my-pi/pull/16669) by [@SheetHappiness](https://github.com/SheetHappiness))
|
|
34
|
+
- Fixed GPT-6 Sol/Luna API and MiniMax-M3 long-context usage estimates above their published input thresholds ([#16711](https://github.com/can1357/oh-my-pi/issues/16711))
|
|
35
|
+
- Fixed Xiaomi Token Plan login and default model selection after the V2.5 retirement by using MiMo V2.6 Flash ([#16727](https://github.com/can1357/oh-my-pi/pull/16727) by [@LiPu-jpg](https://github.com/LiPu-jpg))
|
|
36
|
+
- Fixed Xiaomi model discovery sending `ttp-` Token Plan keys to the pay-as-you-go host, which rejects them ([#17045](https://github.com/can1357/oh-my-pi/issues/17045))
|
|
37
|
+
- Fixed GPT-5.6 Sol requests over 272K input tokens (`openai` and `openai-codex`) being priced at the retired $10/$45 long-context card instead of $8/$30 ([#16742](https://github.com/can1357/oh-my-pi/issues/16742))
|
|
38
|
+
- Fixed DeepSeek's official vision requests being held to the 5-image unknown-host floor: the catalog endpoint now carries DeepSeek's documented 600-image and 40 MiB inline-image budgets, while a custom `baseUrl` keeps the conservative floor ([vision limits](https://api-docs.deepseek.com/guides/vision#limits); [#16737](https://github.com/can1357/oh-my-pi/pull/16737) by [@Fun10165](https://github.com/Fun10165))
|
|
39
|
+
- Fixed Devin model discovery falling back to the two SWE-1.6 seed models when the catalog takes longer than 5s to respond; it now waits up to 15s ([#16668](https://github.com/can1357/oh-my-pi/pull/16668) by [@DusKing1](https://github.com/DusKing1))
|
|
40
|
+
- Fixed Go Task keeping stale prompt-cache affinity after a model's wire model changed ([#16988](https://github.com/can1357/oh-my-pi/pull/16988) by [@rafalopilowski1](https://github.com/rafalopilowski1))
|
|
41
|
+
- Fixed Devin models all showing a 200K context window: each model now reports its own (1M for Claude Opus 5.5 and the `-1m` lanes, 262K for SWE-2), and GPT and Grok models with a long-context price tier start at that tier's threshold, with `/extended-context on` opening their full window ([#16905](https://github.com/can1357/oh-my-pi/pull/16905) by [@will-bogusz](https://github.com/will-bogusz))
|
|
42
|
+
- Added the `extended-cache-ttl-beta` compat axis so a route can opt out of the `extended-cache-ttl-2025-04-11` beta (Factory Droid does), and prompt-cache lifetimes and long-retention support for Factory Droid's Claude models ([#16296](https://github.com/can1357/oh-my-pi/pull/16296) by [@will-bogusz](https://github.com/will-bogusz))
|
|
43
|
+
- Added Factory Droid's image models (GPT Image 2.5, GPT Image 2.5 Flare, Gemini 3 Pro Image) to the `image` role's choices, listed only while your Factory organization allows image generation and that model ([#16316](https://github.com/can1357/oh-my-pi/pull/16316) by [@will-bogusz](https://github.com/will-bogusz))
|
|
44
|
+
- Fixed LiteLLM model groups with `mode: decisions` being listed as chat models; they now route to `openai-decisions` as judge models ([#16939](https://github.com/can1357/oh-my-pi/issues/16939))
|
|
45
|
+
- Removed retired Anthropic models (Claude 3.x, Opus 4/4.1, Sonnet 4) from the bundled catalog and discovery ([#16755](https://github.com/can1357/oh-my-pi/issues/16755))
|
|
46
|
+
- Fixed Kimi Code K3 and K3 256K (`k3`, `k3-256k`) pricing to include Kimi's $3/MTok cache-write rate, matching the Moonshot API `kimi-k3` card ([#16508](https://github.com/can1357/oh-my-pi/issues/16508), [#16903](https://github.com/can1357/oh-my-pi/pull/16903) by [@eggpeat](https://github.com/eggpeat))
|
|
47
|
+
- Fixed Devin models all showing a 200K context window: each model now reports its own (1M for Claude Opus 5.5 and the `-1m` lanes, 262K for SWE-2), and GPT and Grok models with a long-context price tier start at that tier's threshold, with `/extended-context on` opening their full window ([#16905](https://github.com/can1357/oh-my-pi/pull/16905) by [@will-bogusz](https://github.com/will-bogusz))
|
|
48
|
+
- Fixed Cursor Auto (`cursor/default`) being metered against the third-party ("Other Models") pool instead of the Cursor Models pool it bills to ([#17048](https://github.com/can1357/oh-my-pi/pull/17048) by [@trukhinyuri](https://github.com/trukhinyuri))
|
|
49
|
+
|
|
50
|
+
## [18.12.6] - 2026-10-21
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
|
|
54
|
+
- Added the `prompt-cache-persistent` catalog axis (`isPromptCachePersistent`) for providers whose own endpoint never expires prompt caches; logged-in OpenAI Codex declares it
|
|
55
|
+
|
|
56
|
+
### Changed
|
|
57
|
+
|
|
58
|
+
- Updated the bundled Yolo-Auto catalog to its current models, `qwen3.8-27b` (now the default), `yolo`, `yolo-small`, and `yolo-128k`, and removed the retired `deepseek-flash-v4` and `qwen3.8-flash`
|
|
59
|
+
|
|
5
60
|
## [18.12.5] - 2026-10-21
|
|
6
61
|
|
|
7
62
|
### Fixed
|
|
@@ -6,6 +6,26 @@
|
|
|
6
6
|
* prefix check would accept lookalikes like `https://api.anthropic.com.evil.com`.
|
|
7
7
|
*/
|
|
8
8
|
export declare function isOfficialAnthropicApiUrl(baseUrl?: string): boolean;
|
|
9
|
+
/** `anthropic-version` values this codebase knows how to speak. */
|
|
10
|
+
export declare const ANTHROPIC_API_VERSIONS: readonly ["2023-06-01", "2026-10-21"];
|
|
11
|
+
export type AnthropicApiVersion = (typeof ANTHROPIC_API_VERSIONS)[number];
|
|
12
|
+
/** Version every non-official Anthropic-compatible endpoint receives. */
|
|
13
|
+
export declare const LEGACY_ANTHROPIC_API_VERSION: AnthropicApiVersion;
|
|
14
|
+
/**
|
|
15
|
+
* `anthropic-version` for a request to `baseUrl`. `PI_ANTHROPIC_API_VERSION`
|
|
16
|
+
* opts the official first-party API into a newer version; every other host
|
|
17
|
+
* (Copilot, Bedrock, Foundry, Cloudflare, third-party compatibles) stays on
|
|
18
|
+
* {@link LEGACY_ANTHROPIC_API_VERSION} because those deployments gate newer
|
|
19
|
+
* versions on their own schedule (Bedrock accepts 2026-10-21 only for 4.7+).
|
|
20
|
+
* Read per call so a flipped environment takes effect without a restart.
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveAnthropicApiVersion(baseUrl?: string): AnthropicApiVersion;
|
|
23
|
+
/**
|
|
24
|
+
* Whether Messages requests on `version` may carry `temperature`, `top_p`,
|
|
25
|
+
* or `top_k`. API version 2026-10-21 rejects all three with a 400, even at
|
|
26
|
+
* their default values.
|
|
27
|
+
*/
|
|
28
|
+
export declare function anthropicApiVersionAcceptsSamplingParams(version: AnthropicApiVersion): boolean;
|
|
9
29
|
/**
|
|
10
30
|
* Amazon Bedrock's Anthropic Messages API: the `/anthropic` path on the
|
|
11
31
|
* bedrock-runtime or bedrock-mantle endpoint. It rejects the tool `strict`
|
|
@@ -71,6 +71,8 @@ export declare function isRetiredProvider(provider: string): boolean;
|
|
|
71
71
|
* model that happens to advertise the same bare id.
|
|
72
72
|
*/
|
|
73
73
|
export declare function isBareIdReferenceProvider(provider: string): boolean;
|
|
74
|
+
/** Whether a host's prefix cache should use append-only conversation context by default. */
|
|
75
|
+
export declare function prefersAppendOnlyContext(provider: string): boolean;
|
|
74
76
|
/** The declared subscription tier required to use a provider model id, if any. */
|
|
75
77
|
export declare function planRequirementFor(provider: string, model: string): string | undefined;
|
|
76
78
|
/** Cross-provider pricing-peer resolution for one provider model id. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CatalogPolicyInputs } from "../types.js";
|
|
2
2
|
/**
|
|
3
3
|
* The `catalog` axis bag authored in the KDL cascade rules for a model,
|
|
4
4
|
* memoized per distinct model. Frozen: the bag is shared across callers, so it
|
|
5
5
|
* must stay read-only — extract the value you need rather than handing it on.
|
|
6
6
|
*/
|
|
7
|
-
export declare function resolveCatalogPolicy(model:
|
|
7
|
+
export declare function resolveCatalogPolicy(model: CatalogPolicyInputs): Readonly<Record<string, unknown>>;
|
|
@@ -139,6 +139,16 @@ export declare function isCollapsedVariantSpec(spec: VariantSpecLike): boolean;
|
|
|
139
139
|
* and for routes live discovery never advertised.
|
|
140
140
|
*/
|
|
141
141
|
export declare function isCursorMaxModeWireId(wireModelId: string): boolean;
|
|
142
|
+
/**
|
|
143
|
+
* Whether `wireModelId` is one tier of a reviewed `provider` family that serves
|
|
144
|
+
* different efforts from distinct sibling SKUs (`-low`/`-medium`/`-high`), so
|
|
145
|
+
* the SKU, not the effort, fixes the thinking strength. Decided from the
|
|
146
|
+
* declared family routes, not a collapsed row's routing: an account roster
|
|
147
|
+
* listing one tier collapses to a row routing every effort to it, yet that SKU
|
|
148
|
+
* still advertises its own fixed thinking. Families routing every effort to
|
|
149
|
+
* one `-thinking` SKU keep the effort's own budget or level.
|
|
150
|
+
*/
|
|
151
|
+
export declare function isReviewedTierVariantWireId(provider: string, wireModelId: string): boolean;
|
|
142
152
|
/**
|
|
143
153
|
* Collapse a full mixed-provider list: per provider, the compiled reviewed table, Cursor's
|
|
144
154
|
* conservative live effort-sibling rule, and the automatic `X`/`X-thinking`
|
|
@@ -45,6 +45,8 @@ export interface FactoryDroidModelPolicy {
|
|
|
45
45
|
entitlement: FactoryDroidEntitlement;
|
|
46
46
|
/** Native default with no caller effort is thinking off. */
|
|
47
47
|
defaultReasoningOff: boolean;
|
|
48
|
+
/** A `generate_image` model: gated by the org's image-generation settings, served through Factory's image routes. */
|
|
49
|
+
image: boolean;
|
|
48
50
|
}
|
|
49
51
|
/** One registry model: its roster row and resolved policy. */
|
|
50
52
|
export interface FactoryDroidRegistryModel {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Model } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Whether {@link model}'s prompt-cache entries never expire
|
|
4
|
+
* (`prompt-cache-persistent` axis). Only the provider's own endpoint
|
|
5
|
+
* qualifies: a gateway or proxy reusing the provider id makes no such promise.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isPromptCachePersistent(model: Model): boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Api, CompatOf, ModelSpec, ThinkingConfig } from "../types.js";
|
|
1
|
+
import type { Api, CatalogPolicyInputs, CompatOf, ModelSpec, ThinkingConfig } from "../types.js";
|
|
2
2
|
import type { ModelIdentity, RequestPolicy } from "./types.js";
|
|
3
3
|
/** Result of resolving one model spec through the compat engine. */
|
|
4
4
|
export interface ResolvedModelPolicy<TApi extends Api = Api> {
|
|
@@ -21,7 +21,7 @@ export declare function resolveDiscoveryApi(spec: ModelSpec<Api>, providerType:
|
|
|
21
21
|
* {@link resolveModelPolicy} without resolving the compat and thinking
|
|
22
22
|
* policies, which dominate its cost on catalog-wide scans.
|
|
23
23
|
*/
|
|
24
|
-
export declare function resolveCatalogAxes(spec:
|
|
24
|
+
export declare function resolveCatalogAxes(spec: CatalogPolicyInputs): Record<string, unknown>;
|
|
25
25
|
/**
|
|
26
26
|
* Resolves the full policy surface for one model spec: structured identity,
|
|
27
27
|
* complete compat record, thinking metadata, and catalog-data corrections.
|
|
@@ -327,6 +327,8 @@ export interface CompiledBehavior {
|
|
|
327
327
|
pricingPeers: CompiledPricingPeer[];
|
|
328
328
|
retryResetTimezones: CompiledRetryResetTimezone[];
|
|
329
329
|
retiredProviders: string[];
|
|
330
|
+
/** Hosts whose prefix caches benefit from a stable append-only conversation. */
|
|
331
|
+
appendOnlyContextProviders: string[];
|
|
330
332
|
referenceIsolatedProviders: string[];
|
|
331
333
|
/** Built-in model selector chains per agent role, keyed by role in declaration order. */
|
|
332
334
|
roleDefaults: Record<string, string[]>;
|
|
@@ -11,6 +11,8 @@ export interface AntigravityDiscoveryApiModel {
|
|
|
11
11
|
supportsImages?: boolean;
|
|
12
12
|
supportsThinking?: boolean;
|
|
13
13
|
thinkingBudget?: number;
|
|
14
|
+
/** SKU thinking level: 1 low, 2 medium, 3 high. */
|
|
15
|
+
thinkingLevel?: number;
|
|
14
16
|
recommended?: boolean;
|
|
15
17
|
maxTokens?: number;
|
|
16
18
|
maxOutputTokens?: number;
|
|
@@ -55,8 +57,11 @@ export interface FetchAntigravityDiscoveryModelsOptions {
|
|
|
55
57
|
token: string;
|
|
56
58
|
/** Optional endpoint override. Defaults to Antigravity fallback endpoints. */
|
|
57
59
|
endpoint?: string;
|
|
58
|
-
/**
|
|
59
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Cloud Code Assist project the account is onboarded to. Sent as the body's
|
|
62
|
+
* `project` field like the native client; the body is `{}` when absent.
|
|
63
|
+
*/
|
|
64
|
+
projectId?: string;
|
|
60
65
|
/** Optional user agent override. */
|
|
61
66
|
userAgent?: string;
|
|
62
67
|
/** Optional abort signal for request cancellation. */
|
|
@@ -7,7 +7,7 @@ export interface DevinModelDiscoveryOptions {
|
|
|
7
7
|
apiKey?: string;
|
|
8
8
|
/** Optional Codeium API base URL override. */
|
|
9
9
|
baseUrl?: string;
|
|
10
|
-
/** Optional request timeout in milliseconds (default
|
|
10
|
+
/** Optional request timeout in milliseconds (default 15000). */
|
|
11
11
|
timeoutMs?: number;
|
|
12
12
|
/** Optional caller abort signal, combined with the internal timeout. */
|
|
13
13
|
signal?: AbortSignal;
|
|
@@ -21,6 +21,8 @@ export interface GoogleAntigravityAccount {
|
|
|
21
21
|
* When any account lacks one, no model records per-account access.
|
|
22
22
|
*/
|
|
23
23
|
accountKey?: string;
|
|
24
|
+
/** Cloud Code Assist project of the credential, sent with roster discovery like the native client. */
|
|
25
|
+
projectId?: string;
|
|
24
26
|
}
|
|
25
27
|
export interface GoogleAntigravityModelManagerConfig {
|
|
26
28
|
/**
|
|
@@ -475,8 +475,8 @@ export interface YoloAutoModelManagerConfig {
|
|
|
475
475
|
fetch?: FetchImpl;
|
|
476
476
|
}
|
|
477
477
|
/**
|
|
478
|
-
* Yolo-Auto model manager: OpenAI-compatible chat completions
|
|
479
|
-
*
|
|
478
|
+
* Yolo-Auto model manager: flat-rate OpenAI-compatible chat completions
|
|
479
|
+
* (`qwen3.8-27b`, `yolo`, ...). Live `/v1/models` discovery replaces the
|
|
480
480
|
* bundled seed once a key is stored or present in `YOLO_AUTO_API_KEY`. Models
|
|
481
481
|
* the provider adds later inherit metadata (reasoning, thinking, context)
|
|
482
482
|
* from the global bundled reference index, so new ids work without a per-id
|
|
@@ -560,6 +560,11 @@ export declare const OPENAI_COMPAT_DISCOVERY_DEFAULT_MAX_TOKENS = 32768;
|
|
|
560
560
|
/** Exclude only known non-conversational modes; unknown and non-string modes remain selectable for aliases. */
|
|
561
561
|
export declare function isSelectableLiteLLMModelMode(mode: unknown): boolean;
|
|
562
562
|
export declare function normalizeLiteLLMManagementBaseUrl(baseUrl: string): string;
|
|
563
|
+
/**
|
|
564
|
+
* Transport for a LiteLLM model group: `mode: "decisions"` answers only on the
|
|
565
|
+
* proxy's `/v1/decisions` route, OpenAI-backed groups use Responses, and every
|
|
566
|
+
* other group uses `fallbackApi`.
|
|
567
|
+
*/
|
|
563
568
|
export declare function resolveLiteLLMApi(entry: Record<string, unknown> | undefined, id: string, fallbackApi?: Api): Api;
|
|
564
569
|
export declare function fetchLiteLLMRichModels<TApi extends Api>(options: FetchLiteLLMRichModelsOptions<TApi>): Promise<ModelSpec<TApi>[] | null>;
|
|
565
570
|
export declare function litellmModelManagerOptions(config?: LiteLLMModelManagerConfig): ModelManagerOptions<Api>;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -20,12 +20,12 @@ export declare const RUNNER_API_KINDS: Record<Exclude<(typeof RUNNER_APIS)[numbe
|
|
|
20
20
|
/** Kind a runner API serves; `undefined` for chat transports and multi-kind `local-inference`. */
|
|
21
21
|
export declare function runnerApiKind(api: Api): ModelKind | undefined;
|
|
22
22
|
/** Catalog APIs `generate_image` runs through a pi-ai image client; the hosted Responses pair needs a carrier model. */
|
|
23
|
-
export declare const IMAGE_GENERATION_APIS: readonly ["openai-images", "openrouter-images", "google-generative-ai", "google-gemini-cli", "openai-responses", "openai-codex-responses"];
|
|
23
|
+
export declare const IMAGE_GENERATION_APIS: readonly ["openai-images", "openrouter-images", "google-generative-ai", "google-gemini-cli", "openai-responses", "openai-codex-responses", "factory-droid-agent"];
|
|
24
24
|
export type ImageGenerationApi = (typeof IMAGE_GENERATION_APIS)[number];
|
|
25
25
|
/**
|
|
26
26
|
* Kinds a model on `api` may declare: a runner api serves its own kind; a chat
|
|
27
27
|
* transport serves `chat` and `tiny`, plus `image` when `generate_image` runs it
|
|
28
|
-
* (hosted Responses image tool, Gemini image models). `undefined` for
|
|
28
|
+
* (hosted Responses image tool, Gemini and Factory Droid image models). `undefined` for
|
|
29
29
|
* `local-inference`, which hosts several kinds chosen by the model itself.
|
|
30
30
|
*/
|
|
31
31
|
export declare function servedKinds(api: Api): readonly ModelKind[] | undefined;
|
|
@@ -550,6 +550,8 @@ export interface AnthropicCompat {
|
|
|
550
550
|
supportsEagerToolInputStreaming?: boolean;
|
|
551
551
|
/** Whether long prompt-cache retention (`ttl: "1h"`) is supported. Default: true for canonical Anthropic API. */
|
|
552
552
|
supportsLongCacheRetention?: boolean;
|
|
553
|
+
/** Whether a `ttl: "1h"` breakpoint on API-key requests adds the `extended-cache-ttl-2025-04-11` beta. Unset: true (Vertex rawPredict URLs never send it). */
|
|
554
|
+
extendedCacheTtlBeta?: boolean;
|
|
553
555
|
/**
|
|
554
556
|
* Whether mid-conversation `role: "system"` messages are accepted in the
|
|
555
557
|
* `messages` array. When unset, auto-detected from model and deployment policy.
|
|
@@ -608,6 +610,21 @@ export interface AnthropicCompat {
|
|
|
608
610
|
* Default: auto-detected from provider/baseUrl and `model.reasoning`.
|
|
609
611
|
*/
|
|
610
612
|
replayUnsignedThinking?: boolean;
|
|
613
|
+
/**
|
|
614
|
+
* Whether a thinking-mode history must carry a `thinking` block on EVERY
|
|
615
|
+
* assistant turn of the current turn. DeepSeek's Anthropic endpoint rejects
|
|
616
|
+
* the whole request (`The content[].thinking in the thinking mode must be
|
|
617
|
+
* passed back to the API.`) when any assistant turn after the last user text
|
|
618
|
+
* lacks one, including turns another upstream in the same gateway model group
|
|
619
|
+
* produced without reasoning. Presence is all it validates (the block text may
|
|
620
|
+
* be a placeholder, the signature may be empty), and only `thinking` counts —
|
|
621
|
+
* `redacted_thinking` does not, and that endpoint rejects the block outright.
|
|
622
|
+
* A model group that may fail over to such an endpoint must set this: the
|
|
623
|
+
* stricter member defines the replay contract for the group.
|
|
624
|
+
* Default: false (official Anthropic and lax proxies tolerate a turn without
|
|
625
|
+
* thinking and the block is not invented for them).
|
|
626
|
+
*/
|
|
627
|
+
requiresThinkingPresence?: boolean;
|
|
611
628
|
/**
|
|
612
629
|
* Whether the endpoint requires `thinking.type: "enabled"` whenever the
|
|
613
630
|
* model reasons. Use for models that reject omitted or disabled thinking.
|
|
@@ -975,9 +992,11 @@ export interface ResolvedOpenAIResponsesCompat extends ResolvedOpenAISharedCompa
|
|
|
975
992
|
*/
|
|
976
993
|
export type ResolvedOpenRouterCompat = ResolvedOpenAICompat & ResolvedOpenAIResponsesCompat;
|
|
977
994
|
/** Fully-resolved anthropic-messages compat view (same contract as `ResolvedOpenAICompat`). */
|
|
978
|
-
export type ResolvedAnthropicCompat = Required<Omit<AnthropicCompat, "streamIdleTimeoutMs" | "thinkingLoopGuard" | "bedrockMessagesApi" | "effortBeta" | "disabledThinking" | "betweenToolsEffort" | "stripThinkingHistory" | "fastMode" | "maxImageDimension" | "maxImagePayloadBytes">> & {
|
|
995
|
+
export type ResolvedAnthropicCompat = Required<Omit<AnthropicCompat, "streamIdleTimeoutMs" | "thinkingLoopGuard" | "bedrockMessagesApi" | "effortBeta" | "extendedCacheTtlBeta" | "disabledThinking" | "betweenToolsEffort" | "stripThinkingHistory" | "fastMode" | "maxImageDimension" | "maxImagePayloadBytes">> & {
|
|
979
996
|
/** Effort-beta override; undefined keeps the transport's legacy heuristic. */
|
|
980
997
|
effortBeta?: AnthropicCompat["effortBeta"];
|
|
998
|
+
/** Extended-cache-ttl beta opt-out; undefined sends it where a 1h breakpoint needs it. */
|
|
999
|
+
extendedCacheTtlBeta?: AnthropicCompat["extendedCacheTtlBeta"];
|
|
981
1000
|
/** Disabled-thinking wire form; undefined keeps the direct-provider behavior. */
|
|
982
1001
|
disabledThinking?: AnthropicCompat["disabledThinking"];
|
|
983
1002
|
/** Effort pinned on `between_tools` turns; undefined leaves effort untouched. */
|
|
@@ -1204,6 +1223,13 @@ export interface ModelAccountAccess {
|
|
|
1204
1223
|
* Absent when the backend reported no program metadata.
|
|
1205
1224
|
*/
|
|
1206
1225
|
cyberPrograms?: readonly string[];
|
|
1226
|
+
/**
|
|
1227
|
+
* Antigravity request constants this account's `fetchAvailableModels`
|
|
1228
|
+
* roster advertised, keyed by upstream SKU id. Takes precedence over
|
|
1229
|
+
* {@link Model.antigravityWireProfiles}, which keeps only the first
|
|
1230
|
+
* account's values when multi-account rosters are unioned.
|
|
1231
|
+
*/
|
|
1232
|
+
antigravityWireProfiles?: Readonly<Record<string, AntigravityModelWireProfile>>;
|
|
1207
1233
|
}
|
|
1208
1234
|
/** One Cursor `RequestedModel.parameters` entry recovered from rich discovery. */
|
|
1209
1235
|
export interface CursorModelParameter {
|
|
@@ -1216,6 +1242,20 @@ export interface CursorModelRoute {
|
|
|
1216
1242
|
parameters: readonly CursorModelParameter[];
|
|
1217
1243
|
maxMode?: boolean;
|
|
1218
1244
|
}
|
|
1245
|
+
/**
|
|
1246
|
+
* Antigravity Cloud Code Assist request constants for one upstream SKU, as the
|
|
1247
|
+
* native client sends them; see {@link Model.antigravityWireProfiles}.
|
|
1248
|
+
*/
|
|
1249
|
+
export interface AntigravityModelWireProfile {
|
|
1250
|
+
/** Opaque `labels.model_enum` token (`fetchAvailableModels` `model`). */
|
|
1251
|
+
modelEnum?: string;
|
|
1252
|
+
/** Fixed `generationConfig.maxOutputTokens` the client always sends. */
|
|
1253
|
+
maxOutputTokens?: number;
|
|
1254
|
+
/** SKU thinking level; the native client sends it in preference to a budget. */
|
|
1255
|
+
thinkingLevel?: "LOW" | "MEDIUM" | "HIGH";
|
|
1256
|
+
/** SKU thinking budget (`-1` is dynamic), sent when no level is advertised. */
|
|
1257
|
+
thinkingBudget?: number;
|
|
1258
|
+
}
|
|
1219
1259
|
export interface Model<TApi extends Api = Api> {
|
|
1220
1260
|
id: string;
|
|
1221
1261
|
/** Role-specific runner capability; omitted for ordinary chat models. */
|
|
@@ -1329,6 +1369,13 @@ export interface Model<TApi extends Api = Api> {
|
|
|
1329
1369
|
* their single wire id) and on bundled snapshots that predate discovery.
|
|
1330
1370
|
*/
|
|
1331
1371
|
cursorMaxModeRoutes?: Readonly<Record<string, boolean>>;
|
|
1372
|
+
/**
|
|
1373
|
+
* Per-wire-id Antigravity request constants recorded from the account's
|
|
1374
|
+
* `fetchAvailableModels` roster, keyed by upstream SKU id. A collapsed row
|
|
1375
|
+
* carries one entry per member it routes to; a raw row carries its own.
|
|
1376
|
+
* Absent on bundled snapshots that predate discovery.
|
|
1377
|
+
*/
|
|
1378
|
+
antigravityWireProfiles?: Readonly<Record<string, AntigravityModelWireProfile>>;
|
|
1332
1379
|
/**
|
|
1333
1380
|
* Per-account availability recorded by multi-account discovery: provider
|
|
1334
1381
|
* account key (Codex: ChatGPT `chatgpt_account_id`; Antigravity: login
|
|
@@ -1525,3 +1572,11 @@ export interface ModelSpec<TApi extends Api = Api> extends Omit<Model<TApi>, "co
|
|
|
1525
1572
|
/** Sparse compatibility overrides; resolved into `Model.compat` by `buildModel`. */
|
|
1526
1573
|
compat?: CompatConfigOf<TApi>;
|
|
1527
1574
|
}
|
|
1575
|
+
/**
|
|
1576
|
+
* The model facts the catalog policy cascade reads: the resolve-target inputs
|
|
1577
|
+
* (`providerType ?? provider`, the request adapter, the wire model id, the
|
|
1578
|
+
* reasoning flag) plus the unverified-thinking correction applied before the
|
|
1579
|
+
* cascade. Callers holding a reduced model view — request adapters that only
|
|
1580
|
+
* need policy — supply exactly these instead of asserting a full `Model`.
|
|
1581
|
+
*/
|
|
1582
|
+
export type CatalogPolicyInputs = Pick<ModelSpec<Api>, "provider" | "providerType" | "api" | "id" | "reasoning" | "requestModelId" | "thinking">;
|
|
@@ -13,9 +13,9 @@ export declare const DEVIN_DEFAULT_BASE_URL = "https://server.codeium.com";
|
|
|
13
13
|
export declare function devinCliMetadata(apiKey: string | undefined, userJwt?: string): {
|
|
14
14
|
ideName: "devin-cli";
|
|
15
15
|
ideType: "chisel";
|
|
16
|
-
ideVersion: "3000.11.
|
|
16
|
+
ideVersion: "3000.11.205";
|
|
17
17
|
extensionName: "chisel";
|
|
18
|
-
extensionVersion: "3000.11.
|
|
18
|
+
extensionVersion: "3000.11.205";
|
|
19
19
|
locale: "en";
|
|
20
20
|
os: "darwin" | "linux" | "windows";
|
|
21
21
|
apiKey: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { FetchImpl } from "@oh-my-pi/pi-utils";
|
|
2
|
+
import type { AntigravityModelWireProfile } from "../types.js";
|
|
2
3
|
/**
|
|
3
4
|
* Build a User-Agent string that identifies as Gemini CLI to unlock higher rate limits.
|
|
4
5
|
* Uses the same format as the official Gemini CLI (v0.35+):
|
|
@@ -15,16 +16,19 @@ export declare const getGeminiCliHeaders: (modelId?: string) => {
|
|
|
15
16
|
* (and its @google/genai → google-auth-library dependency chain) into the startup
|
|
16
17
|
* parse graph.
|
|
17
18
|
*
|
|
18
|
-
* Format captured from the real 2.
|
|
19
|
-
* `antigravity/hub/2.
|
|
19
|
+
* Format captured from the real 2.26.0 `antigravity/hub` client:
|
|
20
|
+
* `antigravity/hub/2.26.0 (aidev_client; os_type=darwin; arch=arm64; cl=1005016104)`.
|
|
20
21
|
* The backend gates newer models (e.g. gemini-3.7-flash) on the client version,
|
|
21
22
|
* so the version tracks the latest Antigravity release via the update manifest
|
|
22
23
|
* (see {@link ensureAntigravityVersion}) with `DEFAULT_ANTIGRAVITY_VERSION` as
|
|
23
|
-
* the offline fallback. os_type/arch
|
|
24
|
-
*
|
|
25
|
-
*
|
|
24
|
+
* the offline fallback. os_type/arch name the native build for the host OS:
|
|
25
|
+
* each 2.26.0 installer ships one language-server build whose Go target is
|
|
26
|
+
* stamped into the header (macOS darwin/arm64, Linux linux/amd64, Windows
|
|
27
|
+
* windows/amd64; no other OS/arch builds exist); see
|
|
28
|
+
* {@link getAntigravityPlatform}. The changelist is identical across those
|
|
29
|
+
* builds. Overrides: PI_AI_ANTIGRAVITY_VERSION / _CL / _OS / _ARCH.
|
|
26
30
|
*/
|
|
27
|
-
export declare const DEFAULT_ANTIGRAVITY_VERSION = "2.
|
|
31
|
+
export declare const DEFAULT_ANTIGRAVITY_VERSION = "2.26.0";
|
|
28
32
|
/** Current Antigravity client version: env override → manifest-discovered → pinned fallback. */
|
|
29
33
|
export declare function getAntigravityVersion(): string;
|
|
30
34
|
/**
|
|
@@ -42,24 +46,39 @@ export declare function parseAntigravityManifestVersion(yamlText: string): strin
|
|
|
42
46
|
* timeout; `signal` ends this caller's wait without cancelling the lookup.
|
|
43
47
|
*/
|
|
44
48
|
export declare function ensureAntigravityVersion(fetcher?: FetchImpl, signal?: AbortSignal): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Native build the host would run. OSes without a native build report the
|
|
51
|
+
* Linux build, the closest client that exists.
|
|
52
|
+
*/
|
|
53
|
+
export declare function getAntigravityPlatform(platform?: NodeJS.Platform): {
|
|
54
|
+
os: string;
|
|
55
|
+
arch: string;
|
|
56
|
+
};
|
|
45
57
|
/** Antigravity `User-Agent` header value; rebuilt when the discovered version changes. */
|
|
46
58
|
export declare function getAntigravityUserAgent(): string;
|
|
47
59
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
* Client headers for every Antigravity Cloud Code Assist request. The native
|
|
61
|
+
* client is Go `net/http`, which offers `Accept-Encoding: gzip` and no `Accept`;
|
|
62
|
+
* pinning the encoding replaces the runtime's `gzip, deflate, br, zstd` (Bun
|
|
63
|
+
* still decompresses the gzip body). Bun always adds `Accept: *\/*` itself, so
|
|
64
|
+
* callers must not set a more specific `Accept`.
|
|
65
|
+
*/
|
|
66
|
+
export declare function getAntigravityHeaders(userAgent?: string): {
|
|
67
|
+
"User-Agent": string;
|
|
68
|
+
"Accept-Encoding": string;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Offline fallback for {@link Model.antigravityWireProfiles}: per-SKU request
|
|
72
|
+
* constants for rows that carry no discovered profile. Keyed by the routed
|
|
73
|
+
* upstream wire id (post effort-routing), not the collapsed logical id.
|
|
74
|
+
* `modelEnum` is the opaque `labels.model_enum` token; the backend accepts
|
|
75
|
+
* requests without it. Discovery (and the bundled snapshot baked from it)
|
|
76
|
+
* owns current SKUs; do not extend this table.
|
|
59
77
|
*/
|
|
60
|
-
export interface AntigravityModelWireProfile {
|
|
61
|
-
modelEnum?: string;
|
|
62
|
-
maxOutputTokens: number;
|
|
63
|
-
}
|
|
64
78
|
export declare const ANTIGRAVITY_MODEL_WIRE_PROFILES: Readonly<Record<string, AntigravityModelWireProfile>>;
|
|
65
|
-
|
|
79
|
+
/**
|
|
80
|
+
* Request constants for `wireModelId`: the first discovered profile map that
|
|
81
|
+
* lists it (callers pass the serving account's before the row's), else the
|
|
82
|
+
* offline fallback table.
|
|
83
|
+
*/
|
|
84
|
+
export declare function getAntigravityModelWireProfile(wireModelId: string, ...discovered: (Readonly<Record<string, AntigravityModelWireProfile>> | undefined)[]): AntigravityModelWireProfile | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-catalog",
|
|
3
|
-
"version": "18.
|
|
3
|
+
"version": "18.13.0",
|
|
4
4
|
"description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -93,12 +93,12 @@
|
|
|
93
93
|
"gen:proto": "bun scripts/generate-protocols.ts"
|
|
94
94
|
},
|
|
95
95
|
"dependencies": {
|
|
96
|
-
"@oh-my-pi/omptype": "18.
|
|
97
|
-
"@oh-my-pi/pi-utils": "18.
|
|
96
|
+
"@oh-my-pi/omptype": "18.13.0",
|
|
97
|
+
"@oh-my-pi/pi-utils": "18.13.0"
|
|
98
98
|
},
|
|
99
99
|
"devDependencies": {
|
|
100
100
|
"@bgotink/kdl": "0.4.0",
|
|
101
|
-
"@oh-my-pi/pi-ai": "18.
|
|
101
|
+
"@oh-my-pi/pi-ai": "18.13.0",
|
|
102
102
|
"@types/bun": "^1.3.14"
|
|
103
103
|
},
|
|
104
104
|
"engines": {
|
package/src/build.ts
CHANGED
|
@@ -19,7 +19,16 @@ import {
|
|
|
19
19
|
NO_RECURRING_TARIFF,
|
|
20
20
|
parseDatedCostCards,
|
|
21
21
|
} from "./pricing";
|
|
22
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
type AntigravityModelWireProfile,
|
|
24
|
+
type Api,
|
|
25
|
+
type EffectiveTokenCost,
|
|
26
|
+
MODEL_KINDS,
|
|
27
|
+
type Model,
|
|
28
|
+
type ModelAccountAccess,
|
|
29
|
+
type ModelCost,
|
|
30
|
+
type ModelSpec,
|
|
31
|
+
} from "./types";
|
|
23
32
|
import { cleanModelName } from "./utils";
|
|
24
33
|
|
|
25
34
|
function numberField(source: object, key: string): number | undefined {
|
|
@@ -353,6 +362,42 @@ export function applyCatalogCorrections(
|
|
|
353
362
|
}
|
|
354
363
|
}
|
|
355
364
|
|
|
365
|
+
/**
|
|
366
|
+
* Lower discovered Antigravity per-SKU output caps to the host's
|
|
367
|
+
* `max-tokens-ceiling`. The transport sends a profile's `maxOutputTokens`
|
|
368
|
+
* verbatim, so a roster value above the ceiling (Claude 4.x advertises 65,536;
|
|
369
|
+
* Cloud Code Assist 400s past 64,000, #3067) must be corrected here as the
|
|
370
|
+
* row's `maxTokens` is.
|
|
371
|
+
*/
|
|
372
|
+
function capAntigravityWireProfiles(
|
|
373
|
+
model: Pick<Model<Api>, "antigravityWireProfiles" | "accountAccess">,
|
|
374
|
+
ceiling: unknown,
|
|
375
|
+
): void {
|
|
376
|
+
if (typeof ceiling !== "number") return;
|
|
377
|
+
const cap = (
|
|
378
|
+
profiles: Readonly<Record<string, AntigravityModelWireProfile>> | undefined,
|
|
379
|
+
): Readonly<Record<string, AntigravityModelWireProfile>> | undefined => {
|
|
380
|
+
if (profiles === undefined) return undefined;
|
|
381
|
+
let capped: Record<string, AntigravityModelWireProfile> | undefined;
|
|
382
|
+
for (const [wireId, profile] of Object.entries(profiles)) {
|
|
383
|
+
if (profile.maxOutputTokens === undefined || profile.maxOutputTokens <= ceiling) continue;
|
|
384
|
+
capped ??= { ...profiles };
|
|
385
|
+
capped[wireId] = { ...profile, maxOutputTokens: ceiling };
|
|
386
|
+
}
|
|
387
|
+
return capped ?? profiles;
|
|
388
|
+
};
|
|
389
|
+
model.antigravityWireProfiles = cap(model.antigravityWireProfiles);
|
|
390
|
+
if (model.accountAccess === undefined) return;
|
|
391
|
+
let accountAccess: Record<string, ModelAccountAccess> | undefined;
|
|
392
|
+
for (const [accountKey, access] of Object.entries(model.accountAccess)) {
|
|
393
|
+
const profiles = cap(access.antigravityWireProfiles);
|
|
394
|
+
if (profiles === access.antigravityWireProfiles) continue;
|
|
395
|
+
accountAccess ??= { ...model.accountAccess };
|
|
396
|
+
accountAccess[accountKey] = { ...access, antigravityWireProfiles: profiles };
|
|
397
|
+
}
|
|
398
|
+
if (accountAccess !== undefined) model.accountAccess = accountAccess;
|
|
399
|
+
}
|
|
400
|
+
|
|
356
401
|
/**
|
|
357
402
|
* Direct first-party OpenAI Responses endpoints (api.openai.com, Azure OpenAI
|
|
358
403
|
* deployments). Gates GA computer-use detection; identity supplies the model
|
|
@@ -445,6 +490,7 @@ export function buildModel<TApi extends Api>(spec: ModelSpec<TApi>): Model<TApi>
|
|
|
445
490
|
};
|
|
446
491
|
applyCatalogAssignments(model, policy.catalog);
|
|
447
492
|
applyCatalogCorrections(model, policy.catalog);
|
|
493
|
+
capAntigravityWireProfiles(model, policy.catalog.maxTokensCeiling);
|
|
448
494
|
// Configured kinds and lifetimes replace catalog values rather than merging with them.
|
|
449
495
|
if (spec.kindConfig !== undefined) model.kind = spec.kindConfig;
|
|
450
496
|
if (spec.promptCacheConfig !== undefined) model.promptCache = { ...spec.promptCacheConfig };
|
package/src/compat/anthropic.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* pi-ai both consume these; URL matching is the one detection surface that
|
|
6
6
|
* stays in code.
|
|
7
7
|
*/
|
|
8
|
+
import { $env, logger } from "@oh-my-pi/pi-utils";
|
|
8
9
|
import { hostMatchesUrl, isBedrockRouteUrl } from "../hosts";
|
|
9
10
|
|
|
10
11
|
const OFFICIAL_ANTHROPIC_URL = "https://api.anthropic.com";
|
|
@@ -22,6 +23,52 @@ export function isOfficialAnthropicApiUrl(baseUrl?: string): boolean {
|
|
|
22
23
|
return lower === OFFICIAL_ANTHROPIC_URL || lower.startsWith(`${OFFICIAL_ANTHROPIC_URL}/`);
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
/** `anthropic-version` values this codebase knows how to speak. */
|
|
27
|
+
export const ANTHROPIC_API_VERSIONS = ["2023-06-01", "2026-10-21"] as const;
|
|
28
|
+
export type AnthropicApiVersion = (typeof ANTHROPIC_API_VERSIONS)[number];
|
|
29
|
+
|
|
30
|
+
/** Version every non-official Anthropic-compatible endpoint receives. */
|
|
31
|
+
export const LEGACY_ANTHROPIC_API_VERSION: AnthropicApiVersion = "2023-06-01";
|
|
32
|
+
|
|
33
|
+
let warnedInvalidApiVersion: string | undefined;
|
|
34
|
+
|
|
35
|
+
function isAnthropicApiVersion(value: string): value is AnthropicApiVersion {
|
|
36
|
+
return (ANTHROPIC_API_VERSIONS as readonly string[]).includes(value);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* `anthropic-version` for a request to `baseUrl`. `PI_ANTHROPIC_API_VERSION`
|
|
41
|
+
* opts the official first-party API into a newer version; every other host
|
|
42
|
+
* (Copilot, Bedrock, Foundry, Cloudflare, third-party compatibles) stays on
|
|
43
|
+
* {@link LEGACY_ANTHROPIC_API_VERSION} because those deployments gate newer
|
|
44
|
+
* versions on their own schedule (Bedrock accepts 2026-10-21 only for 4.7+).
|
|
45
|
+
* Read per call so a flipped environment takes effect without a restart.
|
|
46
|
+
*/
|
|
47
|
+
export function resolveAnthropicApiVersion(baseUrl?: string): AnthropicApiVersion {
|
|
48
|
+
if (!isOfficialAnthropicApiUrl(baseUrl)) return LEGACY_ANTHROPIC_API_VERSION;
|
|
49
|
+
const configured = $env.PI_ANTHROPIC_API_VERSION?.trim();
|
|
50
|
+
if (!configured) return LEGACY_ANTHROPIC_API_VERSION;
|
|
51
|
+
if (isAnthropicApiVersion(configured)) return configured;
|
|
52
|
+
if (warnedInvalidApiVersion !== configured) {
|
|
53
|
+
warnedInvalidApiVersion = configured;
|
|
54
|
+
logger.warn("anthropic: unsupported PI_ANTHROPIC_API_VERSION; using legacy version", {
|
|
55
|
+
configured,
|
|
56
|
+
supported: ANTHROPIC_API_VERSIONS,
|
|
57
|
+
using: LEGACY_ANTHROPIC_API_VERSION,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return LEGACY_ANTHROPIC_API_VERSION;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Whether Messages requests on `version` may carry `temperature`, `top_p`,
|
|
65
|
+
* or `top_k`. API version 2026-10-21 rejects all three with a 400, even at
|
|
66
|
+
* their default values.
|
|
67
|
+
*/
|
|
68
|
+
export function anthropicApiVersionAcceptsSamplingParams(version: AnthropicApiVersion): boolean {
|
|
69
|
+
return version === "2023-06-01";
|
|
70
|
+
}
|
|
71
|
+
|
|
25
72
|
const CLOUDFLARE_ANTHROPIC_GATEWAY_URL_MARKER = /gateway\.ai\.cloudflare\.com\/.+\/anthropic(?:\/|$)/i;
|
|
26
73
|
const VERTEX_ANTHROPIC_URL_MARKER = /aiplatform\.googleapis\.com\/.+\/publishers\/anthropic\//i;
|
|
27
74
|
const BEDROCK_ANTHROPIC_URL_MARKER = /(?:^|\/\/|\.)bedrock-runtime\.[a-z0-9-]+\.amazonaws\.com/i;
|