@oh-my-pi/pi-catalog 18.4.2 → 18.4.4
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 +43 -0
- package/dist/types/compat/anthropic.d.ts +6 -0
- package/dist/types/compat/types.d.ts +4 -0
- package/dist/types/hosts.d.ts +13 -0
- package/dist/types/provider-models/openai-compat.d.ts +10 -7
- package/dist/types/types.d.ts +35 -1
- package/dist/types/wire/codex.d.ts +5 -3
- package/package.json +4 -4
- package/src/build.ts +5 -0
- package/src/compat/anthropic.ts +11 -1
- package/src/compat/axes.ts +5 -0
- package/src/compat/collapse.ts +11 -2
- package/src/compat/resolve.ts +13 -3
- package/src/compat/rules/README.md +1 -1
- package/src/compat/rules/auth/commandcode.kdl +10 -4
- package/src/compat/rules/classes/anthropic.kdl +37 -3
- package/src/compat/rules/classes/gemini.kdl +11 -0
- package/src/compat/rules/classes/openai.kdl +22 -0
- package/src/compat/rules/classes/xai.kdl +6 -0
- package/src/compat/rules/providers/anthropic.kdl +6 -0
- package/src/compat/rules/providers/commandcode.kdl +223 -76
- package/src/compat/rules/providers/openai-codex.kdl +20 -2
- package/src/compat/rules/providers/openai.kdl +0 -6
- package/src/compat/rules/providers/web.kdl +8 -0
- package/src/compat/rules/runtime/behavior.kdl +7 -2
- package/src/compat/rules/taxonomy/_collapse.kdl +3 -0
- package/src/compat/rules.json +1 -1
- package/src/compat/types.ts +11 -1
- package/src/discovery/codex.ts +16 -0
- package/src/hosts.ts +47 -0
- package/src/models.json +1 -1
- package/src/provider-models/openai-compat.ts +19 -11
- package/src/types.ts +37 -1
- package/src/wire/codex.ts +5 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,49 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.4.4] - 2026-09-29
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added `compat.bedrockMessagesApi` for `anthropic-messages` models: detected from a Bedrock `/anthropic` base URL under any provider id, it drops tool `strict`, fits `metadata.user_id` to Bedrock's pattern, and enables on-demand compaction; set it in `models.yml` to opt a proxy or an `ANTHROPIC_BASE_URL` reroute in, or `false` to opt out ([#13311](https://github.com/can1357/oh-my-pi/pull/13311)).
|
|
10
|
+
- Added GPT-6.1 Sol pricing for `openai-codex` (`gpt-6.1-sol`, `gpt-6.1-sol-wm`: $2 input, $10 output, $0.10 cached input), so Codex usage shows cost instead of $0 ([#13782](https://github.com/can1357/oh-my-pi/pull/13782) by [@H4vC](https://github.com/H4vC)).
|
|
11
|
+
- Added `Model.serviceTiers`, the service tiers a provider advertises for a model; Codex discovery fills it from `service_tiers` (e.g. `priority`, `ultrafast`) ([#13782](https://github.com/can1357/oh-my-pi/pull/13782) by [@H4vC](https://github.com/H4vC)).
|
|
12
|
+
- Added the documented 922K input maximum for `openai-codex/gpt-6.1-sol` with extended context on (Codex reports a stale 872K), matching GPT-6 Astra; the default window stays 272K ([#13782](https://github.com/can1357/oh-my-pi/pull/13782) by [@H4vC](https://github.com/H4vC)).
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- Fixed `openai-codex/gpt-6.1-sol` not appearing in Codex discovery even on accounts where the Codex CLI lists it: the backend hides it from client version 0.155.1, so Codex requests now report 0.159.0, the current Codex CLI release ([#13782](https://github.com/can1357/oh-my-pi/pull/13782) by [@H4vC](https://github.com/H4vC)).
|
|
17
|
+
- Fixed on-demand compaction staying off for Claude models on the `amazon-bedrock` and `bedrock-mantle` providers when they use Bedrock's `/anthropic` routes ([#13311](https://github.com/can1357/oh-my-pi/pull/13311) by [@mustafaabidali](https://github.com/mustafaabidali)).
|
|
18
|
+
- Fixed Claude models on Bedrock's `/anthropic` routes resolving `compat.disableStrictTools: false`, although those routes reject the tool `strict` field ([#13311](https://github.com/can1357/oh-my-pi/pull/13311) by [@mustafaabidali](https://github.com/mustafaabidali)).
|
|
19
|
+
- Fixed Bedrock's FIPS (`bedrock-runtime-fips`) and AWS PrivateLink (`vpce-….vpce.amazonaws.com`) hostnames, and Mantle's documented `/v1` OpenAI base, not being recognized as Bedrock routes, which left them without native compaction and the `/anthropic` request fixes ([#13311](https://github.com/can1357/oh-my-pi/pull/13311) by [@mustafaabidali](https://github.com/mustafaabidali)).
|
|
20
|
+
- Added `supportsBetweenToolsThinking` Anthropic compat flag (`supports-between-tools-thinking` KDL axis), enabled for Claude Sonnet 5.5
|
|
21
|
+
|
|
22
|
+
## [18.4.3] - 2026-09-28
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- Added Command Code's typesafe/jev decision model for the judge role ([#13666](https://github.com/can1357/oh-my-pi/pull/13666) by [@riicodespretty](https://github.com/riicodespretty))
|
|
27
|
+
- Added Command Code's DeepSeek V4.1 Flash Fast model ([#13666](https://github.com/can1357/oh-my-pi/pull/13666) by [@riicodespretty](https://github.com/riicodespretty))
|
|
28
|
+
- Added Command Code's Claude Sonnet 5.5 model ([#13666](https://github.com/can1357/oh-my-pi/pull/13666) by [@riicodespretty](https://github.com/riicodespretty))
|
|
29
|
+
- Added `trust-forbidden=#true` for optional login `validate` checks, so a key check that answers 403 keeps the pasted key instead of rejecting it ([#13666](https://github.com/can1357/oh-my-pi/pull/13666) by [@riicodespretty](https://github.com/riicodespretty))
|
|
30
|
+
- `hosted-image #false` and `image-model #false` now remove a hosted image flag or image model that a class rule grants ([#13666](https://github.com/can1357/oh-my-pi/pull/13666) by [@riicodespretty](https://github.com/riicodespretty))
|
|
31
|
+
- Added support for Claude Sonnet 5.5 model with image and text inputs
|
|
32
|
+
- Added new compatibility rules for Anthropic Sonnet family enabling mid‑conversation system features and disabling forced tool choice
|
|
33
|
+
- Added the `web-search-model`, `hosted-image`, and `image-model` catalog axes (`Model.webSearchModel`, `hostedImage`, `imageModel`). `web-search` now comes from the model's lineage and API (GPT-5+ Responses, Claude 4+ Messages, Gemini 2+), so proxies and gateways that expose these models inherit it.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- Renamed the Codex image model `openai-codex/gpt-image-1` to `openai-codex/gpt-image-2` to match what the Codex backend runs (`gpt-image-2-codex`); saved `openai-codex/gpt-image-1` selectors resolve to the new id.
|
|
38
|
+
- Routed Command Code's 10 GPT models through the OpenAI Responses API ([#13666](https://github.com/can1357/oh-my-pi/pull/13666) by [@riicodespretty](https://github.com/riicodespretty))
|
|
39
|
+
- Command Code login now rejects a key that Command Code answers with 401; a 403 or an unreachable check keeps the pasted key, as the Command Code CLI does ([#13666](https://github.com/can1357/oh-my-pi/pull/13666) by [@riicodespretty](https://github.com/riicodespretty))
|
|
40
|
+
- Command Code GPT models no longer advertise hosted image generation or the `gpt-image-2` image model, which Command Code does not serve ([#13666](https://github.com/can1357/oh-my-pi/pull/13666) by [@riicodespretty](https://github.com/riicodespretty))
|
|
41
|
+
- Command Code Muse Spark models drop the minimal thinking level, and Muse Spark 1.3 adds max, matching the Command Code CLI ([#13666](https://github.com/can1357/oh-my-pi/pull/13666) by [@riicodespretty](https://github.com/riicodespretty))
|
|
42
|
+
- Changed Command Code prices to match the Command Code CLI: DeepSeek V4 Flash and V4 Flash Vision Exp drop from 0.22 / 0.66 to 0.15 / 0.6 per 1M tokens, Step 3.5 Flash input drops from 0.1 to 0.09, and LongCat 2.0 is no longer shown as free (0.3 / 1.2) ([#13666](https://github.com/can1357/oh-my-pi/pull/13666) by [@riicodespretty](https://github.com/riicodespretty))
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- Fixed missing thinking levels, image input, and prices for Command Code models ([#13666](https://github.com/can1357/oh-my-pi/pull/13666) by [@riicodespretty](https://github.com/riicodespretty))
|
|
47
|
+
|
|
5
48
|
## [18.4.2] - 2026-09-28
|
|
6
49
|
|
|
7
50
|
### Changed
|
|
@@ -6,6 +6,12 @@
|
|
|
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
|
+
/**
|
|
10
|
+
* Amazon Bedrock's Anthropic Messages API: the `/anthropic` path on the
|
|
11
|
+
* bedrock-runtime or bedrock-mantle endpoint. It rejects the tool `strict`
|
|
12
|
+
* field and enforces Anthropic signatures on replay.
|
|
13
|
+
*/
|
|
14
|
+
export declare function isBedrockAnthropicRoute(baseUrl?: string): boolean;
|
|
9
15
|
/**
|
|
10
16
|
* Azure AI Inference / Foundry Anthropic route
|
|
11
17
|
* (`<resource>.inference.ai.azure.com`, `<resource>.services.ai.azure.com`).
|
|
@@ -350,12 +350,15 @@ export type CompiledAuthValidation = {
|
|
|
350
350
|
maxTokensField?: "max_tokens" | "max_completion_tokens";
|
|
351
351
|
maxTokens?: number;
|
|
352
352
|
optional?: boolean;
|
|
353
|
+
/** With `optional`: a 403 also trusts the key; only a 401 rejects it. */
|
|
354
|
+
trustForbidden?: boolean;
|
|
353
355
|
} | {
|
|
354
356
|
kind: "anthropic-messages";
|
|
355
357
|
label?: string;
|
|
356
358
|
baseUrl: string;
|
|
357
359
|
model: string;
|
|
358
360
|
optional?: boolean;
|
|
361
|
+
trustForbidden?: boolean;
|
|
359
362
|
} | {
|
|
360
363
|
kind: "models-endpoint";
|
|
361
364
|
label?: string;
|
|
@@ -365,6 +368,7 @@ export type CompiledAuthValidation = {
|
|
|
365
368
|
/** Hook returning extra request headers (may throw a configuration error). */
|
|
366
369
|
headersHook?: string;
|
|
367
370
|
optional?: boolean;
|
|
371
|
+
trustForbidden?: boolean;
|
|
368
372
|
};
|
|
369
373
|
/** Paste-an-API-key login: optional browser hint, prompt, optional validation. */
|
|
370
374
|
export interface CompiledApiKeyLogin {
|
package/dist/types/hosts.d.ts
CHANGED
|
@@ -165,5 +165,18 @@ export declare function isVertexExpressOpenAIUrl(baseUrl: string): boolean;
|
|
|
165
165
|
export declare function isVertexRawPredictUrl(baseUrl: string): boolean;
|
|
166
166
|
/** Azure OpenAI deployment-scoped path (`…/deployments/<name>/…`). */
|
|
167
167
|
export declare function isAzureDeploymentsUrl(baseUrl: string): boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Amazon Bedrock API route on a bedrock-runtime or bedrock-mantle endpoint
|
|
170
|
+
* (public, FIPS, or PrivateLink hostname):
|
|
171
|
+
* - `anthropic`: the Anthropic Messages API under `/anthropic`.
|
|
172
|
+
* - `openai`: the OpenAI-compatible APIs under `/openai`, plus Mantle's
|
|
173
|
+
* documented `/v1` base (`https://bedrock-mantle.<region>.api.aws/v1`).
|
|
174
|
+
*
|
|
175
|
+
* Hostnames are parsed strictly so proxies that embed these hosts in a path
|
|
176
|
+
* do not match.
|
|
177
|
+
*/
|
|
178
|
+
export declare function isBedrockRouteUrl(baseUrl: string | undefined, route: "openai" | "anthropic"): boolean;
|
|
179
|
+
/** Amazon Bedrock's OpenAI-compatible routes; see {@link isBedrockRouteUrl}. */
|
|
180
|
+
export declare function isBedrockOpenAIUrl(baseUrl: string | undefined): boolean;
|
|
168
181
|
/** Alibaba DashScope consumer `compatible-mode` endpoint (rejects multimodal arrays for some text-only SKUs). */
|
|
169
182
|
export declare function isDashscopeCompatibleModeUrl(baseUrl: string): boolean;
|
|
@@ -648,7 +648,8 @@ export declare function modelsDevCatalogFallback(providerId: string, fetchImpl?:
|
|
|
648
648
|
* `baseUrl` overrides the Provider API base path for testing; it is
|
|
649
649
|
* normalized to the shared `/provider` root (a trailing `/v1` is stripped)
|
|
650
650
|
* so Claude ids route to the Anthropic-compatible Messages endpoint at the
|
|
651
|
-
* root
|
|
651
|
+
* root, the ten GPT ids listed in the `api-routes` table to the Responses
|
|
652
|
+
* endpoint under `/v1`, and every other id to chat completions under `/v1`.
|
|
652
653
|
*/
|
|
653
654
|
export interface CommandCodeModelManagerConfig {
|
|
654
655
|
apiKey?: string;
|
|
@@ -659,12 +660,14 @@ export interface CommandCodeModelManagerConfig {
|
|
|
659
660
|
* Builds the Command Code model manager: a mixed-protocol OpenAI-compatible
|
|
660
661
|
* discovery client. The public `/v1/models` catalog is fetched once per
|
|
661
662
|
* options instance; `mapModel` pins each row's transport from the
|
|
662
|
-
* `api-routes` table (Claude ids to `anthropic-messages`,
|
|
663
|
-
* `openai-completions`) and seeds
|
|
664
|
-
* Command Code policy (effort ladders,
|
|
665
|
-
* applied later by `buildModel` from
|
|
666
|
-
* mapper never inherits another provider's
|
|
667
|
-
* or context window.
|
|
663
|
+
* `api-routes` table (Claude ids to `anthropic-messages`, the listed GPT ids
|
|
664
|
+
* to `openai-responses`, everything else to `openai-completions`) and seeds
|
|
665
|
+
* neutral capability defaults. Reviewed Command Code policy (effort ladders,
|
|
666
|
+
* pricing, limits, modalities) is applied later by `buildModel` from
|
|
667
|
+
* `providers/commandcode.kdl` — the mapper never inherits another provider's
|
|
668
|
+
* reasoning, rates, image support, or context window. A successful fetch also
|
|
669
|
+
* appends the KDL `seed` rows (typesafe/jev), rebased onto the configured
|
|
670
|
+
* base, because `dynamicModelsAuthoritative` would prune `staticModels`.
|
|
668
671
|
*/
|
|
669
672
|
export declare function commandCodeModelManagerOptions(config?: CommandCodeModelManagerConfig): ModelManagerOptions<Api>;
|
|
670
673
|
/**
|
package/dist/types/types.d.ts
CHANGED
|
@@ -481,6 +481,15 @@ export interface AnthropicCompat {
|
|
|
481
481
|
* `tools.<n>.custom.strict: Extra inputs are not permitted`.
|
|
482
482
|
*/
|
|
483
483
|
disableStrictTools?: boolean;
|
|
484
|
+
/**
|
|
485
|
+
* The endpoint is Amazon Bedrock's Anthropic Messages API (`/anthropic` on
|
|
486
|
+
* bedrock-runtime or bedrock-mantle). Requests drop tool `strict`, fit
|
|
487
|
+
* `metadata.user_id` to Bedrock's request-metadata pattern, and may use
|
|
488
|
+
* on-demand compaction. Detected from the model `baseUrl`; set it in
|
|
489
|
+
* models.yml `compat` for a route the URL check cannot see (a proxy, an
|
|
490
|
+
* `ANTHROPIC_BASE_URL` reroute) or to `false` to opt out.
|
|
491
|
+
*/
|
|
492
|
+
bedrockMessagesApi?: boolean;
|
|
484
493
|
/**
|
|
485
494
|
* Map adaptive thinking (`thinking: { type: "adaptive" }`) to
|
|
486
495
|
* `{ type: "enabled", budget_tokens }`. Vertex AI rejects the `adaptive`
|
|
@@ -508,6 +517,13 @@ export interface AnthropicCompat {
|
|
|
508
517
|
* `input_transformations` under the thinking-binding-controls beta.
|
|
509
518
|
*/
|
|
510
519
|
supportsThinkingBindingControls?: boolean;
|
|
520
|
+
/**
|
|
521
|
+
* Whether the model replaces `thinking: { type: "disabled" }` with
|
|
522
|
+
* `thinking: { type: "between_tools" }` (Claude Sonnet 5.5). The disabled
|
|
523
|
+
* form is rejected with a 400; `between_tools` skips up-front thinking and
|
|
524
|
+
* only allows progress updates between tool calls.
|
|
525
|
+
*/
|
|
526
|
+
supportsBetweenToolsThinking?: boolean;
|
|
511
527
|
/**
|
|
512
528
|
* Whether the model accepts a forced `tool_choice` (`{ type: "any" }` or
|
|
513
529
|
* `{ type: "tool", name }`). Claude Fable/Mythos 5 reject forced tool use
|
|
@@ -804,9 +820,15 @@ export interface ResolvedOpenAIResponsesCompat extends ResolvedOpenAISharedCompa
|
|
|
804
820
|
*/
|
|
805
821
|
export type ResolvedOpenRouterCompat = ResolvedOpenAICompat & ResolvedOpenAIResponsesCompat;
|
|
806
822
|
/** Fully-resolved anthropic-messages compat view (same contract as `ResolvedOpenAICompat`). */
|
|
807
|
-
export type ResolvedAnthropicCompat = Required<Omit<AnthropicCompat, "streamIdleTimeoutMs" | "thinkingLoopGuard">> & {
|
|
823
|
+
export type ResolvedAnthropicCompat = Required<Omit<AnthropicCompat, "streamIdleTimeoutMs" | "thinkingLoopGuard" | "bedrockMessagesApi">> & {
|
|
808
824
|
/** Thinking-loop watchdog guard family applied to streamed reasoning. */
|
|
809
825
|
thinkingLoopGuard?: AnthropicCompat["thinkingLoopGuard"];
|
|
826
|
+
/**
|
|
827
|
+
* Bedrock's Anthropic Messages API (see {@link AnthropicCompat.bedrockMessagesApi}).
|
|
828
|
+
* `true` when detected or configured; otherwise unset, so rows baked before
|
|
829
|
+
* this field keep matching.
|
|
830
|
+
*/
|
|
831
|
+
bedrockMessagesApi?: boolean;
|
|
810
832
|
/**
|
|
811
833
|
* Stream-watchdog idle-timeout fallback in ms for slow reasoning hosts; 0 disables the idle watchdog.
|
|
812
834
|
* Undefined defers to `PI_STREAM_IDLE_TIMEOUT_MS`, then the legacy
|
|
@@ -986,6 +1008,12 @@ export interface Model<TApi extends Api = Api> {
|
|
|
986
1008
|
kind?: ModelKind;
|
|
987
1009
|
/** Grounding transport supported by this chat model. */
|
|
988
1010
|
webSearch?: WebSearchGrounding;
|
|
1011
|
+
/** Cheaper same-provider model to run hosted web search in this model's place (model id or provider/id). */
|
|
1012
|
+
webSearchModel?: string;
|
|
1013
|
+
/** Whether this chat model can carry the Responses `image_generation` tool itself. */
|
|
1014
|
+
hostedImage?: boolean;
|
|
1015
|
+
/** Same-provider image model to generate images in this model's place (model id or provider/id). */
|
|
1016
|
+
imageModel?: string;
|
|
989
1017
|
/**
|
|
990
1018
|
* Structured model identity resolved by the compat engine: vendor lineage
|
|
991
1019
|
* class, product family, and revision. Baked into models.json rows and
|
|
@@ -1137,6 +1165,12 @@ export interface Model<TApi extends Api = Api> {
|
|
|
1137
1165
|
useResponsesLite?: boolean;
|
|
1138
1166
|
/** Codex Code Mode restriction: model expects tools routed through a programmatic exec surface (mirrors codex-rs `tool_mode`). */
|
|
1139
1167
|
toolMode?: "code_mode_only";
|
|
1168
|
+
/**
|
|
1169
|
+
* Service-tier ids the provider advertises for this model (Codex discovery
|
|
1170
|
+
* `service_tiers[].id`, e.g. `priority`, `ultrafast`). Absent when the
|
|
1171
|
+
* provider publishes no per-model tier list.
|
|
1172
|
+
*/
|
|
1173
|
+
serviceTiers?: readonly string[];
|
|
1140
1174
|
/** Preferred model to switch to when context promotion is triggered (model id or provider/id). */
|
|
1141
1175
|
contextPromotionTarget?: string;
|
|
1142
1176
|
/** Preferred model to use only for compaction (model id or provider/id); the active session model is unchanged. */
|
|
@@ -7,10 +7,12 @@ export declare const CODEX_BASE_URL = "https://chatgpt.com/backend-api";
|
|
|
7
7
|
* Updated from npm by `bun run check-spoofed-versions --update`.
|
|
8
8
|
*
|
|
9
9
|
* The backend version-gates model availability against this value on both
|
|
10
|
-
* `/models?client_version=` and `/responses
|
|
11
|
-
*
|
|
10
|
+
* `/models?client_version=` and `/responses`, independently of a model's
|
|
11
|
+
* declared `minimal_client_version`: GPT-6.1 Sol declares 0.153.0 yet is
|
|
12
|
+
* omitted from `/models` at 0.155.1 and listed at 0.159.0. An older pin
|
|
13
|
+
* silently hides newer SKUs from discovery.
|
|
12
14
|
*/
|
|
13
|
-
export declare const CODEX_CLIENT_VERSION = "0.
|
|
15
|
+
export declare const CODEX_CLIENT_VERSION = "0.159.0";
|
|
14
16
|
export declare const OPENAI_HEADERS: {
|
|
15
17
|
readonly BETA: "OpenAI-Beta";
|
|
16
18
|
/** Codex feature-negotiation header; values identify opt-in wire protocols. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-catalog",
|
|
3
|
-
"version": "18.4.
|
|
3
|
+
"version": "18.4.4",
|
|
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.4.
|
|
97
|
-
"@oh-my-pi/pi-utils": "18.4.
|
|
96
|
+
"@oh-my-pi/omptype": "18.4.4",
|
|
97
|
+
"@oh-my-pi/pi-utils": "18.4.4"
|
|
98
98
|
},
|
|
99
99
|
"devDependencies": {
|
|
100
100
|
"@bgotink/kdl": "0.4.0",
|
|
101
|
-
"@oh-my-pi/pi-ai": "18.4.
|
|
101
|
+
"@oh-my-pi/pi-ai": "18.4.4",
|
|
102
102
|
"@types/bun": "^1.3.14"
|
|
103
103
|
},
|
|
104
104
|
"engines": {
|
package/src/build.ts
CHANGED
|
@@ -87,6 +87,11 @@ function applyCatalogAssignments<TApi extends Api>(model: Model<TApi>, catalog:
|
|
|
87
87
|
) {
|
|
88
88
|
model.webSearch = webSearch;
|
|
89
89
|
}
|
|
90
|
+
if (typeof catalog.webSearchModel === "string") model.webSearchModel = catalog.webSearchModel;
|
|
91
|
+
if (catalog.hostedImage === true) model.hostedImage = true;
|
|
92
|
+
else if (catalog.hostedImage === false) delete model.hostedImage;
|
|
93
|
+
if (typeof catalog.imageModel === "string") model.imageModel = catalog.imageModel;
|
|
94
|
+
else if (catalog.imageModel === false) delete model.imageModel;
|
|
90
95
|
const serviceTierCost = objectPayload(catalog.serviceTierCost);
|
|
91
96
|
if (serviceTierCost !== undefined) {
|
|
92
97
|
const flex = numberField(serviceTierCost, "flex");
|
package/src/compat/anthropic.ts
CHANGED
|
@@ -5,7 +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 { hostMatchesUrl } from "../hosts";
|
|
8
|
+
import { hostMatchesUrl, isBedrockRouteUrl } from "../hosts";
|
|
9
9
|
|
|
10
10
|
const OFFICIAL_ANTHROPIC_URL = "https://api.anthropic.com";
|
|
11
11
|
|
|
@@ -27,6 +27,15 @@ const VERTEX_ANTHROPIC_URL_MARKER = /aiplatform\.googleapis\.com\/.+\/publishers
|
|
|
27
27
|
const BEDROCK_ANTHROPIC_URL_MARKER = /(?:^|\/\/|\.)bedrock-runtime\.[a-z0-9-]+\.amazonaws\.com/i;
|
|
28
28
|
const AZURE_ANTHROPIC_URL_MARKER = /(?:^|\/\/|\.)[a-z0-9-]+\.(?:inference|services)\.ai\.azure\.com/i;
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Amazon Bedrock's Anthropic Messages API: the `/anthropic` path on the
|
|
32
|
+
* bedrock-runtime or bedrock-mantle endpoint. It rejects the tool `strict`
|
|
33
|
+
* field and enforces Anthropic signatures on replay.
|
|
34
|
+
*/
|
|
35
|
+
export function isBedrockAnthropicRoute(baseUrl?: string): boolean {
|
|
36
|
+
return isBedrockRouteUrl(baseUrl, "anthropic");
|
|
37
|
+
}
|
|
38
|
+
|
|
30
39
|
/**
|
|
31
40
|
* Azure AI Inference / Foundry Anthropic route
|
|
32
41
|
* (`<resource>.inference.ai.azure.com`, `<resource>.services.ai.azure.com`).
|
|
@@ -53,6 +62,7 @@ export function isAnthropicSigningProxyUrl(baseUrl?: string): boolean {
|
|
|
53
62
|
(CLOUDFLARE_ANTHROPIC_GATEWAY_URL_MARKER.test(baseUrl) ||
|
|
54
63
|
VERTEX_ANTHROPIC_URL_MARKER.test(baseUrl) ||
|
|
55
64
|
BEDROCK_ANTHROPIC_URL_MARKER.test(baseUrl))) ||
|
|
65
|
+
isBedrockAnthropicRoute(baseUrl) ||
|
|
56
66
|
isAzureAnthropicRoute(baseUrl)
|
|
57
67
|
);
|
|
58
68
|
}
|
package/src/compat/axes.ts
CHANGED
|
@@ -190,6 +190,7 @@ export const AXES: Readonly<Record<string, AxisDef>> = {
|
|
|
190
190
|
"zai-reasoning-effort-dialect": wire("zaiReasoningEffortDialect", ["openai"]),
|
|
191
191
|
|
|
192
192
|
// ── wire: anthropic-messages ──
|
|
193
|
+
"bedrock-messages-api": wire("bedrockMessagesApi", ["anthropic"]),
|
|
193
194
|
"allow-anthropic-header-overrides": wire("allowAnthropicHeaderOverrides", ["anthropic"]),
|
|
194
195
|
"disable-adaptive-thinking": wire("disableAdaptiveThinking", ["anthropic"]),
|
|
195
196
|
"disable-strict-tools": wire("disableStrictTools", ["anthropic"]),
|
|
@@ -209,6 +210,7 @@ export const AXES: Readonly<Record<string, AxisDef>> = {
|
|
|
209
210
|
"supports-mid-conversation-tool-changes": wire("supportsMidConversationToolChanges", ["anthropic"]),
|
|
210
211
|
"supports-per-message-effort": wire("supportsPerMessageEffort", ["anthropic"]),
|
|
211
212
|
"supports-server-compaction": wire("supportsServerCompaction", ["anthropic"]),
|
|
213
|
+
"supports-between-tools-thinking": wire("supportsBetweenToolsThinking", ["anthropic"]),
|
|
212
214
|
"supports-thinking-binding-controls": wire("supportsThinkingBindingControls", ["anthropic"]),
|
|
213
215
|
"supports-turn-scoped-system": wire("supportsTurnScopedSystem", ["anthropic"]),
|
|
214
216
|
|
|
@@ -343,6 +345,9 @@ export const AXES: Readonly<Record<string, AxisDef>> = {
|
|
|
343
345
|
shape: "scalar",
|
|
344
346
|
values: ["gemini", "anthropic", "codex", "xai", "openrouter", "openai"],
|
|
345
347
|
},
|
|
348
|
+
"web-search-model": { key: "webSearchModel", set: "catalog", shape: "scalar" },
|
|
349
|
+
"hosted-image": { key: "hostedImage", set: "catalog", shape: "scalar", values: [true, false] },
|
|
350
|
+
"image-model": { key: "imageModel", set: "catalog", shape: "scalar" },
|
|
346
351
|
"limits-patch": { key: "limitsPatch", set: "catalog", shape: "object" },
|
|
347
352
|
"long-context-cost": { key: "longContext", set: "catalog", shape: "object" },
|
|
348
353
|
"prompt-cache": { key: "promptCache", set: "catalog", shape: "object" },
|
package/src/compat/collapse.ts
CHANGED
|
@@ -1033,8 +1033,17 @@ function retargetCollapsedModelReferences<TSpec extends VariantSpecLike>(specs:
|
|
|
1033
1033
|
liveIdsByProvider,
|
|
1034
1034
|
);
|
|
1035
1035
|
const compactionModel = resolveCollapsedModelReference(spec.compactionModel, spec.provider, liveIdsByProvider);
|
|
1036
|
-
|
|
1037
|
-
|
|
1036
|
+
const webSearchModel = resolveCollapsedModelReference(spec.webSearchModel, spec.provider, liveIdsByProvider);
|
|
1037
|
+
const imageModel = resolveCollapsedModelReference(spec.imageModel, spec.provider, liveIdsByProvider);
|
|
1038
|
+
if (
|
|
1039
|
+
contextPromotionTarget === spec.contextPromotionTarget &&
|
|
1040
|
+
compactionModel === spec.compactionModel &&
|
|
1041
|
+
webSearchModel === spec.webSearchModel &&
|
|
1042
|
+
imageModel === spec.imageModel
|
|
1043
|
+
) {
|
|
1044
|
+
continue;
|
|
1045
|
+
}
|
|
1046
|
+
specs[index] = { ...spec, contextPromotionTarget, compactionModel, webSearchModel, imageModel };
|
|
1038
1047
|
}
|
|
1039
1048
|
}
|
|
1040
1049
|
|
package/src/compat/resolve.ts
CHANGED
|
@@ -31,7 +31,12 @@ import type {
|
|
|
31
31
|
ResolvedOpenAISharedCompat,
|
|
32
32
|
ThinkingConfig,
|
|
33
33
|
} from "../types";
|
|
34
|
-
import {
|
|
34
|
+
import {
|
|
35
|
+
isAnthropicSigningProxyUrl,
|
|
36
|
+
isAzureAnthropicRoute,
|
|
37
|
+
isBedrockAnthropicRoute,
|
|
38
|
+
isOfficialAnthropicApiUrl,
|
|
39
|
+
} from "./anthropic";
|
|
35
40
|
import { applyCompatOverrides } from "./apply";
|
|
36
41
|
import { API_COMPAT_RECORDS, AXES, type CompatRecordName } from "./axes";
|
|
37
42
|
import { hasModelScopedEffortsRule, resolveCascade } from "./cascade";
|
|
@@ -853,7 +858,9 @@ function resolveAnthropicPolicy(
|
|
|
853
858
|
const isCopilot = modelMatchesHost(spec, "githubCopilot");
|
|
854
859
|
const isZenmux = modelMatchesHost(spec, "zenmux");
|
|
855
860
|
const requiresThinkingEnabled = modelMatchesHost(spec, "moonshotNative") && facts.kimiMandatoryThinking;
|
|
856
|
-
const
|
|
861
|
+
const bedrockMessagesApi = isBedrockAnthropicRoute(baseUrl);
|
|
862
|
+
// Both routes reject the top-level tool `strict` field.
|
|
863
|
+
const rejectsStrictTools = isAzureAnthropicRoute(baseUrl) || bedrockMessagesApi;
|
|
857
864
|
const signingEndpoint = official || isCopilot || isZenmux || isAnthropicSigningProxyUrl(baseUrl);
|
|
858
865
|
const compat: ResolvedAnthropicCompat = {
|
|
859
866
|
officialEndpoint: official,
|
|
@@ -862,7 +869,9 @@ function resolveAnthropicPolicy(
|
|
|
862
869
|
supportsServerCompaction: false,
|
|
863
870
|
firstPartyProvider: false,
|
|
864
871
|
supportsOutputEffort: true,
|
|
865
|
-
disableStrictTools:
|
|
872
|
+
disableStrictTools: rejectsStrictTools,
|
|
873
|
+
// Present as a key so models.yml `compat` can set it; unset unless detected.
|
|
874
|
+
bedrockMessagesApi: bedrockMessagesApi || undefined,
|
|
866
875
|
disableAdaptiveThinking: false,
|
|
867
876
|
allowAnthropicHeaderOverrides: false,
|
|
868
877
|
supportsEagerToolInputStreaming: official,
|
|
@@ -872,6 +881,7 @@ function resolveAnthropicPolicy(
|
|
|
872
881
|
supportsMidConversationToolChanges: false,
|
|
873
882
|
supportsPerMessageEffort: false,
|
|
874
883
|
supportsThinkingBindingControls: false,
|
|
884
|
+
supportsBetweenToolsThinking: false,
|
|
875
885
|
supportsForcedToolChoice: !requiresThinkingEnabled && !facts.family("fable", "mythos"),
|
|
876
886
|
supportsSamplingParams: !facts.anthropicAdaptiveGenAtLeast("4.7"),
|
|
877
887
|
requiresToolResultId: false,
|
|
@@ -358,7 +358,7 @@ auth "anthropic" {
|
|
|
358
358
|
|
|
359
359
|
Login kinds:
|
|
360
360
|
|
|
361
|
-
- `login "api-key" { auth-url "…"; instructions "…"; prompt "…" placeholder="…"; empty-fallback "…"; normalize "strip-bearer"; validate … }` — `validate "chat-completions" base-url= model= tolerate-model-denied= max-tokens-field= max-tokens=`, `validate "anthropic-messages" base-url= model=`, or `validate "models-endpoint" url= base-url-env= headers-hook=`; all accept `label=` (error-message label, defaults to `name`)
|
|
361
|
+
- `login "api-key" { auth-url "…"; instructions "…"; prompt "…" placeholder="…"; empty-fallback "…"; normalize "strip-bearer"; validate … }` — `validate "chat-completions" base-url= model= tolerate-model-denied= max-tokens-field= max-tokens=`, `validate "anthropic-messages" base-url= model=`, or `validate "models-endpoint" url= base-url-env= headers-hook=`; all accept `label=` (error-message label, defaults to `name`), `optional=#true` (only auth failures reject), and `trust-forbidden=#true` (requires `optional=#true`; a 403 no longer rejects, so only a 401 does).
|
|
362
362
|
- `login "oauth-code" { … }` as above; `token`/`refresh` `params` values may use `{code}`, `{state}`, `{redirect_uri}`, `{code_verifier}`, `{client_id}`, `{client_secret}`, `{refresh_token}`, `{scope}`; the standard grant parameters are sent unless `standard=#false`.
|
|
363
363
|
- `login "device-code" { client-id …; base-url "…"; scopes …; headers-hook "…"; device url="{base}/…" body="form" { params {…} headers {…} }; token url="…" url-hook="…"; response user-code= device-code= verification-uri= verification-uri-complete= interval= expires-in=; instructions "Enter code: {user_code}"; credential {…}; userinfo …; after-exchange hook=… }`.
|
|
364
364
|
- `login "custom" hook="name"` — the whole flow is a named `@oh-my-pi/pi-ai` hook (`src/registry/hooks/custom.ts`).
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
1
|
+
// `/provider/v1/models` is public: it answers 200 to a missing or bogus key.
|
|
2
|
+
// Login therefore validates against `GET /alpha/whoami`, the identity route
|
|
3
|
+
// that command-code@1.67.0 calls. That route answers 401 to a bad key
|
|
4
|
+
// (verified 2026-09-29) and bills nothing. It is not in the Provider API
|
|
5
|
+
// docs, so the probe is optional and only a 401 rejects the key, matching
|
|
6
|
+
// `validateCommandApiKey` in command-code@1.67.0. A 403, a 404, a 5xx, or a
|
|
7
|
+
// moved route trusts the pasted key.
|
|
8
|
+
// The `models-endpoint` probe only checks for a 2xx answer, so this identity
|
|
9
|
+
// route serves as its target.
|
|
5
10
|
auth "commandcode" {
|
|
6
11
|
name "Command Code"
|
|
7
12
|
env "COMMAND_CODE_API_KEY" "COMMANDCODE_API_KEY"
|
|
@@ -9,5 +14,6 @@ auth "commandcode" {
|
|
|
9
14
|
auth-url "https://commandcode.ai/studio"
|
|
10
15
|
instructions "Create or copy a Provider API key from Command Code Studio"
|
|
11
16
|
prompt "Paste your Command Code API key" placeholder="user_..."
|
|
17
|
+
validate "models-endpoint" label="Command Code" url="https://api.commandcode.ai/alpha/whoami" optional=#true trust-forbidden=#true
|
|
12
18
|
}
|
|
13
19
|
}
|
|
@@ -7,11 +7,11 @@ class "anthropic" {
|
|
|
7
7
|
thinking-prefix-binding #true
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
|
-
// On-demand compaction (compact-2026-09-04)
|
|
11
|
-
//
|
|
10
|
+
// On-demand compaction (compact-2026-09-04) works on the Claude API, Vertex,
|
|
11
|
+
// and Amazon Bedrock's `/anthropic` routes, not Bedrock Converse.
|
|
12
12
|
// Foundry / Claude Platform on AWS are first-party Anthropic routes whose
|
|
13
13
|
// effective URLs are checked at request time.
|
|
14
|
-
on "anthropic" "google-vertex" {
|
|
14
|
+
on "anthropic" "google-vertex" "amazon-bedrock" "bedrock-mantle" {
|
|
15
15
|
family "fable" {
|
|
16
16
|
revision ">=5" {
|
|
17
17
|
supports-server-compaction #true
|
|
@@ -61,6 +61,21 @@ class "anthropic" {
|
|
|
61
61
|
supports-forced-tool-choice #false
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
+
// Sonnet 5.5 rejects forced tool selection like Opus 5.5 (400 `tool_choice:
|
|
65
|
+
// type "tool" and "any" are not supported for this model`); upper-bounded
|
|
66
|
+
// for the same reason as the Opus rule above.
|
|
67
|
+
// https://platform.claude.com/docs/en/models/sonnet-5-5/whats-new-sonnet-5-5
|
|
68
|
+
family "sonnet" {
|
|
69
|
+
revision ">=5.5 <6" {
|
|
70
|
+
supports-forced-tool-choice #false
|
|
71
|
+
// `thinking: {type: "disabled"}` is a 400; `between_tools` is the
|
|
72
|
+
// lowest thinking setting.
|
|
73
|
+
// https://platform.claude.com/docs/en/models/sonnet-5-5/migration-guide#turn-off-up-front-thinking
|
|
74
|
+
supports-between-tools-thinking #true
|
|
75
|
+
// Signed thinking is bound to the exact preceding conversation.
|
|
76
|
+
thinking-prefix-binding #true
|
|
77
|
+
}
|
|
78
|
+
}
|
|
64
79
|
on "anthropic" "cloudflare-ai-gateway" "google-vertex" {
|
|
65
80
|
family "fable" {
|
|
66
81
|
revision ">=5" {
|
|
@@ -87,6 +102,15 @@ class "anthropic" {
|
|
|
87
102
|
supports-thinking-binding-controls #true
|
|
88
103
|
}
|
|
89
104
|
}
|
|
105
|
+
family "sonnet" {
|
|
106
|
+
revision ">=5.5" {
|
|
107
|
+
supports-mid-conversation-system #true
|
|
108
|
+
supports-mid-conversation-tool-changes #true
|
|
109
|
+
supports-turn-scoped-system #true
|
|
110
|
+
supports-per-message-effort #true
|
|
111
|
+
supports-thinking-binding-controls #true
|
|
112
|
+
}
|
|
113
|
+
}
|
|
90
114
|
family "opus" {
|
|
91
115
|
revision ">=4.8" {
|
|
92
116
|
supports-mid-conversation-system #true
|
|
@@ -369,3 +393,13 @@ class "anthropic" {
|
|
|
369
393
|
antigravity-usage-label "true"
|
|
370
394
|
}
|
|
371
395
|
}
|
|
396
|
+
|
|
397
|
+
// Claude 4+ ships the server-side `web_search` tool on any Messages-compatible host.
|
|
398
|
+
class "anthropic" {
|
|
399
|
+
on-api "anthropic-messages" {
|
|
400
|
+
revision ">=4" {
|
|
401
|
+
web-search "anthropic"
|
|
402
|
+
web-search-model "claude-haiku-4-5"
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
@@ -107,3 +107,14 @@ class "gemini" {
|
|
|
107
107
|
|
|
108
108
|
thinking-loop-guard "gemini"
|
|
109
109
|
}
|
|
110
|
+
|
|
111
|
+
// Google Search grounding is a Gemini 2+ lineage capability on every Gemini transport.
|
|
112
|
+
class "gemini" {
|
|
113
|
+
on-api "google-generative-ai" "google-gemini-cli" {
|
|
114
|
+
revision ">=2" {
|
|
115
|
+
web-search "gemini"
|
|
116
|
+
web-search-model "gemini-2.5-flash"
|
|
117
|
+
image-model "gemini-3-pro-image"
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -59,3 +59,25 @@ class "openai" {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
+
|
|
63
|
+
// Hosted Responses tools are a GPT-5+ lineage capability on any
|
|
64
|
+
// Responses-compatible host, so proxies exposing these ids inherit them. The
|
|
65
|
+
// swap targets resolve on the same provider only; when a host lacks them the
|
|
66
|
+
// session model runs the tool itself.
|
|
67
|
+
class "openai" {
|
|
68
|
+
on-api "openai-responses" {
|
|
69
|
+
revision ">=5" {
|
|
70
|
+
web-search "openai"
|
|
71
|
+
web-search-model "gpt-5.6-luna"
|
|
72
|
+
hosted-image #true
|
|
73
|
+
image-model "gpt-image-2"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
on-api "openai-codex-responses" {
|
|
77
|
+
revision ">=5" {
|
|
78
|
+
web-search-model "gpt-5.6-luna"
|
|
79
|
+
hosted-image #true
|
|
80
|
+
image-model "gpt-image-2"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -28,6 +28,12 @@ provider "anthropic" {
|
|
|
28
28
|
cost input=3 output=15 cache-read=0.3 cache-write=3.75
|
|
29
29
|
limits context=1000000 max-tokens=128000
|
|
30
30
|
}
|
|
31
|
+
model "claude-sonnet-5-5" name="Claude Sonnet 5.5" {
|
|
32
|
+
reasoning #true
|
|
33
|
+
input "text" "image"
|
|
34
|
+
cost input=2 output=10 cache-read=0.2 cache-write=2.5
|
|
35
|
+
limits context=1000000 max-tokens=128000
|
|
36
|
+
}
|
|
31
37
|
model "claude-fable-5" name="Claude Fable 5" {
|
|
32
38
|
reasoning #true
|
|
33
39
|
input "text" "image"
|