@oh-my-pi/pi-catalog 18.2.8 → 18.2.10
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 +18 -0
- package/dist/types/compat/auth-ids.d.ts +2 -2
- package/dist/types/compat/axes.d.ts +2 -2
- package/dist/types/compat/catalog-policy.d.ts +7 -0
- package/dist/types/compat/output-limits.d.ts +3 -0
- package/dist/types/compat/provider-ids.d.ts +1 -1
- package/dist/types/compat/tools.d.ts +5 -0
- package/dist/types/provider-models/openai-compat.d.ts +26 -0
- package/dist/types/wire/codex.d.ts +4 -3
- package/dist/types/wire/singularityapi.d.ts +29 -0
- package/package.json +4 -4
- package/src/compat/auth-ids.ts +4 -0
- package/src/compat/axes.ts +21 -2
- package/src/compat/catalog-policy.ts +28 -0
- package/src/compat/output-limits.ts +12 -0
- package/src/compat/provider-ids.ts +2 -0
- package/src/compat/resolve.ts +4 -2
- package/src/compat/rules/README.md +10 -10
- package/src/compat/rules/auth/_order.kdl +1 -1
- package/src/compat/rules/auth/singularityapi-dev.kdl +22 -0
- package/src/compat/rules/auth/singularityapi-tech.kdl +23 -0
- package/src/compat/rules/classes/gpt-oss.kdl +3 -0
- package/src/compat/rules/classes/xai.kdl +3 -3
- package/src/compat/rules/providers/amazon-bedrock.kdl +1 -1
- package/src/compat/rules/providers/anthropic.kdl +1 -1
- package/src/compat/rules/providers/cloudflare-ai-gateway.kdl +1 -1
- package/src/compat/rules/providers/commandcode.kdl +1 -1
- package/src/compat/rules/providers/cursor.kdl +1 -1
- package/src/compat/rules/providers/google-antigravity.kdl +5 -0
- package/src/compat/rules/providers/kilo.kdl +1 -1
- package/src/compat/rules/providers/litellm.kdl +1 -1
- package/src/compat/rules/providers/native-tools.kdl +4 -0
- package/src/compat/rules/providers/opencode-zen.kdl +1 -1
- package/src/compat/rules/providers/output-limits.kdl +4 -0
- package/src/compat/rules/providers/singularityapi-dev.kdl +92 -0
- package/src/compat/rules/providers/singularityapi-tech.kdl +72 -0
- package/src/compat/rules/providers/tool-free-history.kdl +6 -0
- package/src/compat/rules/providers/vercel-ai-gateway.kdl +1 -1
- package/src/compat/rules/providers/xai-oauth.kdl +8 -1
- package/src/compat/rules/providers/xai.kdl +4 -4
- package/src/compat/rules/providers/xiaomi-token-plan-cn.kdl +23 -0
- package/src/compat/rules/providers/zenmux.kdl +1 -1
- package/src/compat/rules/runtime/behavior.kdl +2 -0
- package/src/compat/rules.json +1 -12526
- package/src/compat/tools.ts +12 -0
- package/src/discovery/devin.ts +59 -36
- package/src/models.json +1 -1
- package/src/provider-models/cache-provider-id.ts +35 -0
- package/src/provider-models/descriptors.ts +4 -0
- package/src/provider-models/openai-compat.ts +159 -0
- package/src/provider-models/special.ts +1 -0
- package/src/wire/codex.ts +4 -3
- package/src/wire/singularityapi.ts +34 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.2.10] - 2026-09-22
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Updated default models for anthropic, amazon-bedrock, cloudflare-ai-gateway, kilo, litellm, opencode-zen, vercel-ai-gateway, and zenmux to claude-opus-5-5
|
|
10
|
+
- Updated default model for commandcode to claude-sonnet-5
|
|
11
|
+
|
|
12
|
+
## [18.2.9] - 2026-09-22
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- Local OpenAI-compatible backends—including llama.cpp, LM Studio, vLLM, Ollama, and custom loopback or LAN hosts—now support maxTokens values above 64k without incorrectly applying the hosted OpenAI limit.
|
|
17
|
+
- Fixed Union Alpha requests on OpenCode Go and Zen by using the correct Messages API.
|
|
18
|
+
- Updated SuperGrok’s Grok 4.7 metadata to expose its documented 500K context window and low, medium, high, and xhigh thinking levels.
|
|
19
|
+
- Fixed GPT-OSS tool interactions on Google Antigravity and Gemini CLI so function-call history is preserved correctly.
|
|
20
|
+
- Fixed Devin model discovery for Enterprise credentials by falling back to the legacy Windsurf catalog when native discovery does not return the full model list.
|
|
21
|
+
- Curated Xiaomi Token Plan (China) MiMo V2.6 metadata: context/output limits, reasoning, and image input ([#12841](https://github.com/can1357/oh-my-pi/pull/12841) by [@roboomp](https://github.com/roboomp)).
|
|
22
|
+
|
|
5
23
|
## [18.2.8] - 2026-09-21
|
|
6
24
|
|
|
7
25
|
### Added
|
|
@@ -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" | "azure" | "baseten" | "bedrock-mantle" | "cerebras" | "charm-hyper" | "cline-pass" | "cloudflare-ai-gateway" | "commandcode" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "exa" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google" | "google-antigravity" | "google-gemini-cli" | "google-vertex" | "groq" | "huggingface" | "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" | "siliconflow" | "siliconflow-cn" | "stencil" | "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" | "azure" | "baseten" | "bedrock-mantle" | "cerebras" | "charm-hyper" | "cline-pass" | "cloudflare-ai-gateway" | "commandcode" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "exa" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google" | "google-antigravity" | "google-gemini-cli" | "google-vertex" | "groq" | "huggingface" | "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" | "siliconflow" | "siliconflow-cn" | "singularityapi-dev" | "singularityapi-tech" | "stencil" | "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" | "commandcode" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "exa" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google-antigravity" | "google-gemini-cli" | "huggingface" | "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" | "siliconflow" | "siliconflow-cn" | "stencil" | "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" | "commandcode" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "exa" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google-antigravity" | "google-gemini-cli" | "huggingface" | "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" | "siliconflow" | "siliconflow-cn" | "singularityapi-dev" | "singularityapi-tech" | "stencil" | "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";
|
|
@@ -25,8 +25,8 @@ export interface AxisDef {
|
|
|
25
25
|
shape: AxisShape;
|
|
26
26
|
/** Wire axes only: records this key exists on. */
|
|
27
27
|
records?: readonly CompatRecordName[];
|
|
28
|
-
/** Closed value vocabulary for
|
|
29
|
-
values?: readonly string[];
|
|
28
|
+
/** Closed value vocabulary for scalars / arrays (strings, and booleans on flag axes). */
|
|
29
|
+
values?: readonly (string | boolean)[];
|
|
30
30
|
/**
|
|
31
31
|
* Object axes only: payload child names are literal wire JSON keys copied
|
|
32
32
|
* verbatim (`extra-body`). Default object payloads author kebab-case names
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Model } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The `catalog` axis bag authored in the KDL cascade rules for a model,
|
|
4
|
+
* memoized per distinct model. Frozen: the bag is shared across callers, so it
|
|
5
|
+
* must stay read-only — extract the value you need rather than handing it on.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveCatalogPolicy(model: Model): Readonly<Record<string, unknown>>;
|
|
@@ -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" | "azure" | "baseten" | "bedrock-mantle" | "cerebras" | "charm-hyper" | "cline-pass" | "cloudflare-ai-gateway" | "commandcode" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google" | "google-antigravity" | "google-gemini-cli" | "google-vertex" | "groq" | "huggingface" | "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" | "siliconflow" | "siliconflow-cn" | "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" | "azure" | "baseten" | "bedrock-mantle" | "cerebras" | "charm-hyper" | "cline-pass" | "cloudflare-ai-gateway" | "commandcode" | "coreweave" | "cursor" | "deepinfra" | "deepseek" | "devin" | "firepass" | "fireworks" | "github-copilot" | "gitlab-duo" | "gitlab-duo-agent" | "gmi-cloud" | "google" | "google-antigravity" | "google-gemini-cli" | "google-vertex" | "groq" | "huggingface" | "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" | "siliconflow" | "siliconflow-cn" | "singularityapi-dev" | "singularityapi-tech" | "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";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Model } from "../types.js";
|
|
2
|
+
/** Whether the transport exposes native tools that an empty caller catalog cannot disable. */
|
|
3
|
+
export declare function requiresNativeTools(model: Model): boolean;
|
|
4
|
+
/** Whether disabling tools requires a history without prior tool calls or results. */
|
|
5
|
+
export declare function requiresToolFreeHistoryForToolOptOut(model: Model): boolean;
|
|
@@ -661,3 +661,29 @@ export interface CharmHyperModelManagerConfig {
|
|
|
661
661
|
* alive by a stale bundled row.
|
|
662
662
|
*/
|
|
663
663
|
export declare function charmHyperModelManagerOptions(config?: CharmHyperModelManagerConfig): ModelManagerOptions<"openai-completions">;
|
|
664
|
+
export interface SingularityApiModelManagerConfig {
|
|
665
|
+
apiKey?: string;
|
|
666
|
+
baseUrl?: string;
|
|
667
|
+
fetch?: FetchImpl;
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* `singularityapi-dev` — SingularityAPI's pay-as-you-go universal gateway
|
|
671
|
+
* (`api.singularityapi.dev`): chat completions over a 300+ model catalog,
|
|
672
|
+
* plus image generation for the rows that advertise it.
|
|
673
|
+
* `GET /v1/models` publishes each row's per-endpoint capabilities — context
|
|
674
|
+
* window, max output tokens, and per-million pricing as 12-decimal strings —
|
|
675
|
+
* with `cache-control: no-store`, so discovery reads limits and tariffs
|
|
676
|
+
* straight off the wire and the endpoint list picks each row's transport.
|
|
677
|
+
* Rows without a reasoning vocabulary stay non-reasoning; reviewed KDL rules
|
|
678
|
+
* own the ladders the gateway leaves implicit (DeepSeek Flash/Pro, GPT-5.6
|
|
679
|
+
* flagships), because a model discovered as non-reasoning never sends a
|
|
680
|
+
* `reasoning_effort` and the gateway requires one alongside tools.
|
|
681
|
+
*/
|
|
682
|
+
export declare function singularityApiDevModelManagerOptions(config?: SingularityApiModelManagerConfig): ModelManagerOptions<Api>;
|
|
683
|
+
/**
|
|
684
|
+
* `singularityapi-tech` — SingularityAPI's slot-reserved DeepSeek lanes
|
|
685
|
+
* (`api.singularityapi.tech`). `/v1/models` answers with bare `{id}` rows and
|
|
686
|
+
* no capability metadata, so rows keep the discovery defaults and the
|
|
687
|
+
* reviewed KDL rules own the wire shape, limits patch, and effort ladder.
|
|
688
|
+
*/
|
|
689
|
+
export declare function singularityApiTechModelManagerOptions(config?: SingularityApiModelManagerConfig): ModelManagerOptions<Api>;
|
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
export declare const CODEX_BASE_URL = "https://chatgpt.com/backend-api";
|
|
5
5
|
/**
|
|
6
6
|
* Pinned OpenAI Codex client version (corresponds to @openai/codex package version).
|
|
7
|
+
* Updated from npm by `bun run check-spoofed-versions --update`.
|
|
7
8
|
*
|
|
8
9
|
* The backend version-gates model availability against this value on both
|
|
9
|
-
* `/models?client_version=` and `/responses
|
|
10
|
-
*
|
|
10
|
+
* `/models?client_version=` and `/responses`; 0.155.1 exposes GPT-6 Sol and Luna.
|
|
11
|
+
* An older pin silently hides newer SKUs from discovery.
|
|
11
12
|
*/
|
|
12
|
-
export declare const CODEX_CLIENT_VERSION = "0.
|
|
13
|
+
export declare const CODEX_CLIENT_VERSION = "0.155.1";
|
|
13
14
|
export declare const OPENAI_HEADERS: {
|
|
14
15
|
readonly BETA: "OpenAI-Beta";
|
|
15
16
|
/** Codex feature-negotiation header; values identify opt-in wire protocols. */
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SingularityAPI gateways, shared so a host migration — or a self-hosted
|
|
3
|
+
* proxy override — touches a single module.
|
|
4
|
+
*
|
|
5
|
+
* SingularityAPI ships two unrelated products behind one brand: the
|
|
6
|
+
* pay-as-you-go universal gateway (`singularityapi-dev`) and the
|
|
7
|
+
* slot-reserved DeepSeek lanes (`singularityapi-tech`). They accept disjoint
|
|
8
|
+
* keys, so each provider resolves its own canonical endpoint from here.
|
|
9
|
+
*/
|
|
10
|
+
export declare const SINGULARITYAPI_DEV_API_BASE_URL = "https://api.singularityapi.dev/v1";
|
|
11
|
+
export declare const SINGULARITYAPI_TECH_API_BASE_URL = "https://api.singularityapi.tech/v1";
|
|
12
|
+
/**
|
|
13
|
+
* Resolve a configured SingularityAPI base URL onto its gateway's `/v1`
|
|
14
|
+
* surface.
|
|
15
|
+
*
|
|
16
|
+
* Every consumer must agree on this, because they key different things off the
|
|
17
|
+
* result: discovery and inference target it, and the model-cache namespace is
|
|
18
|
+
* hashed from it. `ModelRegistry` hashes the raw configured value while the
|
|
19
|
+
* model-manager options hash a `/v1`-suffixed one, so a disagreement would
|
|
20
|
+
* split the namespace discovery writes from the one the registry reads and the
|
|
21
|
+
* authoritative roster would never come back.
|
|
22
|
+
*
|
|
23
|
+
* `canonical` names the product the caller belongs to: a blank or
|
|
24
|
+
* whitespace-only value means "not configured" and resolves to that canonical
|
|
25
|
+
* host, while anything else keeps its host and gains the `/v1` segment if it
|
|
26
|
+
* omits one. Passing the wrong product's canonical URL would silently point a
|
|
27
|
+
* provider at the other gateway, so there is no default.
|
|
28
|
+
*/
|
|
29
|
+
export declare function normalizeSingularityApiBaseUrl(baseUrl: string | undefined, canonical: string): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-catalog",
|
|
3
|
-
"version": "18.2.
|
|
3
|
+
"version": "18.2.10",
|
|
4
4
|
"description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -90,12 +90,12 @@
|
|
|
90
90
|
"gen:proto": "bun scripts/generate-protocols.ts"
|
|
91
91
|
},
|
|
92
92
|
"dependencies": {
|
|
93
|
-
"@oh-my-pi/omptype": "18.2.
|
|
94
|
-
"@oh-my-pi/pi-utils": "18.2.
|
|
93
|
+
"@oh-my-pi/omptype": "18.2.10",
|
|
94
|
+
"@oh-my-pi/pi-utils": "18.2.10"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
97
|
"@bgotink/kdl": "0.4.0",
|
|
98
|
-
"@oh-my-pi/pi-ai": "18.2.
|
|
98
|
+
"@oh-my-pi/pi-ai": "18.2.10",
|
|
99
99
|
"@types/bun": "^1.3.14"
|
|
100
100
|
},
|
|
101
101
|
"engines": {
|
package/src/compat/auth-ids.ts
CHANGED
|
@@ -67,6 +67,8 @@ export type AuthProviderId =
|
|
|
67
67
|
| "sakana"
|
|
68
68
|
| "siliconflow"
|
|
69
69
|
| "siliconflow-cn"
|
|
70
|
+
| "singularityapi-dev"
|
|
71
|
+
| "singularityapi-tech"
|
|
70
72
|
| "stencil"
|
|
71
73
|
| "synthetic"
|
|
72
74
|
| "tavily"
|
|
@@ -146,6 +148,8 @@ export type LoginProviderId =
|
|
|
146
148
|
| "sakana"
|
|
147
149
|
| "siliconflow"
|
|
148
150
|
| "siliconflow-cn"
|
|
151
|
+
| "singularityapi-dev"
|
|
152
|
+
| "singularityapi-tech"
|
|
149
153
|
| "stencil"
|
|
150
154
|
| "synthetic"
|
|
151
155
|
| "tavily"
|
package/src/compat/axes.ts
CHANGED
|
@@ -29,8 +29,8 @@ export interface AxisDef {
|
|
|
29
29
|
shape: AxisShape;
|
|
30
30
|
/** Wire axes only: records this key exists on. */
|
|
31
31
|
records?: readonly CompatRecordName[];
|
|
32
|
-
/** Closed value vocabulary for
|
|
33
|
-
values?: readonly string[];
|
|
32
|
+
/** Closed value vocabulary for scalars / arrays (strings, and booleans on flag axes). */
|
|
33
|
+
values?: readonly (string | boolean)[];
|
|
34
34
|
/**
|
|
35
35
|
* Object axes only: payload child names are literal wire JSON keys copied
|
|
36
36
|
* verbatim (`extra-body`). Default object payloads author kebab-case names
|
|
@@ -284,6 +284,25 @@ export const AXES: Readonly<Record<string, AxisDef>> = {
|
|
|
284
284
|
shape: "scalar",
|
|
285
285
|
values: ["freeform", "function"],
|
|
286
286
|
},
|
|
287
|
+
"requires-native-tools": { key: "requiresNativeTools", set: "catalog", shape: "scalar", values: [true, false] },
|
|
288
|
+
"requires-tool-free-history-for-tool-opt-out": {
|
|
289
|
+
key: "requiresToolFreeHistoryForToolOptOut",
|
|
290
|
+
set: "catalog",
|
|
291
|
+
shape: "scalar",
|
|
292
|
+
values: [true, false],
|
|
293
|
+
},
|
|
294
|
+
"preserves-max-output-tokens": {
|
|
295
|
+
key: "preservesMaxOutputTokens",
|
|
296
|
+
set: "catalog",
|
|
297
|
+
shape: "scalar",
|
|
298
|
+
values: [true, false],
|
|
299
|
+
},
|
|
300
|
+
"omit-max-output-tokens": {
|
|
301
|
+
key: "omitMaxOutputTokens",
|
|
302
|
+
set: "catalog",
|
|
303
|
+
shape: "scalar",
|
|
304
|
+
values: [true, false],
|
|
305
|
+
},
|
|
287
306
|
"clamp-context-override": { key: "clampContextOverride", set: "catalog", shape: "scalar" },
|
|
288
307
|
"context-promotion-target": { key: "contextPromotionTarget", set: "catalog", shape: "scalar" },
|
|
289
308
|
"context-window-floor": { key: "contextWindowFloor", set: "catalog", shape: "scalar" },
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { toModelSpec } from "../provider-models/bundled-references";
|
|
2
|
+
import type { Model } from "../types";
|
|
3
|
+
import { resolveModelPolicy } from "./resolve";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Rule-owned catalog-axis policy by model. Resolve once per process rather
|
|
7
|
+
* than walking the static policy cascade on every accessor call. The key
|
|
8
|
+
* mirrors the cascade target inputs — `providerType ?? provider`, api, model
|
|
9
|
+
* id, and the reasoning flag; identity-derived class/family/revision facts are
|
|
10
|
+
* a pure function of provider + id. Bounded: one entry per distinct model.
|
|
11
|
+
*/
|
|
12
|
+
const catalogPolicyCache = new Map<string, Readonly<Record<string, unknown>>>();
|
|
13
|
+
const CATALOG_POLICY_CACHE_MAX = 8192;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The `catalog` axis bag authored in the KDL cascade rules for a model,
|
|
17
|
+
* memoized per distinct model. Frozen: the bag is shared across callers, so it
|
|
18
|
+
* must stay read-only — extract the value you need rather than handing it on.
|
|
19
|
+
*/
|
|
20
|
+
export function resolveCatalogPolicy(model: Model): Readonly<Record<string, unknown>> {
|
|
21
|
+
const key = `${model.provider}\u0000${model.providerType ?? ""}\u0000${model.api}\u0000${model.id}\u0000${model.reasoning ? 1 : 0}`;
|
|
22
|
+
const cached = catalogPolicyCache.get(key);
|
|
23
|
+
if (cached !== undefined) return cached;
|
|
24
|
+
const policy = Object.freeze({ ...resolveModelPolicy(toModelSpec(model)).catalog });
|
|
25
|
+
if (catalogPolicyCache.size >= CATALOG_POLICY_CACHE_MAX) catalogPolicyCache.clear();
|
|
26
|
+
catalogPolicyCache.set(key, policy);
|
|
27
|
+
return policy;
|
|
28
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Model } from "../types";
|
|
2
|
+
import { resolveCatalogPolicy } from "./catalog-policy";
|
|
3
|
+
|
|
4
|
+
/** Whether discovery and transport policy allow preserving a caller's output cap. */
|
|
5
|
+
export function supportsOutputTokenLimit(model: Model): boolean {
|
|
6
|
+
const policy = resolveCatalogPolicy(model);
|
|
7
|
+
return (
|
|
8
|
+
model.omitMaxOutputTokens !== true &&
|
|
9
|
+
policy.omitMaxOutputTokens !== true &&
|
|
10
|
+
policy.preservesMaxOutputTokens !== false
|
|
11
|
+
);
|
|
12
|
+
}
|
package/src/compat/resolve.ts
CHANGED
|
@@ -562,7 +562,7 @@ function detectOpenAICompat(
|
|
|
562
562
|
dropThinkingWhenReasoningEffort: false,
|
|
563
563
|
nativeKimiK3Reasoning: false,
|
|
564
564
|
zaiReasoningEffortDialect: false,
|
|
565
|
-
clampOutputToModelMax:
|
|
565
|
+
clampOutputToModelMax: d.isLocalOpenAICompatBackend,
|
|
566
566
|
stripImageInput: false,
|
|
567
567
|
thinkingLoopGuard: undefined,
|
|
568
568
|
rejectRootObjectUnion: false,
|
|
@@ -765,7 +765,9 @@ function resolveOpenAIResponsesPolicy(
|
|
|
765
765
|
wireModelIdMode: isOpenRouter ? "openrouter" : "raw",
|
|
766
766
|
toolSchemaFlavor: facts.is("kimi") ? "moonshot-mfjs" : undefined,
|
|
767
767
|
alwaysSendMaxTokens: facts.is("kimi"),
|
|
768
|
-
clampOutputToModelMax:
|
|
768
|
+
clampOutputToModelMax:
|
|
769
|
+
PROXY_OPENAI_COMPAT_PROVIDERS[backendProvider] !== true &&
|
|
770
|
+
(LOCAL_OPENAI_COMPAT_PROVIDERS[backendProvider] === true || hasLocalLoopbackBaseUrl(baseUrl)),
|
|
769
771
|
supportsObfuscationOptOut: isOpenAIUrl || provider === "openai",
|
|
770
772
|
officialEndpoint: isOfficialOpenAIEndpoint(provider, baseUrl),
|
|
771
773
|
harmonyLeakMitigation: false,
|
|
@@ -152,7 +152,7 @@ discovery {
|
|
|
152
152
|
|
|
153
153
|
## Cascade grammar
|
|
154
154
|
|
|
155
|
-
A cascade document starts with `class` or `
|
|
155
|
+
A cascade document starts with `class`, `provider`, or `on-api`. Root `on-api` declares a transport contract independent of model identity and provider name. Every selector adds a conjunct to the current rule. `on` scopes by deployment provider; `on-api` scopes by request adapter, including custom provider names. Axis directives may appear directly in any permitted scope, and nested selector blocks may appear alongside them.
|
|
156
156
|
|
|
157
157
|
```kdl
|
|
158
158
|
class "gemini" {
|
|
@@ -179,15 +179,15 @@ provider "openrouter" {
|
|
|
179
179
|
|
|
180
180
|
### Selectors and nesting
|
|
181
181
|
|
|
182
|
-
| Selector | Form | Matching semantics
|
|
183
|
-
| ---------- | ---------------------------------------- |
|
|
184
|
-
| `class` | `class "id" { ... }` | Exact class ID. At document root it may contain `on`, `on-api`, `family`, `revision`, and `models`. Under `provider` it may contain `family`, `revision`, and `models`.
|
|
185
|
-
| `provider` | `provider "id" { ... }` | Exact provider ID. It is root-only and may contain `class` and `models`.
|
|
186
|
-
| `on` | `on "provider-a" "provider-b" { ... }` | One or more provider IDs, combined as OR. It is allowed only under a root `class`, and may contain `family`, `revision`, and `models`.
|
|
187
|
-
| `on-api` | `on-api "adapter-a" "adapter-b" { ... }` | One or more request adapter IDs, combined as OR.
|
|
188
|
-
| `family` | `family "id" { ... }` | Exact classified family ID. It may contain `revision` and `models`. A target with no family does not match.
|
|
189
|
-
| `revision` | `revision ">=2.5 <4" { ... }` | A non-empty, whitespace-separated conjunction of comparisons. It may contain `models`. A target with no revision does not match.
|
|
190
|
-
| `models` | `models "id" "vendor/*" { ... }` | One or more alternatives, combined as OR. It cannot contain another selector. `token="name"` matches an ASCII-case-insensitive token bounded by non-alphanumerics.
|
|
182
|
+
| Selector | Form | Matching semantics |
|
|
183
|
+
| ---------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
184
|
+
| `class` | `class "id" { ... }` | Exact class ID. At document root it may contain `on`, `on-api`, `family`, `revision`, and `models`. Under `provider` it may contain `family`, `revision`, and `models`. |
|
|
185
|
+
| `provider` | `provider "id" { ... }` | Exact provider ID. It is root-only and may contain `class` and `models`. |
|
|
186
|
+
| `on` | `on "provider-a" "provider-b" { ... }` | One or more provider IDs, combined as OR. It is allowed only under a root `class`, and may contain `family`, `revision`, and `models`. |
|
|
187
|
+
| `on-api` | `on-api "adapter-a" "adapter-b" { ... }` | One or more request adapter IDs, combined as OR. At document root it may contain `class` and `models`; under a root `class` it may contain `family`, `revision`, and `models`. |
|
|
188
|
+
| `family` | `family "id" { ... }` | Exact classified family ID. It may contain `revision` and `models`. A target with no family does not match. |
|
|
189
|
+
| `revision` | `revision ">=2.5 <4" { ... }` | A non-empty, whitespace-separated conjunction of comparisons. It may contain `models`. A target with no revision does not match. |
|
|
190
|
+
| `models` | `models "id" "vendor/*" { ... }` | One or more alternatives, combined as OR. It cannot contain another selector. `token="name"` matches an ASCII-case-insensitive token bounded by non-alphanumerics. |
|
|
191
191
|
|
|
192
192
|
Class, provider/`on`, `on-api`, and family selector values are compared exactly and case-sensitively to the structured resolve target. Revision operators are `>=`, `>`, `<=`, `<`, and `=`; operands have one to three dot-separated unsigned 8-bit components, omitted components zero.
|
|
193
193
|
|
|
@@ -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" "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"
|
|
13
|
+
"gmi-cloud" "stencil" "singularityapi-dev" "singularityapi-tech"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// SingularityAPI universal inference gateway (api.singularityapi.dev): 300+
|
|
2
|
+
// models behind one OpenAI-compatible endpoint, pay-as-you-go `sk-sapi-...`
|
|
3
|
+
// bearer keys, per-million-token tariffs published per model. SingularityAPI
|
|
4
|
+
// ships two unrelated products behind one brand — this gateway and the
|
|
5
|
+
// slot-reserved DeepSeek lanes on api.singularityapi.tech — with disjoint
|
|
6
|
+
// keys, dashboards, effort ladders, and billing, so each owns its own
|
|
7
|
+
// provider id, env var, and login flow (neither key works on the other host,
|
|
8
|
+
// verified 2026-09-22).
|
|
9
|
+
// Key validation probes the non-billable `GET /v1/models`: it answers 401
|
|
10
|
+
// `invalid_api_key` for a missing, malformed, or unknown key (verified
|
|
11
|
+
// 2026-09-22), so a bad key is rejected without spending.
|
|
12
|
+
auth "singularityapi-dev" {
|
|
13
|
+
name "SingularityAPI"
|
|
14
|
+
env "SINGULARITYAPI_DEV_API_KEY"
|
|
15
|
+
login "api-key" {
|
|
16
|
+
auth-url "https://app.singularityapi.dev"
|
|
17
|
+
instructions "Create an API key from the SingularityAPI dashboard, then paste it here"
|
|
18
|
+
prompt "Paste your SingularityAPI API key" placeholder="sk-sapi-..."
|
|
19
|
+
normalize "strip-bearer"
|
|
20
|
+
validate "models-endpoint" label="SingularityAPI" url="https://api.singularityapi.dev/v1/models"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// SingularityAPI reserved DeepSeek lanes (api.singularityapi.tech, a LiteLLM
|
|
2
|
+
// front end in front of slot-reserved lanes) — the vendor's other product,
|
|
3
|
+
// separated from api.singularityapi.dev because the two share no key, no
|
|
4
|
+
// billing model, and no effort ladder. Usage here is charged against a booked
|
|
5
|
+
// reservation slot rather than prepaid credit: a valid key with no active
|
|
6
|
+
// slot answers 403 `permission_error` ("No active lane reservation for this
|
|
7
|
+
// key", verified 2026-09-22), so login succeeds while a slot is idle and
|
|
8
|
+
// inference needs one. Keys are lane-scoped `sk-...` bearer tokens issued
|
|
9
|
+
// from the dashboard.
|
|
10
|
+
// Key validation probes the non-billable `GET /v1/models`: it answers 401
|
|
11
|
+
// for a missing, malformed, or unknown key (verified 2026-09-21), so a bad
|
|
12
|
+
// key is rejected without spending.
|
|
13
|
+
auth "singularityapi-tech" {
|
|
14
|
+
name "SingularityAPI Reserved Lanes"
|
|
15
|
+
env "SINGULARITYAPI_TECH_API_KEY"
|
|
16
|
+
login "api-key" {
|
|
17
|
+
auth-url "https://app.singularityapi.tech/compute/billing"
|
|
18
|
+
instructions "Create a key from the SingularityAPI lanes dashboard, then paste it here"
|
|
19
|
+
prompt "Paste your SingularityAPI lanes key" placeholder="sk-..."
|
|
20
|
+
normalize "strip-bearer"
|
|
21
|
+
validate "models-endpoint" label="SingularityAPI Reserved Lanes" url="https://api.singularityapi.tech/v1/models"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -5,7 +5,7 @@ class "xai" {
|
|
|
5
5
|
// on both the API and OAuth surfaces; the multiplier form tracks
|
|
6
6
|
// stencil.so price updates. Zero-cost subscription rows carry no tier.
|
|
7
7
|
on "xai" "xai-oauth" {
|
|
8
|
-
models "grok-4.3" "grok-4.5" "grok-4.6" "grok-build-0.1" "grok-4.20*" {
|
|
8
|
+
models "grok-4.3" "grok-4.5" "grok-4.6" "grok-4.7" "grok-build-0.1" "grok-4.20*" {
|
|
9
9
|
long-context-cost {
|
|
10
10
|
input-threshold 200000
|
|
11
11
|
input-threshold-inclusive #true
|
|
@@ -26,10 +26,10 @@ class "xai" {
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
// First-party xhigh-capable SKUs (grok-4.6, multi-agent) advertise xhigh.
|
|
29
|
+
// First-party xhigh-capable SKUs (grok-4.6, grok-4.7, multi-agent) advertise xhigh.
|
|
30
30
|
on "xai" "xai-oauth" {
|
|
31
31
|
family "grok" {
|
|
32
|
-
models "grok-4.6*" "grok-4.20-multi-agent*" {
|
|
32
|
+
models "grok-4.6*" "grok-4.7*" "grok-4.20-multi-agent*" {
|
|
33
33
|
thinking-efforts "minimal" "low" "medium" "high" "xhigh"
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Provider-wire compat for "amazon-bedrock"; regenerated from the frozen census using deployment contract selectors.
|
|
2
2
|
|
|
3
3
|
provider "amazon-bedrock" {
|
|
4
|
-
default-model "us.anthropic.claude-opus-
|
|
4
|
+
default-model "us.anthropic.claude-opus-5-5"
|
|
5
5
|
|
|
6
6
|
// The Converse assembler positions content blocks by wire index
|
|
7
7
|
// (`amazon-bedrock.ts`), so a block can land above text already rendered.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Provider-wire compat for "anthropic"; regenerated from the frozen census using deployment contract selectors.
|
|
2
2
|
|
|
3
3
|
provider "anthropic" {
|
|
4
|
-
default-model "claude-opus-
|
|
4
|
+
default-model "claude-opus-5-5"
|
|
5
5
|
env "ANTHROPIC_API_KEY"
|
|
6
6
|
discovery label="Anthropic"
|
|
7
7
|
web-search "anthropic"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Provider-wire compat for "cloudflare-ai-gateway"; regenerated from the frozen census using deployment contract selectors.
|
|
2
2
|
|
|
3
3
|
provider "cloudflare-ai-gateway" {
|
|
4
|
-
default-model "anthropic/claude-opus-
|
|
4
|
+
default-model "anthropic/claude-opus-5"
|
|
5
5
|
env "CLOUDFLARE_AI_GATEWAY_API_KEY"
|
|
6
6
|
discovery label="Cloudflare AI Gateway"
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// dials to a few further ids — MiniMaxAI/MiniMax-M3 and meta/muse-spark-1.3's
|
|
10
10
|
// `max` — which stay out of this change.
|
|
11
11
|
provider "commandcode" {
|
|
12
|
-
default-model "claude-sonnet-
|
|
12
|
+
default-model "claude-sonnet-5"
|
|
13
13
|
env "COMMAND_CODE_API_KEY" "COMMANDCODE_API_KEY"
|
|
14
14
|
allow-unauthenticated #true
|
|
15
15
|
dynamic-models-authoritative #true
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Provider-wire compat for "cursor"; regenerated from the frozen census using deployment contract selectors.
|
|
2
2
|
|
|
3
3
|
provider "cursor" {
|
|
4
|
-
default-model "claude-
|
|
4
|
+
default-model "claude-opus-5-high"
|
|
5
5
|
env "CURSOR_ACCESS_TOKEN"
|
|
6
6
|
discovery label="Cursor" oauth-provider="cursor" {
|
|
7
7
|
env "CURSOR_API_KEY"
|
|
@@ -17,6 +17,11 @@ provider "google-antigravity" {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
// Routed wire profiles overwrite caller caps with fixed output limits.
|
|
21
|
+
// Conservatively reject requested bounds for this provider, including
|
|
22
|
+
// logical ids whose effort routing selects a profiled wire id later.
|
|
23
|
+
preserves-max-output-tokens #false
|
|
24
|
+
|
|
20
25
|
class "anthropic" {
|
|
21
26
|
family "opus" {
|
|
22
27
|
thinking-mode "budget"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Provider-wire compat for "kilo"; regenerated from the frozen census using deployment contract selectors.
|
|
2
2
|
|
|
3
3
|
provider "kilo" {
|
|
4
|
-
default-model "anthropic/claude-opus-
|
|
4
|
+
default-model "anthropic/claude-opus-5"
|
|
5
5
|
env "KILO_API_KEY"
|
|
6
6
|
discovery label="Kilo Gateway" allow-unauthenticated=#true
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Provider-wire compat for "opencode-zen"; regenerated from the frozen census using deployment contract selectors.
|
|
2
2
|
|
|
3
3
|
provider "opencode-zen" {
|
|
4
|
-
default-model "claude-opus-
|
|
4
|
+
default-model "claude-opus-5"
|
|
5
5
|
env "OPENCODE_API_KEY"
|
|
6
6
|
dynamic-models-authoritative #true
|
|
7
7
|
|