@oh-my-pi/pi-catalog 18.14.1 → 18.15.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 +21 -0
- package/dist/types/compat/auth-ids.d.ts +2 -2
- package/dist/types/compat/provider-ids.d.ts +1 -1
- package/dist/types/model-manager.d.ts +11 -1
- package/dist/types/types.d.ts +6 -16
- package/dist/types/utils.d.ts +8 -0
- package/package.json +4 -4
- package/src/compat/auth-ids.ts +2 -0
- package/src/compat/axes.ts +13 -5
- package/src/compat/provider-ids.ts +1 -0
- package/src/compat/resolve.ts +0 -3
- package/src/compat/rules/auth/_order.kdl +1 -1
- package/src/compat/rules/auth/modular.kdl +9 -0
- package/src/compat/rules/classes/anthropic.kdl +5 -0
- package/src/compat/rules/classes/deepseek.kdl +1 -1
- package/src/compat/rules/classes/gemini.kdl +1 -1
- package/src/compat/rules/classes/xai.kdl +1 -1
- package/src/compat/rules/providers/modular.kdl +35 -0
- package/src/compat/rules/providers/sambanova.kdl +2 -0
- package/src/compat/rules.json +1 -1
- package/src/discovery/codex.ts +2 -9
- package/src/model-cache.ts +5 -4
- package/src/model-manager.ts +58 -22
- package/src/models.json +1 -1
- package/src/provider-models/openai-compat.ts +6 -20
- package/src/types.ts +3 -16
- package/src/utils.ts +18 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.15.0] - 2026-11-01
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added Modular Cloud (`modular`) as a provider: `/login modular` with an API key, models and prices from the models.dev `modular` entry, and per-model reasoning controls for MiniMax M3.1 Flash, MiniMax M3, and Gemma 4 31B ([#17334](https://github.com/can1357/oh-my-pi/pull/17334) by [@tommyjtl](https://github.com/tommyjtl))
|
|
10
|
+
- SambaNova Cloud follow-up turns now reuse the provider's prefix cache, so multi-turn conversations stop re-processing earlier context ([#17555](https://github.com/can1357/oh-my-pi/pull/17555) by [@rjuez00](https://github.com/rjuez00))
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Fixed newly discovered OpenAI-compatible models ignoring provider-reported context and output token limits ([#17561](https://github.com/can1357/oh-my-pi/pull/17561) by [@wolfiesch](https://github.com/wolfiesch))
|
|
15
|
+
|
|
16
|
+
## [18.14.2] - 2026-10-31
|
|
17
|
+
|
|
18
|
+
### Breaking Changes
|
|
19
|
+
|
|
20
|
+
- Removed `thinkingLoopGuard` from compat records; `thinking-loop-guard` is now a catalog axis that applies on every host, with `"semantic"` for Gemini, DeepSeek, and Grok and `"off"` for Claude
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Fixed GitHub Copilot Claude 5.x base models (`claude-opus-5`, `claude-opus-5.5`, `claude-sonnet-5`, `claude-sonnet-5.5`) reporting the 1M window of their `-1m` variants once the model list was read from cache; discovered limits now survive cached reads instead of reverting to bundled values ([#17481](https://github.com/can1357/oh-my-pi/issues/17481))
|
|
25
|
+
|
|
5
26
|
## [18.14.1] - 2026-10-31
|
|
6
27
|
|
|
7
28
|
### Changed
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/** Every provider with an `auth/<id>.kdl` policy. */
|
|
2
|
-
export type AuthProviderId = "abliteration" | "aiand" | "aimlapi" | "alibaba-coding-plan" | "alibaba-token-plan" | "amazon-bedrock" | "anthropic" | "apple" | "azure" | "baseten" | "bedrock-mantle" | "cerebras" | "charm-hyper" | "cline-pass" | "cloudflare-ai-gateway" | "cloudflare-workers-ai" | "commandcode" | "coralbricks" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "exa" | "factory-droid" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google" | "google-antigravity" | "google-gemini-cli" | "google-vertex" | "groq" | "helmcode" | "huggingface" | "inception" | "kagi" | "kilo" | "kimi-code" | "litellm" | "llama.cpp" | "lm-studio" | "local" | "meta" | "minimax" | "minimax-code" | "minimax-code-cn" | "mistral" | "moonshot" | "muse-code" | "nanogpt" | "novita" | "nvidia" | "ollama" | "ollama-cloud" | "openai" | "openai-codex" | "openai-codex-device" | "opencode-go" | "opencode-zen" | "openrouter" | "parallel" | "perplexity" | "qianfan" | "qwen-portal" | "sakana" | "sambanova" | "siliconflow" | "siliconflow-cn" | "singularityapi-dev" | "singularityapi-tech" | "snowflake" | "stencil" | "stepfun" | "synthetic" | "tavily" | "together" | "typesafe" | "umans" | "venice" | "vercel-ai-gateway" | "vllm" | "wafer-serverless" | "web" | "xai" | "xai-oauth" | "xiaomi" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-sgp" | "yolo-auto" | "zai" | "zai-coding-plan" | "zenmux" | "zhipu-coding-plan";
|
|
2
|
+
export type AuthProviderId = "abliteration" | "aiand" | "aimlapi" | "alibaba-coding-plan" | "alibaba-token-plan" | "amazon-bedrock" | "anthropic" | "apple" | "azure" | "baseten" | "bedrock-mantle" | "cerebras" | "charm-hyper" | "cline-pass" | "cloudflare-ai-gateway" | "cloudflare-workers-ai" | "commandcode" | "coralbricks" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "exa" | "factory-droid" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google" | "google-antigravity" | "google-gemini-cli" | "google-vertex" | "groq" | "helmcode" | "huggingface" | "inception" | "kagi" | "kilo" | "kimi-code" | "litellm" | "llama.cpp" | "lm-studio" | "local" | "meta" | "minimax" | "minimax-code" | "minimax-code-cn" | "mistral" | "modular" | "moonshot" | "muse-code" | "nanogpt" | "novita" | "nvidia" | "ollama" | "ollama-cloud" | "openai" | "openai-codex" | "openai-codex-device" | "opencode-go" | "opencode-zen" | "openrouter" | "parallel" | "perplexity" | "qianfan" | "qwen-portal" | "sakana" | "sambanova" | "siliconflow" | "siliconflow-cn" | "singularityapi-dev" | "singularityapi-tech" | "snowflake" | "stencil" | "stepfun" | "synthetic" | "tavily" | "together" | "typesafe" | "umans" | "venice" | "vercel-ai-gateway" | "vllm" | "wafer-serverless" | "web" | "xai" | "xai-oauth" | "xiaomi" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-sgp" | "yolo-auto" | "zai" | "zai-coding-plan" | "zenmux" | "zhipu-coding-plan";
|
|
3
3
|
/** Providers whose policy declares a `login` flow (the `/login` roster). */
|
|
4
|
-
export type LoginProviderId = "abliteration" | "aiand" | "alibaba-coding-plan" | "alibaba-token-plan" | "anthropic" | "baseten" | "cerebras" | "charm-hyper" | "cline-pass" | "cloudflare-ai-gateway" | "cloudflare-workers-ai" | "commandcode" | "coralbricks" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "exa" | "factory-droid" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google-antigravity" | "google-gemini-cli" | "helmcode" | "huggingface" | "inception" | "kagi" | "kilo" | "kimi-code" | "litellm" | "llama.cpp" | "lm-studio" | "meta" | "minimax-code" | "minimax-code-cn" | "moonshot" | "muse-code" | "nanogpt" | "novita" | "nvidia" | "ollama" | "ollama-cloud" | "openai-codex" | "openai-codex-device" | "opencode-go" | "opencode-zen" | "openrouter" | "parallel" | "perplexity" | "qianfan" | "qwen-portal" | "sakana" | "sambanova" | "siliconflow" | "siliconflow-cn" | "singularityapi-dev" | "singularityapi-tech" | "snowflake" | "stencil" | "stepfun" | "synthetic" | "tavily" | "together" | "typesafe" | "umans" | "venice" | "vercel-ai-gateway" | "vllm" | "wafer-serverless" | "xai" | "xai-oauth" | "xiaomi" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-sgp" | "yolo-auto" | "zai" | "zai-coding-plan" | "zenmux" | "zhipu-coding-plan";
|
|
4
|
+
export type LoginProviderId = "abliteration" | "aiand" | "alibaba-coding-plan" | "alibaba-token-plan" | "anthropic" | "baseten" | "cerebras" | "charm-hyper" | "cline-pass" | "cloudflare-ai-gateway" | "cloudflare-workers-ai" | "commandcode" | "coralbricks" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "exa" | "factory-droid" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google-antigravity" | "google-gemini-cli" | "helmcode" | "huggingface" | "inception" | "kagi" | "kilo" | "kimi-code" | "litellm" | "llama.cpp" | "lm-studio" | "meta" | "minimax-code" | "minimax-code-cn" | "modular" | "moonshot" | "muse-code" | "nanogpt" | "novita" | "nvidia" | "ollama" | "ollama-cloud" | "openai-codex" | "openai-codex-device" | "opencode-go" | "opencode-zen" | "openrouter" | "parallel" | "perplexity" | "qianfan" | "qwen-portal" | "sakana" | "sambanova" | "siliconflow" | "siliconflow-cn" | "singularityapi-dev" | "singularityapi-tech" | "snowflake" | "stencil" | "stepfun" | "synthetic" | "tavily" | "together" | "typesafe" | "umans" | "venice" | "vercel-ai-gateway" | "vllm" | "wafer-serverless" | "xai" | "xai-oauth" | "xiaomi" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-sgp" | "yolo-auto" | "zai" | "zai-coding-plan" | "zenmux" | "zhipu-coding-plan";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Every chat-model provider with a catalog entry (`default-model` in its provider rules). */
|
|
2
|
-
export type KnownProvider = "abliteration" | "aiand" | "aimlapi" | "alibaba-coding-plan" | "alibaba-token-plan" | "amazon-bedrock" | "anthropic" | "apple" | "azure" | "baseten" | "bedrock-mantle" | "cerebras" | "charm-hyper" | "cline-pass" | "cloudflare-ai-gateway" | "cloudflare-workers-ai" | "commandcode" | "coralbricks" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "factory-droid" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google" | "google-antigravity" | "google-gemini-cli" | "google-vertex" | "groq" | "helmcode" | "huggingface" | "inception" | "kilo" | "kimi-code" | "litellm" | "lm-studio" | "local" | "meta" | "minimax" | "minimax-code" | "minimax-code-cn" | "mistral" | "moonshot" | "muse-code" | "nanogpt" | "novita" | "nvidia" | "ollama" | "ollama-cloud" | "openai" | "openai-codex" | "opencode-go" | "opencode-zen" | "openrouter" | "qianfan" | "qwen-portal" | "sakana" | "sambanova" | "siliconflow" | "siliconflow-cn" | "singularityapi-dev" | "singularityapi-tech" | "snowflake" | "stepfun" | "synthetic" | "together" | "typesafe" | "umans" | "venice" | "vercel-ai-gateway" | "vllm" | "wafer-serverless" | "web" | "xai" | "xai-oauth" | "xiaomi" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-sgp" | "yolo-auto" | "zai" | "zenmux" | "zhipu-coding-plan";
|
|
2
|
+
export type KnownProvider = "abliteration" | "aiand" | "aimlapi" | "alibaba-coding-plan" | "alibaba-token-plan" | "amazon-bedrock" | "anthropic" | "apple" | "azure" | "baseten" | "bedrock-mantle" | "cerebras" | "charm-hyper" | "cline-pass" | "cloudflare-ai-gateway" | "cloudflare-workers-ai" | "commandcode" | "coralbricks" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "factory-droid" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google" | "google-antigravity" | "google-gemini-cli" | "google-vertex" | "groq" | "helmcode" | "huggingface" | "inception" | "kilo" | "kimi-code" | "litellm" | "lm-studio" | "local" | "meta" | "minimax" | "minimax-code" | "minimax-code-cn" | "mistral" | "modular" | "moonshot" | "muse-code" | "nanogpt" | "novita" | "nvidia" | "ollama" | "ollama-cloud" | "openai" | "openai-codex" | "opencode-go" | "opencode-zen" | "openrouter" | "qianfan" | "qwen-portal" | "sakana" | "sambanova" | "siliconflow" | "siliconflow-cn" | "singularityapi-dev" | "singularityapi-tech" | "snowflake" | "stepfun" | "synthetic" | "together" | "typesafe" | "umans" | "venice" | "vercel-ai-gateway" | "vllm" | "wafer-serverless" | "web" | "xai" | "xai-oauth" | "xiaomi" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-sgp" | "yolo-auto" | "zai" | "zenmux" | "zhipu-coding-plan";
|
|
@@ -129,9 +129,19 @@ export declare function createModelManager<TApi extends Api = Api, TModelsDevPay
|
|
|
129
129
|
* when at least one configured remote source did not refresh successfully.
|
|
130
130
|
*/
|
|
131
131
|
export declare function resolveProviderModels<TApi extends Api = Api, TModelsDevPayload = unknown>(options: ModelManagerOptions<TApi, TModelsDevPayload>, strategy?: ModelRefreshStrategy): Promise<ModelResolutionResult<TApi>>;
|
|
132
|
+
/**
|
|
133
|
+
* Merge policy that is part of a cache's identity in
|
|
134
|
+
* {@link fingerprintStaticModels}: `authoritative` when dynamic discovery owns
|
|
135
|
+
* the catalog, `additive` when the shared catalog may only add ids. The flags
|
|
136
|
+
* compose; snapshots written under different policies never match.
|
|
137
|
+
*/
|
|
138
|
+
export interface StaticFingerprintPolicy {
|
|
139
|
+
authoritative?: boolean;
|
|
140
|
+
additive?: boolean;
|
|
141
|
+
}
|
|
132
142
|
/**
|
|
133
143
|
* Return the versioned content identity for a static provider slice. Callers
|
|
134
144
|
* may mutate or freeze their arrays, so every call observes current content
|
|
135
145
|
* and never attaches a stale sidecar fingerprint to caller-owned data.
|
|
136
146
|
*/
|
|
137
|
-
export declare function fingerprintStaticModels<TApi extends Api>(models: readonly (ModelSpec<TApi> | Model<TApi>)[],
|
|
147
|
+
export declare function fingerprintStaticModels<TApi extends Api>(models: readonly (ModelSpec<TApi> | Model<TApi>)[], policy?: StaticFingerprintPolicy): string;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -477,8 +477,6 @@ export interface OpenAICompat {
|
|
|
477
477
|
clampOutputToModelMax?: boolean;
|
|
478
478
|
/** Strip image inputs before encoding (text-only serving of a multimodal id). */
|
|
479
479
|
stripImageInput?: boolean;
|
|
480
|
-
/** Thinking-loop watchdog guard family applied to streamed reasoning. */
|
|
481
|
-
thinkingLoopGuard?: "gemini" | "deepseek" | "xai";
|
|
482
480
|
}
|
|
483
481
|
/**
|
|
484
482
|
* Compatibility settings for anthropic-messages API.
|
|
@@ -676,8 +674,6 @@ export interface AnthropicCompat {
|
|
|
676
674
|
* contract override it. Default: 10485760.
|
|
677
675
|
*/
|
|
678
676
|
maxImagePayloadBytes?: number;
|
|
679
|
-
/** Thinking-loop watchdog guard family applied to streamed reasoning. */
|
|
680
|
-
thinkingLoopGuard?: "gemini" | "deepseek" | "xai";
|
|
681
677
|
/**
|
|
682
678
|
* Drop the enabled `thinking` config and replayed thinking blocks when the
|
|
683
679
|
* conversation is not thinking-led (a proxy contract for non-interleaved
|
|
@@ -887,8 +883,6 @@ export interface ResolvedOpenAISharedCompat {
|
|
|
887
883
|
toolSchemaFlavor?: OpenAICompat["toolSchemaFlavor"];
|
|
888
884
|
/** Strip image inputs before encoding (text-only serving of a multimodal id). */
|
|
889
885
|
stripImageInput: boolean;
|
|
890
|
-
/** Thinking-loop watchdog guard family applied to streamed reasoning. */
|
|
891
|
-
thinkingLoopGuard?: OpenAICompat["thinkingLoopGuard"];
|
|
892
886
|
/** Flatten/reject leftover root `anyOf`/`oneOf` unions in strict tool schemas (xAI's function-calling validator 400s on them). */
|
|
893
887
|
rejectRootObjectUnion: boolean;
|
|
894
888
|
/** Retry without strict tools when the host rejects a strict grammar as too large (OpenRouter-Anthropic compiled-grammar overflow). */
|
|
@@ -900,7 +894,7 @@ export interface ResolvedOpenAISharedCompat {
|
|
|
900
894
|
* `buildModel`; request handlers read fields and never detect, resolve, or
|
|
901
895
|
* allocate.
|
|
902
896
|
*/
|
|
903
|
-
export type ResolvedOpenAICompat = ResolvedOpenAISharedCompat & Required<Omit<OpenAICompat, "supportsDeveloperRole" | "supportsReasoningEffort" | "trustExplicitThinkingOnly" | "reasoningEffortMap" | "supportsReasoningParams" | "supportsReasoningSummary" | "statefulResponses" | "supportsSamplingParams" | "supportsPenaltyAndStopParams" | "thinkingFormat" | "kimiApiFormat" | "reasoningDisableMode" | "omitReasoningEffort" | "includeEncryptedReasoning" | "filterReasoningHistory" | "disableReasoningOnForcedToolChoice" | "disableReasoningOnToolChoice" | "disableReasoningWithTools" | "supportsToolChoice" | "supportsForcedToolChoice" | "supportsNamedToolChoice" | "reasoningContentField" | "mistralReasoningContentParts" | "requiresReasoningContentForToolCalls" | "requiresReasoningContentForAllAssistantTurns" | "allowsSyntheticReasoningContentForToolCalls" | "syntheticReasoningContentFallback" | "replayReasoningContent" | "qwenPreserveThinking" | "qwenTemplateReasoningEffort" | "requiresThinkingAsText" | "requiresMistralToolIds" | "requiresToolResultName" | "requiresAssistantAfterToolResult" | "requiresAssistantContentForToolCalls" | "stripDeepseekSpecialTokens" | "stripThinkingHistory" | "streamMarkupHealingPattern" | "reasoningDeltasMayBeCumulative" | "emptyLengthFinishIsContextError" | "usesOpenAIToolCallIdLimit" | "promptCacheSessionHeader" | "sessionHeader" | "supportsPromptCacheBreakpoints" | "promptCacheBreakpointTtl" | "openRouterRouting" | "isOpenRouterHost" | "supportsStrictMode" | "supportsLongPromptCacheRetention" | "alwaysSendMaxTokens" | "clampOutputToModelMax" | "wireModelIdMode" | "vercelGatewayRouting" | "extraBody" | "toolStrictMode" | "toolSchemaFlavor" | "streamFirstEventTimeoutMs" | "streamIdleTimeoutMs" | "streamRevision" | "cacheControlFormat" | "thinkingKeep" | "strictResponsesPairing" | "supportsImageDetailOriginal" | "supportsConfigurationUpdate" | "supportsSteering" | "stripImageInput" | "
|
|
897
|
+
export type ResolvedOpenAICompat = ResolvedOpenAISharedCompat & Required<Omit<OpenAICompat, "supportsDeveloperRole" | "supportsReasoningEffort" | "trustExplicitThinkingOnly" | "reasoningEffortMap" | "supportsReasoningParams" | "supportsReasoningSummary" | "statefulResponses" | "supportsSamplingParams" | "supportsPenaltyAndStopParams" | "thinkingFormat" | "kimiApiFormat" | "reasoningDisableMode" | "omitReasoningEffort" | "includeEncryptedReasoning" | "filterReasoningHistory" | "disableReasoningOnForcedToolChoice" | "disableReasoningOnToolChoice" | "disableReasoningWithTools" | "supportsToolChoice" | "supportsForcedToolChoice" | "supportsNamedToolChoice" | "reasoningContentField" | "mistralReasoningContentParts" | "requiresReasoningContentForToolCalls" | "requiresReasoningContentForAllAssistantTurns" | "allowsSyntheticReasoningContentForToolCalls" | "syntheticReasoningContentFallback" | "replayReasoningContent" | "qwenPreserveThinking" | "qwenTemplateReasoningEffort" | "requiresThinkingAsText" | "requiresMistralToolIds" | "requiresToolResultName" | "requiresAssistantAfterToolResult" | "requiresAssistantContentForToolCalls" | "stripDeepseekSpecialTokens" | "stripThinkingHistory" | "streamMarkupHealingPattern" | "reasoningDeltasMayBeCumulative" | "emptyLengthFinishIsContextError" | "usesOpenAIToolCallIdLimit" | "promptCacheSessionHeader" | "sessionHeader" | "supportsPromptCacheBreakpoints" | "promptCacheBreakpointTtl" | "openRouterRouting" | "isOpenRouterHost" | "supportsStrictMode" | "supportsLongPromptCacheRetention" | "alwaysSendMaxTokens" | "clampOutputToModelMax" | "wireModelIdMode" | "vercelGatewayRouting" | "extraBody" | "toolStrictMode" | "toolSchemaFlavor" | "streamFirstEventTimeoutMs" | "streamIdleTimeoutMs" | "streamRevision" | "cacheControlFormat" | "thinkingKeep" | "strictResponsesPairing" | "supportsImageDetailOriginal" | "supportsConfigurationUpdate" | "supportsSteering" | "stripImageInput" | "whenThinking">> & {
|
|
904
898
|
vercelGatewayRouting?: OpenAICompat["vercelGatewayRouting"];
|
|
905
899
|
extraBody?: OpenAICompat["extraBody"];
|
|
906
900
|
cacheControlFormat?: OpenAICompat["cacheControlFormat"];
|
|
@@ -992,7 +986,7 @@ export interface ResolvedOpenAIResponsesCompat extends ResolvedOpenAISharedCompa
|
|
|
992
986
|
*/
|
|
993
987
|
export type ResolvedOpenRouterCompat = ResolvedOpenAICompat & ResolvedOpenAIResponsesCompat;
|
|
994
988
|
/** Fully-resolved anthropic-messages compat view (same contract as `ResolvedOpenAICompat`). */
|
|
995
|
-
export type ResolvedAnthropicCompat = Required<Omit<AnthropicCompat, "streamIdleTimeoutMs" | "
|
|
989
|
+
export type ResolvedAnthropicCompat = Required<Omit<AnthropicCompat, "streamIdleTimeoutMs" | "bedrockMessagesApi" | "effortBeta" | "extendedCacheTtlBeta" | "disabledThinking" | "betweenToolsEffort" | "stripThinkingHistory" | "fastMode" | "maxImageDimension" | "maxImagePayloadBytes">> & {
|
|
996
990
|
/** Effort-beta override; undefined keeps the transport's legacy heuristic. */
|
|
997
991
|
effortBeta?: AnthropicCompat["effortBeta"];
|
|
998
992
|
/** Extended-cache-ttl beta opt-out; undefined sends it where a 1h breakpoint needs it. */
|
|
@@ -1016,8 +1010,6 @@ export type ResolvedAnthropicCompat = Required<Omit<AnthropicCompat, "streamIdle
|
|
|
1016
1010
|
* request builder.
|
|
1017
1011
|
*/
|
|
1018
1012
|
maxImagePayloadBytes?: number;
|
|
1019
|
-
/** Thinking-loop watchdog guard family applied to streamed reasoning. */
|
|
1020
|
-
thinkingLoopGuard?: AnthropicCompat["thinkingLoopGuard"];
|
|
1021
1013
|
/**
|
|
1022
1014
|
* Bedrock's Anthropic Messages API (see {@link AnthropicCompat.bedrockMessagesApi}).
|
|
1023
1015
|
* `true` when detected or configured; otherwise unset, so rows baked before
|
|
@@ -1116,16 +1108,13 @@ export interface GoogleCompat {
|
|
|
1116
1108
|
* {@link AnthropicCompat.maxImagePayloadBytes}).
|
|
1117
1109
|
*/
|
|
1118
1110
|
maxImagePayloadBytes?: number;
|
|
1119
|
-
/** Thinking-loop watchdog guard family applied to streamed reasoning. */
|
|
1120
|
-
thinkingLoopGuard?: "gemini" | "deepseek" | "xai";
|
|
1121
1111
|
/** See {@link BedrockCompat.supportsSamplingParams}. */
|
|
1122
1112
|
supportsSamplingParams?: boolean;
|
|
1123
1113
|
}
|
|
1124
1114
|
/** Fully-resolved google-API compat view, materialized once by `buildModel`. */
|
|
1125
|
-
export type ResolvedGoogleCompat = Required<Omit<GoogleCompat, "streamFirstEventTimeoutMs" | "streamIdleTimeoutMs" | "
|
|
1115
|
+
export type ResolvedGoogleCompat = Required<Omit<GoogleCompat, "streamFirstEventTimeoutMs" | "streamIdleTimeoutMs" | "antigravityUsageLabel" | "supportsSamplingParams" | "maxImageDimension" | "maxImagePayloadBytes">> & {
|
|
1126
1116
|
streamFirstEventTimeoutMs?: number;
|
|
1127
1117
|
streamIdleTimeoutMs?: number;
|
|
1128
|
-
thinkingLoopGuard?: GoogleCompat["thinkingLoopGuard"];
|
|
1129
1118
|
antigravityUsageLabel?: string;
|
|
1130
1119
|
supportsSamplingParams?: boolean;
|
|
1131
1120
|
maxImageDimension?: number;
|
|
@@ -1478,8 +1467,9 @@ export interface Model<TApi extends Api = Api> {
|
|
|
1478
1467
|
useResponsesLite?: boolean;
|
|
1479
1468
|
/**
|
|
1480
1469
|
* Service-tier ids the provider advertises for this model (Codex discovery
|
|
1481
|
-
* `service_tiers[].id`,
|
|
1482
|
-
*
|
|
1470
|
+
* `service_tiers[].id`, or an OpenAI-compatible `/v1/models` row's
|
|
1471
|
+
* `service_tiers`, e.g. `priority`, `ultrafast`). Absent when the provider
|
|
1472
|
+
* publishes no per-model tier list.
|
|
1483
1473
|
*/
|
|
1484
1474
|
serviceTiers?: readonly string[];
|
|
1485
1475
|
/** Preferred model to switch to when context promotion is triggered (model id or provider/id). */
|
package/dist/types/utils.d.ts
CHANGED
|
@@ -11,6 +11,14 @@ export declare function toPositiveNumber(value: unknown, fallback: number | null
|
|
|
11
11
|
/** Positive finite number, or `null` when the value is missing/non-positive. */
|
|
12
12
|
export declare function toPositiveNumberOrNull(value: unknown): number | null;
|
|
13
13
|
export declare function toBoolean(value: unknown): boolean | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Service-tier ids from a discovery row's `service_tiers` array, deduplicated
|
|
16
|
+
* in advertisement order. Entries may be codex-rs `{ id, name, description }`
|
|
17
|
+
* objects or bare id strings (OpenAI-compatible relays). Returns `undefined`
|
|
18
|
+
* when the value is not an array; an empty array is kept, since it is a
|
|
19
|
+
* statement that the model offers no optional tier.
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseServiceTierIds(value: unknown): string[] | undefined;
|
|
14
22
|
export declare function isAnthropicOAuthToken(key: string): boolean;
|
|
15
23
|
/**
|
|
16
24
|
* Normalize a model display name: drop the gateway author prefix and
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-catalog",
|
|
3
|
-
"version": "18.
|
|
3
|
+
"version": "18.15.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",
|
|
@@ -88,12 +88,12 @@
|
|
|
88
88
|
"gen:proto": "bun scripts/generate-protocols.ts"
|
|
89
89
|
},
|
|
90
90
|
"dependencies": {
|
|
91
|
-
"@oh-my-pi/omptype": "18.
|
|
92
|
-
"@oh-my-pi/pi-utils": "18.
|
|
91
|
+
"@oh-my-pi/omptype": "18.15.0",
|
|
92
|
+
"@oh-my-pi/pi-utils": "18.15.0"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
95
|
"@bgotink/kdl": "0.4.0",
|
|
96
|
-
"@oh-my-pi/pi-ai": "18.
|
|
96
|
+
"@oh-my-pi/pi-ai": "18.15.0",
|
|
97
97
|
"@types/bun": "^1.3.14"
|
|
98
98
|
},
|
|
99
99
|
"engines": {
|
package/src/compat/auth-ids.ts
CHANGED
|
@@ -53,6 +53,7 @@ export type AuthProviderId =
|
|
|
53
53
|
| "minimax-code"
|
|
54
54
|
| "minimax-code-cn"
|
|
55
55
|
| "mistral"
|
|
56
|
+
| "modular"
|
|
56
57
|
| "moonshot"
|
|
57
58
|
| "muse-code"
|
|
58
59
|
| "nanogpt"
|
|
@@ -143,6 +144,7 @@ export type LoginProviderId =
|
|
|
143
144
|
| "meta"
|
|
144
145
|
| "minimax-code"
|
|
145
146
|
| "minimax-code-cn"
|
|
147
|
+
| "modular"
|
|
146
148
|
| "moonshot"
|
|
147
149
|
| "muse-code"
|
|
148
150
|
| "nanogpt"
|
package/src/compat/axes.ts
CHANGED
|
@@ -317,11 +317,6 @@ export const AXES: Readonly<Record<string, AxisDef>> = {
|
|
|
317
317
|
"strip-image-input": wire("stripImageInput", [...OAI, "anthropic", "google"]),
|
|
318
318
|
"supports-forced-tool-choice": wire("supportsForcedToolChoice", [...OAI, "anthropic", "bedrock"]),
|
|
319
319
|
"supports-sampling-params": wire("supportsSamplingParams", [...OAI, "anthropic", "bedrock", "devin", "google"]),
|
|
320
|
-
"thinking-loop-guard": wire("thinkingLoopGuard", [...OAI, "anthropic", "google"], "scalar", [
|
|
321
|
-
"gemini",
|
|
322
|
-
"deepseek",
|
|
323
|
-
"xai",
|
|
324
|
-
]),
|
|
325
320
|
|
|
326
321
|
// ── thinking control surface ──
|
|
327
322
|
"thinking-default-level": { key: "defaultLevel", set: "thinking", shape: "scalar", values: EFFORTS },
|
|
@@ -456,6 +451,19 @@ export const AXES: Readonly<Record<string, AxisDef>> = {
|
|
|
456
451
|
shape: "scalar",
|
|
457
452
|
values: ["output", "signature"],
|
|
458
453
|
},
|
|
454
|
+
/**
|
|
455
|
+
* Stream loop guard for the model line, on every host and API (read
|
|
456
|
+
* through `loopGuardLevel` in pi-ai `utils/thinking-loop`). `semantic`
|
|
457
|
+
* adds near-duplicate and stalled-wording paragraph detection to the
|
|
458
|
+
* exact repeated-cycle check; `off` disables the guard. Unassigned: exact
|
|
459
|
+
* repeated cycles only.
|
|
460
|
+
*/
|
|
461
|
+
"thinking-loop-guard": {
|
|
462
|
+
key: "thinkingLoopGuard",
|
|
463
|
+
set: "catalog",
|
|
464
|
+
shape: "scalar",
|
|
465
|
+
values: ["off", "semantic"],
|
|
466
|
+
},
|
|
459
467
|
"delegation-bias": { key: "delegationBias", set: "catalog", shape: "scalar", values: DELEGATION_BIASES },
|
|
460
468
|
"discovery-api": { key: "discoveryApi", set: "catalog", shape: "scalar" },
|
|
461
469
|
"edit-prompt-variant": { key: "editPromptVariant", set: "catalog", shape: "scalar", values: ["full", "compact"] },
|
package/src/compat/resolve.ts
CHANGED
|
@@ -604,7 +604,6 @@ function detectOpenAICompat(
|
|
|
604
604
|
zaiReasoningEffortDialect: false,
|
|
605
605
|
clampOutputToModelMax: d.isLocalOpenAICompatBackend,
|
|
606
606
|
stripImageInput: false,
|
|
607
|
-
thinkingLoopGuard: undefined,
|
|
608
607
|
rejectRootObjectUnion: false,
|
|
609
608
|
retryWithoutStrictOnGrammarError: false,
|
|
610
609
|
supportsPromptCacheKey: false,
|
|
@@ -762,7 +761,6 @@ function resolveOpenAIResponsesPolicy(
|
|
|
762
761
|
supportsSteering: false,
|
|
763
762
|
requiresReasoningOffJuiceInstruction: false,
|
|
764
763
|
stripImageInput: false,
|
|
765
|
-
thinkingLoopGuard: undefined,
|
|
766
764
|
reasoningEffortMap: {},
|
|
767
765
|
supportsReasoningParams: true,
|
|
768
766
|
supportsSamplingParams: true,
|
|
@@ -936,7 +934,6 @@ function resolveAnthropicPolicy(
|
|
|
936
934
|
// user-authored `compat` block to override them.
|
|
937
935
|
maxImageDimension: undefined,
|
|
938
936
|
maxImagePayloadBytes: undefined,
|
|
939
|
-
thinkingLoopGuard: undefined,
|
|
940
937
|
// Present as keys so models.yml `compat` can set them; unset unless a rule assigns them.
|
|
941
938
|
stripThinkingHistory: undefined,
|
|
942
939
|
fastMode: undefined,
|
|
@@ -10,4 +10,4 @@ login-order "openai-codex" "anthropic" "zai" "zai-coding-plan" "kimi-code" "open
|
|
|
10
10
|
"qianfan" "venice" "siliconflow" "siliconflow-cn" "synthetic" "nanogpt" "wafer-serverless" "coreweave" \
|
|
11
11
|
"vercel-ai-gateway" "cloudflare-ai-gateway" "cloudflare-workers-ai" "snowflake" "litellm" "kilo" "zenmux" "opencode-zen" "opencode-go" \
|
|
12
12
|
"yolo-auto" "tavily" "kagi" "exa" "parallel" "typesafe" "ollama" "ollama-cloud" "lm-studio" "llama.cpp" "vllm" \
|
|
13
|
-
"gmi-cloud" "stencil" "singularityapi-dev" "singularityapi-tech" "coralbricks"
|
|
13
|
+
"gmi-cloud" "stencil" "singularityapi-dev" "singularityapi-tech" "coralbricks" "modular"
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
auth "modular" {
|
|
2
|
+
name "Modular"
|
|
3
|
+
login "api-key" {
|
|
4
|
+
auth-url "https://console.modular.com/api_keys"
|
|
5
|
+
instructions "Create an API key in the Modular Console"
|
|
6
|
+
prompt "Paste your Modular API key" placeholder="..."
|
|
7
|
+
validate "models-endpoint" label="Modular" url="https://api.modular.com/v1/models"
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -29,6 +29,11 @@ class "anthropic" {
|
|
|
29
29
|
// back as text (`reasoning_extraction`, issue #6093).
|
|
30
30
|
classifier-cot-extraction #true
|
|
31
31
|
thinking-replay-tokens "output"
|
|
32
|
+
// Summarized thinking repeats one progress line verbatim while long hidden
|
|
33
|
+
// reasoning runs ("Still writing the parser..." six-plus times back to
|
|
34
|
+
// back), which reads as an exact cycle. Claude has no runaway-loop failure
|
|
35
|
+
// that warrants the guard, so it never discards a turn here.
|
|
36
|
+
thinking-loop-guard "off"
|
|
32
37
|
// verified: billing matched this formula on Opus 4.7+ and Fable 5.1.
|
|
33
38
|
image-tokenization {
|
|
34
39
|
regime "anthropic-patch"
|
|
@@ -102,7 +102,7 @@ class "deepseek" {
|
|
|
102
102
|
// leaks it into content — hosted gateways, local backends, and custom
|
|
103
103
|
// providers alike. On hosts that parse it the healer sees no markup.
|
|
104
104
|
stream-markup-healing-pattern "dsml"
|
|
105
|
-
thinking-loop-guard "
|
|
105
|
+
thinking-loop-guard "semantic"
|
|
106
106
|
// V4 reasoning reaches omp as its plaintext trace on every host, and the
|
|
107
107
|
// revision pins the weights (flash 4.0 / 4.1, pro 4.0). Earlier lineages
|
|
108
108
|
// classify too coarsely to carry: `r1` also matches the R1 distills.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Provider-wire compat for "modular". Modular Cloud serves open models on an
|
|
2
|
+
// OpenAI-compatible API. The provider is catalog-only: models, prices, and
|
|
3
|
+
// limits come from the models.dev `modular` entry. Reasoning controls differ
|
|
4
|
+
// per model and were measured against the API.
|
|
5
|
+
|
|
6
|
+
provider "modular" {
|
|
7
|
+
default-model "google/gemma-4-31b-it"
|
|
8
|
+
env "MODULAR_API_KEY"
|
|
9
|
+
|
|
10
|
+
thinking-mode "effort"
|
|
11
|
+
// The API takes OpenRouter's `reasoning` object for every model, so a model
|
|
12
|
+
// models.dev adds later works without its own block: on sends
|
|
13
|
+
// `reasoning.effort`, off sends `reasoning.enabled = false`.
|
|
14
|
+
thinking-format "openrouter"
|
|
15
|
+
|
|
16
|
+
// MiniMax M3.1 Flash takes a nested `reasoning.effort` and always thinks:
|
|
17
|
+
// `reasoning.enabled = false` still returns reasoning tokens.
|
|
18
|
+
models "MiniMaxAI/MiniMax-M3.1-Flash" {
|
|
19
|
+
thinking-requires-effort #true
|
|
20
|
+
thinking-efforts "low" "medium" "high" "xhigh" "max"
|
|
21
|
+
}
|
|
22
|
+
// MiniMax M3 and Gemma 4 31B switch reasoning with `reasoning.enabled` and
|
|
23
|
+
// ignore any effort, so the ladder is one on-rung beside off: off sends
|
|
24
|
+
// `enabled: false`, and on replaces the effort with `enabled: true`.
|
|
25
|
+
models "minimax/minimax-m3" "google/gemma-4-31b-it" {
|
|
26
|
+
thinking-efforts "high"
|
|
27
|
+
when-thinking {
|
|
28
|
+
extra-body {
|
|
29
|
+
reasoning {
|
|
30
|
+
enabled #true
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -28,6 +28,8 @@ provider "sambanova" {
|
|
|
28
28
|
// (https://docs.sambanova.ai/docs/api-reference/chat-completions/create-chat-based-completion).
|
|
29
29
|
thinking-mode "effort"
|
|
30
30
|
thinking-format "openai"
|
|
31
|
+
// Replay the streamed `reasoning` field so turn-N prompts hit the gateway's prefix cache.
|
|
32
|
+
replay-reasoning-content #true
|
|
31
33
|
class "gpt-oss" {
|
|
32
34
|
thinking-efforts "low" "medium" "high"
|
|
33
35
|
thinking-upgrade-neutral #true
|