@oh-my-pi/pi-catalog 15.10.11

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.
Files changed (90) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/types/build.d.ts +3 -0
  3. package/dist/types/compat/anthropic.d.ts +11 -0
  4. package/dist/types/compat/apply.d.ts +7 -0
  5. package/dist/types/compat/openai.d.ts +21 -0
  6. package/dist/types/discovery/antigravity.d.ts +61 -0
  7. package/dist/types/discovery/codex.d.ts +38 -0
  8. package/dist/types/discovery/cursor-gen/agent_pb.d.ts +13022 -0
  9. package/dist/types/discovery/cursor.d.ts +23 -0
  10. package/dist/types/discovery/gemini.d.ts +25 -0
  11. package/dist/types/discovery/index.d.ts +4 -0
  12. package/dist/types/discovery/openai-compatible.d.ts +72 -0
  13. package/dist/types/effort.d.ts +9 -0
  14. package/dist/types/fireworks-model-id.d.ts +10 -0
  15. package/dist/types/hosts.d.ts +128 -0
  16. package/dist/types/identity/bundled.d.ts +6 -0
  17. package/dist/types/identity/classify.d.ts +45 -0
  18. package/dist/types/identity/equivalence.d.ts +46 -0
  19. package/dist/types/identity/family.d.ts +45 -0
  20. package/dist/types/identity/id.d.ts +12 -0
  21. package/dist/types/identity/index.d.ts +9 -0
  22. package/dist/types/identity/markers.d.ts +4 -0
  23. package/dist/types/identity/priority.d.ts +1 -0
  24. package/dist/types/identity/reference.d.ts +22 -0
  25. package/dist/types/identity/selection.d.ts +20 -0
  26. package/dist/types/index.d.ts +15 -0
  27. package/dist/types/model-cache.d.ts +17 -0
  28. package/dist/types/model-manager.d.ts +64 -0
  29. package/dist/types/model-thinking.d.ts +67 -0
  30. package/dist/types/models.d.ts +12 -0
  31. package/dist/types/provider-models/bundled-references.d.ts +11 -0
  32. package/dist/types/provider-models/descriptor-types.d.ts +74 -0
  33. package/dist/types/provider-models/descriptors.d.ts +384 -0
  34. package/dist/types/provider-models/discovery-constants.d.ts +11 -0
  35. package/dist/types/provider-models/google.d.ts +27 -0
  36. package/dist/types/provider-models/index.d.ts +6 -0
  37. package/dist/types/provider-models/ollama.d.ts +9 -0
  38. package/dist/types/provider-models/openai-compat.d.ts +385 -0
  39. package/dist/types/provider-models/special.d.ts +16 -0
  40. package/dist/types/types.d.ts +405 -0
  41. package/dist/types/utils.d.ts +5 -0
  42. package/dist/types/wire/codex.d.ts +26 -0
  43. package/dist/types/wire/gemini-headers.d.ts +18 -0
  44. package/dist/types/wire/github-copilot.d.ts +18 -0
  45. package/package.json +100 -0
  46. package/src/build.ts +40 -0
  47. package/src/compat/anthropic.ts +67 -0
  48. package/src/compat/apply.ts +15 -0
  49. package/src/compat/openai.ts +365 -0
  50. package/src/discovery/antigravity.ts +261 -0
  51. package/src/discovery/codex.ts +371 -0
  52. package/src/discovery/cursor-gen/agent_pb.ts +15274 -0
  53. package/src/discovery/cursor.ts +307 -0
  54. package/src/discovery/gemini.ts +249 -0
  55. package/src/discovery/index.ts +4 -0
  56. package/src/discovery/openai-compatible.ts +224 -0
  57. package/src/effort.ts +16 -0
  58. package/src/fireworks-model-id.ts +30 -0
  59. package/src/hosts.ts +114 -0
  60. package/src/identity/bundled.ts +38 -0
  61. package/src/identity/classify.ts +141 -0
  62. package/src/identity/equivalence.ts +870 -0
  63. package/src/identity/family.ts +88 -0
  64. package/src/identity/id.ts +81 -0
  65. package/src/identity/index.ts +9 -0
  66. package/src/identity/markers.ts +49 -0
  67. package/src/identity/priority.ts +56 -0
  68. package/src/identity/reference.ts +134 -0
  69. package/src/identity/selection.ts +65 -0
  70. package/src/index.ts +15 -0
  71. package/src/model-cache.ts +132 -0
  72. package/src/model-manager.ts +472 -0
  73. package/src/model-thinking.ts +407 -0
  74. package/src/models.json +75308 -0
  75. package/src/models.json.d.ts +9 -0
  76. package/src/models.ts +64 -0
  77. package/src/provider-models/bundled-references.ts +54 -0
  78. package/src/provider-models/descriptor-types.ts +79 -0
  79. package/src/provider-models/descriptors.ts +456 -0
  80. package/src/provider-models/discovery-constants.ts +11 -0
  81. package/src/provider-models/google.ts +105 -0
  82. package/src/provider-models/index.ts +6 -0
  83. package/src/provider-models/ollama.ts +154 -0
  84. package/src/provider-models/openai-compat.ts +3106 -0
  85. package/src/provider-models/special.ts +67 -0
  86. package/src/types.ts +470 -0
  87. package/src/utils.ts +27 -0
  88. package/src/wire/codex.ts +43 -0
  89. package/src/wire/gemini-headers.ts +41 -0
  90. package/src/wire/github-copilot.ts +72 -0
@@ -0,0 +1,23 @@
1
+ import type { ModelSpec } from "../types";
2
+ /**
3
+ * Options for fetching dynamic Cursor models from `GetUsableModels`.
4
+ */
5
+ export interface CursorModelDiscoveryOptions {
6
+ /** Cursor access token used for bearer authentication. */
7
+ apiKey: string;
8
+ /** Optional Cursor API base URL override. */
9
+ baseUrl?: string;
10
+ /** Optional client version override sent as `x-cursor-client-version`. */
11
+ clientVersion?: string;
12
+ /** Optional request timeout in milliseconds. */
13
+ timeoutMs?: number;
14
+ /** Optional list of custom Cursor model ids to include in request context. */
15
+ customModelIds?: string[];
16
+ }
17
+ /**
18
+ * Fetches Cursor models through `GetUsableModels` and normalizes them into canonical model entries.
19
+ *
20
+ * Returns `null` on request/decode failures.
21
+ * Returns `[]` only when the endpoint responds successfully with no usable models.
22
+ */
23
+ export declare function fetchCursorUsableModels(options: CursorModelDiscoveryOptions): Promise<ModelSpec<"cursor-agent">[] | null>;
@@ -0,0 +1,25 @@
1
+ import type { FetchImpl, ModelSpec } from "../types";
2
+ /**
3
+ * Configuration for Google Generative AI model discovery.
4
+ */
5
+ export interface GeminiDiscoveryOptions {
6
+ /** API key for the Google Generative AI public endpoint. */
7
+ apiKey: string;
8
+ /** Optional endpoint override for testing or proxying. */
9
+ baseUrl?: string;
10
+ /** Optional requested page size for model listing. */
11
+ pageSize?: number;
12
+ /** Maximum number of pages to request before stopping pagination. */
13
+ maxPages?: number;
14
+ /** Optional abort signal for HTTP requests. */
15
+ signal?: AbortSignal;
16
+ /** Optional fetch implementation override for tests. */
17
+ fetch?: FetchImpl;
18
+ }
19
+ /**
20
+ * Fetches and normalizes Google Generative AI models from the public models endpoint.
21
+ *
22
+ * Returns `null` on transport/protocol failures.
23
+ * Returns `[]` only when the endpoint responds successfully with no usable models.
24
+ */
25
+ export declare function fetchGeminiModels(options: GeminiDiscoveryOptions): Promise<ModelSpec<"google-generative-ai">[] | null>;
@@ -0,0 +1,4 @@
1
+ export * from "./antigravity";
2
+ export * from "./codex";
3
+ export * from "./gemini";
4
+ export * from "./openai-compatible";
@@ -0,0 +1,72 @@
1
+ import type { Api, FetchImpl, ModelSpec, Provider } from "../types";
2
+ /**
3
+ * Minimal OpenAI-style model entry shape consumed by discovery.
4
+ *
5
+ * Providers may return additional fields; this type only captures
6
+ * fields that are useful for generic normalization.
7
+ */
8
+ export interface OpenAICompatibleModelRecord {
9
+ id?: unknown;
10
+ name?: unknown;
11
+ object?: unknown;
12
+ owned_by?: unknown;
13
+ [key: string]: unknown;
14
+ }
15
+ /**
16
+ * Tolerant envelope for OpenAI-compatible `/models` responses.
17
+ *
18
+ * Common providers return `{ data: [...] }`, but variants such as
19
+ * `{ models: [...] }`, `{ result: [...] }`, or direct arrays are also
20
+ * accepted during extraction.
21
+ */
22
+ export interface OpenAICompatibleModelsEnvelope {
23
+ data?: unknown;
24
+ models?: unknown;
25
+ result?: unknown;
26
+ items?: unknown;
27
+ [key: string]: unknown;
28
+ }
29
+ /**
30
+ * Context passed to custom OpenAI-compatible model mappers.
31
+ */
32
+ export interface OpenAICompatibleModelMapperContext<TApi extends Api> {
33
+ api: TApi;
34
+ provider: Provider;
35
+ baseUrl: string;
36
+ }
37
+ /**
38
+ * Options for fetching and normalizing OpenAI-compatible `/models` catalogs.
39
+ */
40
+ export interface FetchOpenAICompatibleModelsOptions<TApi extends Api> {
41
+ /** API type assigned to normalized models. */
42
+ api: TApi;
43
+ /** Provider id assigned to normalized models. */
44
+ provider: Provider;
45
+ /** Provider base URL used for both fetch and normalized model records. */
46
+ baseUrl: string;
47
+ /** Optional bearer token for Authorization header. */
48
+ apiKey?: string;
49
+ /** Additional request headers. */
50
+ headers?: Record<string, string>;
51
+ /** Optional AbortSignal for request cancellation. */
52
+ signal?: AbortSignal;
53
+ /** Optional fetch implementation override for testing/custom runtimes. */
54
+ fetch?: FetchImpl;
55
+ /**
56
+ * Optional post-normalization filter.
57
+ * Return false to skip a model.
58
+ */
59
+ filterModel?: (entry: OpenAICompatibleModelRecord, model: ModelSpec<TApi>) => boolean;
60
+ /**
61
+ * Optional mapper override for provider-specific quirks.
62
+ * Return null to skip a model.
63
+ */
64
+ mapModel?: (entry: OpenAICompatibleModelRecord, defaults: ModelSpec<TApi>, context: OpenAICompatibleModelMapperContext<TApi>) => ModelSpec<TApi> | null;
65
+ }
66
+ /**
67
+ * Fetches and normalizes an OpenAI-compatible `/models` catalog.
68
+ *
69
+ * Returns `null` on transport/protocol failures.
70
+ * Returns `[]` only when the endpoint responds successfully with no usable models.
71
+ */
72
+ export declare function fetchOpenAICompatibleModels<TApi extends Api>(options: FetchOpenAICompatibleModelsOptions<TApi>): Promise<ModelSpec<TApi>[] | null>;
@@ -0,0 +1,9 @@
1
+ /** User-facing thinking levels, ordered least to most intensive. */
2
+ export declare const enum Effort {
3
+ Minimal = "minimal",
4
+ Low = "low",
5
+ Medium = "medium",
6
+ High = "high",
7
+ XHigh = "xhigh"
8
+ }
9
+ export declare const THINKING_EFFORTS: readonly Effort[];
@@ -0,0 +1,10 @@
1
+ export declare function toFireworksPublicModelId(modelId: string): string;
2
+ export declare function toFireworksWireModelId(modelId: string): string;
3
+ /**
4
+ * Fire Pass exposes its Kimi K2.6 Turbo subscription through a dedicated router
5
+ * endpoint at `accounts/fireworks/routers/<id>` rather than the `models/` namespace.
6
+ * We keep a friendly public id (e.g. `kimi-k2.6-turbo`) in the catalog and translate
7
+ * to the wire form (`accounts/fireworks/routers/kimi-k2p6-turbo`) at request time.
8
+ */
9
+ export declare function toFirepassPublicModelId(modelId: string): string;
10
+ export declare function toFirepassWireModelId(modelId: string): string;
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Known model-endpoint host classification — the single vocabulary for the
3
+ * `provider === id || baseUrl.includes(marker)` idiom that gates wire-level
4
+ * behavior (compat detection, routing, header shaping, watchdog floors).
5
+ *
6
+ * Markers are case-insensitive substrings matched against the base URL, NOT
7
+ * parsed hostnames: proxies regularly embed the upstream host in a path
8
+ * segment, and the historical call sites all used substring semantics.
9
+ * Callers that need strict hostname matching — where a substring false
10
+ * positive is dangerous, e.g. the Anthropic official-endpoint OAuth gate —
11
+ * parse the URL and compare the hostname themselves.
12
+ */
13
+ export declare const KNOWN_HOSTS: {
14
+ readonly openai: {
15
+ readonly providers: readonly ["openai"];
16
+ readonly urlMarkers: readonly ["api.openai.com"];
17
+ };
18
+ readonly azureOpenAI: {
19
+ readonly providers: readonly ["azure"];
20
+ readonly urlMarkers: readonly [".openai.azure.com", "azure.com/openai", "models.inference.ai.azure.com"];
21
+ };
22
+ readonly openrouter: {
23
+ readonly providers: readonly ["openrouter"];
24
+ readonly urlMarkers: readonly ["openrouter.ai"];
25
+ };
26
+ readonly vercelAIGateway: {
27
+ readonly providers: readonly ["vercel-ai-gateway"];
28
+ readonly urlMarkers: readonly ["ai-gateway.vercel.sh"];
29
+ };
30
+ readonly githubCopilot: {
31
+ readonly providers: readonly ["github-copilot"];
32
+ readonly urlMarkers: readonly ["githubcopilot.com", "copilot-api."];
33
+ };
34
+ readonly anthropic: {
35
+ readonly providers: readonly ["anthropic"];
36
+ readonly urlMarkers: readonly ["api.anthropic.com"];
37
+ };
38
+ /** DeepSeek's first-party API only — gates direct-API quirks (max_tokens field, thinking extraBody). */
39
+ readonly deepseekDirect: {
40
+ readonly providers: readonly ["deepseek"];
41
+ readonly urlMarkers: readonly ["api.deepseek.com"];
42
+ };
43
+ /** Any DeepSeek-operated host (first-party API, web-chat fronts). Wider than `deepseekDirect` on purpose. */
44
+ readonly deepseekFamily: {
45
+ readonly providers: readonly ["deepseek"];
46
+ readonly urlMarkers: readonly ["deepseek.com"];
47
+ };
48
+ readonly cerebras: {
49
+ readonly providers: readonly ["cerebras"];
50
+ readonly urlMarkers: readonly ["cerebras.ai"];
51
+ };
52
+ readonly zai: {
53
+ readonly providers: readonly ["zai"];
54
+ readonly urlMarkers: readonly ["api.z.ai"];
55
+ };
56
+ readonly zhipu: {
57
+ readonly providers: readonly ["zhipu-coding-plan"];
58
+ readonly urlMarkers: readonly ["open.bigmodel.cn"];
59
+ };
60
+ readonly kilo: {
61
+ readonly providers: readonly ["kilo"];
62
+ readonly urlMarkers: readonly ["api.kilo.ai"];
63
+ };
64
+ readonly alibabaDashscope: {
65
+ readonly providers: readonly ["alibaba-coding-plan"];
66
+ readonly urlMarkers: readonly ["dashscope"];
67
+ };
68
+ readonly xiaomi: {
69
+ readonly providers: readonly ["xiaomi"];
70
+ readonly providerPrefixes: readonly ["xiaomi-token-plan-"];
71
+ readonly urlMarkers: readonly ["xiaomimimo.com"];
72
+ };
73
+ readonly xai: {
74
+ readonly providers: readonly ["xai"];
75
+ readonly urlMarkers: readonly ["api.x.ai"];
76
+ };
77
+ readonly mistral: {
78
+ readonly providers: readonly ["mistral"];
79
+ readonly urlMarkers: readonly ["mistral.ai"];
80
+ };
81
+ readonly together: {
82
+ readonly providers: readonly ["together"];
83
+ readonly urlMarkers: readonly ["api.together.xyz"];
84
+ };
85
+ /** URL-only on purpose: the `fireworks`/`firepass` providers route per-model and not every model is Fireworks-shaped. */
86
+ readonly fireworks: {
87
+ readonly urlMarkers: readonly ["fireworks.ai"];
88
+ };
89
+ readonly groq: {
90
+ readonly providers: readonly ["groq"];
91
+ readonly urlMarkers: readonly ["api.groq.com"];
92
+ };
93
+ readonly minimax: {
94
+ readonly providers: readonly ["minimax", "minimax-code", "minimax-code-cn"];
95
+ readonly urlMarkers: readonly ["api.minimax.io", "api.minimaxi.com"];
96
+ };
97
+ readonly qwenPortal: {
98
+ readonly providers: readonly ["qwen-portal"];
99
+ readonly urlMarkers: readonly ["portal.qwen.ai"];
100
+ };
101
+ readonly moonshotNative: {
102
+ readonly providers: readonly ["moonshot", "kimi-code"];
103
+ readonly urlMarkers: readonly ["api.moonshot.ai", "api.kimi.com"];
104
+ };
105
+ readonly opencode: {
106
+ readonly providers: readonly ["opencode-go", "opencode-zen"];
107
+ readonly urlMarkers: readonly ["opencode.ai"];
108
+ };
109
+ readonly chutes: {
110
+ readonly urlMarkers: readonly ["chutes.ai"];
111
+ };
112
+ };
113
+ export type KnownHost = keyof typeof KNOWN_HOSTS;
114
+ /** URL-only host check (for call sites that have no provider id, e.g. raw env config). */
115
+ export declare function hostMatchesUrl(baseUrl: string | undefined, host: KnownHost): boolean;
116
+ /** Provider-or-URL host check — the canonical `provider === id || baseUrl.includes(marker)` idiom. */
117
+ export declare function modelMatchesHost(model: {
118
+ provider: string;
119
+ baseUrl: string;
120
+ }, host: KnownHost): boolean;
121
+ /** Vertex AI express-mode OpenAI-compatible endpoint (`…/endpoints/openapi`). */
122
+ export declare function isVertexExpressOpenAIUrl(baseUrl: string): boolean;
123
+ /** Vertex AI Anthropic raw-predict endpoints (`:streamRawPredict` / `:rawPredict`). */
124
+ export declare function isVertexRawPredictUrl(baseUrl: string): boolean;
125
+ /** Azure OpenAI deployment-scoped path (`…/deployments/<name>/…`). */
126
+ export declare function isAzureDeploymentsUrl(baseUrl: string): boolean;
127
+ /** Alibaba DashScope consumer `compatible-mode` endpoint (rejects multimodal arrays for some text-only SKUs). */
128
+ export declare function isDashscopeCompatibleModeUrl(baseUrl: string): boolean;
@@ -0,0 +1,6 @@
1
+ import { type CanonicalReferenceData } from "./equivalence";
2
+ import { type ModelReferenceIndex } from "./reference";
3
+ /** Canonical-equivalence reference data over the bundled catalog. */
4
+ export declare function getBundledCanonicalReferenceData(): CanonicalReferenceData;
5
+ /** Proxy-reference index over the bundled catalog. */
6
+ export declare function getBundledModelReferenceIndex(): ModelReferenceIndex;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Model-id classification: parse a model id into its family (gemini / anthropic /
3
+ * openai), kind/variant, and version. This is the shared layer both catalog
4
+ * policy rules (`model-thinking.ts`) and downstream consumers build on —
5
+ * classification lives here, the rules that consume it stay with their domain.
6
+ */
7
+ export type SemVer = {
8
+ major: number;
9
+ minor: number;
10
+ patch: number;
11
+ };
12
+ export type GeminiKind = "pro" | "flash";
13
+ export type AnthropicKind = "opus" | "sonnet" | "fable" | "mythos";
14
+ export type OpenAIVariant = "base" | "codex" | "codex-max" | "codex-mini" | "codex-spark" | "mini" | "max" | "nano";
15
+ export interface GeminiModel {
16
+ family: "gemini";
17
+ kind: GeminiKind;
18
+ version: SemVer;
19
+ }
20
+ export interface AnthropicModel {
21
+ family: "anthropic";
22
+ kind: AnthropicKind;
23
+ version: SemVer;
24
+ }
25
+ export interface OpenAIModel {
26
+ family: "openai";
27
+ variant: OpenAIVariant;
28
+ version: SemVer;
29
+ }
30
+ export interface UnknownModel {
31
+ family: "unknown";
32
+ id: string;
33
+ }
34
+ export type ParsedModel = GeminiModel | AnthropicModel | OpenAIModel | UnknownModel;
35
+ /** Strip a provider namespace prefix (`openai/gpt-5.4` → `gpt-5.4`). */
36
+ export declare function bareModelId(modelId: string): string;
37
+ export declare function parseKnownModel(modelId: string): ParsedModel;
38
+ export declare function parseGeminiModel(modelId: string): GeminiModel | null;
39
+ export declare function parseAnthropicModel(modelId: string): AnthropicModel | null;
40
+ export declare function parseOpenAIModel(modelId: string): OpenAIModel | null;
41
+ export declare function isFableOrMythos(kind: AnthropicKind): boolean;
42
+ export declare function parseSemVer(version: string): SemVer | null;
43
+ export declare function semverGte(left: SemVer | string, right: SemVer | string): boolean;
44
+ export declare function semverEqual(left: SemVer | string, right: SemVer | string): boolean;
45
+ export declare function compareSemVer(left: SemVer | string | null, right: SemVer | string | null): number;
@@ -0,0 +1,46 @@
1
+ import type { Api, Model } from "../types";
2
+ export type CanonicalModelSource = "override" | "bundled" | "heuristic" | "fallback";
3
+ export interface ModelEquivalenceConfig {
4
+ overrides?: Record<string, string>;
5
+ exclude?: string[];
6
+ }
7
+ export interface CanonicalModelVariant {
8
+ canonicalId: string;
9
+ selector: string;
10
+ model: Model<Api>;
11
+ source: CanonicalModelSource;
12
+ }
13
+ export interface CanonicalModelRecord {
14
+ id: string;
15
+ name: string;
16
+ variants: CanonicalModelVariant[];
17
+ }
18
+ export interface CanonicalModelIndex {
19
+ records: CanonicalModelRecord[];
20
+ byId: Map<string, CanonicalModelRecord>;
21
+ bySelector: Map<string, string>;
22
+ }
23
+ export interface CanonicalReferenceData {
24
+ references: ReadonlyMap<string, Model<Api>>;
25
+ officialIds: ReadonlySet<string>;
26
+ suffixAliases: ReadonlyMap<string, string>;
27
+ [kResolutionCaches]?: WeakMap<CompiledEquivalenceConfig, Map<string, ResolvedCanonicalModel>>;
28
+ }
29
+ interface CompiledEquivalenceConfig {
30
+ overrides: Map<string, string>;
31
+ exclude: Set<string>;
32
+ }
33
+ interface ResolvedCanonicalModel {
34
+ id: string;
35
+ source: CanonicalModelSource;
36
+ }
37
+ declare const kResolutionCaches: unique symbol;
38
+ /**
39
+ * Build canonical reference data from a model catalog (typically the bundled
40
+ * models). Pure: callers are responsible for memoizing the result — the
41
+ * canonical index keeps per-reference resolution caches internally.
42
+ */
43
+ export declare function buildCanonicalReferenceData(models: Iterable<Model<Api>>): CanonicalReferenceData;
44
+ export declare function formatCanonicalVariantSelector(model: Model<Api>): string;
45
+ export declare function buildCanonicalModelIndex(models: readonly Model<Api>[], reference: CanonicalReferenceData, equivalence?: ModelEquivalenceConfig): CanonicalModelIndex;
46
+ export {};
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Model-family id predicates: the shared vocabulary for "is this id a member
3
+ * of family X" checks that gate wire-level behavior across hosts (a Kimi or
4
+ * DeepSeek model keeps its quirks no matter which OpenAI-compatible proxy
5
+ * serves it). Looser per-feature heuristics (e.g. stream-markup healing)
6
+ * deliberately keep their own patterns — only provably-shared matchers live
7
+ * here.
8
+ */
9
+ /** Kimi family ids in any namespace form (`moonshotai/kimi-*`, `kimi-k2.6`, `vendor/kimi.x`). */
10
+ export declare function isKimiModelId(modelId: string): boolean;
11
+ /** Kimi K2.6 specifically (preserved-thinking transport on Moonshot-native hosts). */
12
+ export declare function isKimiK26ModelId(modelId: string): boolean;
13
+ /** Claude ids in any namespace form (`claude-*`, `vendor/claude.x`). */
14
+ export declare function isClaudeModelId(modelId: string): boolean;
15
+ /** `anthropic/`-namespaced ids (aggregator catalogs like OpenRouter). */
16
+ export declare function isAnthropicNamespacedModelId(modelId: string): boolean;
17
+ /** Qwen family ids (substring match — Qwen SKUs have no stable prefix shape). */
18
+ export declare function isQwenModelId(modelId: string): boolean;
19
+ /** DeepSeek family by id or display name (proxies often rename the id but keep the name). */
20
+ export declare function isDeepseekModelIdOrName(value: string): boolean;
21
+ /** Xiaomi MiMo family by id or display name. */
22
+ export declare function isMimoModelIdOrName(value: string): boolean;
23
+ /**
24
+ * Adaptive thinking `display` is supported starting with Claude Opus 4.7 and
25
+ * the Claude Fable/Mythos 5 generation. Older adaptive-thinking models
26
+ * (Opus 4.6, Sonnet 4.6+) reject the field. Classifier-based, so dotted and
27
+ * dashed version forms both match while bare dated ids
28
+ * (`claude-opus-4-20250514` = Opus 4.0) stay excluded.
29
+ */
30
+ export declare function supportsAdaptiveThinkingDisplay(modelId: string): boolean;
31
+ /**
32
+ * Returns true for Anthropic models with Opus 4.7+/Fable/Mythos API restrictions:
33
+ * - Sampling parameters (temperature/top_p/top_k) return 400 error
34
+ * - Thinking content is omitted by default (needs display: "summarized")
35
+ */
36
+ export declare function hasOpus47ApiRestrictions(modelId: string): boolean;
37
+ /**
38
+ * Mid-conversation `role: "system"` messages (system instructions appended at
39
+ * non-first positions in the `messages` array) are supported starting with
40
+ * Claude Opus 4.8 and the Claude Fable/Mythos 5 generation. Earlier Claude
41
+ * models reject the role.
42
+ * @see https://platform.claude.com/docs/en/build-with-claude/mid-conversation-system-messages
43
+ */
44
+ export declare function supportsMidConversationSystemMessages(modelId: string): boolean;
45
+ export declare function isAnthropicFableOrMythosModel(modelId: string): boolean;
@@ -0,0 +1,12 @@
1
+ export declare function getModelLikeIdSegments(modelId: string): string[];
2
+ export declare function getLongestModelLikeIdSegment(modelId: string): string | undefined;
3
+ /**
4
+ * Strip reseller / wrapper tags that are injected as bracketed affixes around an
5
+ * upstream model id, e.g.
6
+ * "[Kiro] claude-opus-4-8" -> "claude-opus-4-8"
7
+ * "[gcli转] gemini-3.1-pro-preview [假流]" -> "gemini-3.1-pro-preview"
8
+ *
9
+ * Candidates are returned most-stripped first: both ends, then leading-only, then trailing-only.
10
+ */
11
+ export declare function getBracketStrippedModelIdCandidates(modelId: string): string[];
12
+ export declare function stripBracketedModelIdAffixes(modelId: string): string | undefined;
@@ -0,0 +1,9 @@
1
+ export * from "./bundled";
2
+ export * from "./classify";
3
+ export * from "./equivalence";
4
+ export * from "./family";
5
+ export * from "./id";
6
+ export * from "./markers";
7
+ export * from "./priority";
8
+ export * from "./reference";
9
+ export * from "./selection";
@@ -0,0 +1,4 @@
1
+ /** Marker pattern used by canonical-id resolution (`search` excluded). */
2
+ export declare const CANONICAL_TRAILING_MARKER_PATTERN: RegExp;
3
+ /** Marker pattern used by proxy-reference lookup (`search` included). */
4
+ export declare const REFERENCE_TRAILING_MARKER_PATTERN: RegExp;
@@ -0,0 +1 @@
1
+ export declare function buildModelProviderPriorityRank(configuredProviderOrder?: readonly string[]): Map<string, number>;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Proxy/reseller reference lookup: given a custom model id served through a
3
+ * proxy (`[Kiro] claude-opus-4-8`, `gpt-5.4:cloud`, `vendor/claude-sonnet-4-6-thinking`),
4
+ * find the bundled upstream model so missing pricing/capability metadata can be
5
+ * inherited while keeping the custom transport.
6
+ *
7
+ * Kept separate from canonical-id resolution (`./equivalence`): this lookup
8
+ * may strip `search`-style markers and prefers cache-pricing-complete
9
+ * references, both of which would be wrong for canonical coalescing.
10
+ */
11
+ import type { Api, Model } from "../types";
12
+ export interface ModelReferenceIndex {
13
+ exact: Map<string, Model<Api>>;
14
+ suffixAlias: Map<string, Model<Api>>;
15
+ }
16
+ /**
17
+ * Build a reference index from a model catalog (typically the bundled models).
18
+ * Pure: callers are responsible for memoizing the result.
19
+ */
20
+ export declare function buildModelReferenceIndex(models: Iterable<Model<Api>>): ModelReferenceIndex;
21
+ /** Resolve a (possibly proxied/affixed) model id to its bundled upstream reference. */
22
+ export declare function resolveModelReference(modelId: string, index: ModelReferenceIndex): Model<Api> | undefined;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Canonical-variant selection: pick the preferred variant of a canonical
3
+ * model record given caller-supplied provider and candidate orderings.
4
+ */
5
+ import type { Api, Model } from "../types";
6
+ import { type CanonicalModelVariant } from "./equivalence";
7
+ export interface CanonicalVariantPreferences {
8
+ /** Lowercased provider id → rank (lower wins). */
9
+ providerRank: ReadonlyMap<string, number>;
10
+ /** Variant selector (`provider/id`) → candidate-list position (lower wins). */
11
+ modelOrder: ReadonlyMap<string, number>;
12
+ }
13
+ /** Selector → index map over an ordered candidate list, for `modelOrder` tiebreaks. */
14
+ export declare function buildCanonicalModelOrder(candidates: readonly Model<Api>[]): Map<string, number>;
15
+ /**
16
+ * Pick the preferred variant. Sort order: configured provider rank →
17
+ * exact-id match → variant source (override/bundled > heuristic > fallback)
18
+ * → shorter id → candidate-list order.
19
+ */
20
+ export declare function resolveCanonicalVariant(variants: readonly CanonicalModelVariant[], preferences: CanonicalVariantPreferences): CanonicalModelVariant | undefined;
@@ -0,0 +1,15 @@
1
+ export * from "./compat/openai";
2
+ export * from "./discovery";
3
+ export * from "./effort";
4
+ export * from "./fireworks-model-id";
5
+ export * from "./identity";
6
+ export * from "./model-cache";
7
+ export * from "./model-manager";
8
+ export * from "./model-thinking";
9
+ export * from "./models";
10
+ export * from "./provider-models";
11
+ export * from "./types";
12
+ export * from "./utils";
13
+ export * from "./wire/codex";
14
+ export * from "./wire/gemini-headers";
15
+ export * from "./wire/github-copilot";
@@ -0,0 +1,17 @@
1
+ import type { Api, Model, ModelSpec } from "./types";
2
+ interface CacheEntry<TApi extends Api = Api> {
3
+ models: ModelSpec<TApi>[];
4
+ fresh: boolean;
5
+ authoritative: boolean;
6
+ updatedAt: number;
7
+ /**
8
+ * Hash of the static catalog slice that was merged into `models` when this
9
+ * row was written. `resolveProviderModels` compares against the current
10
+ * static fingerprint and bypasses the static+cache re-merge when they
11
+ * match — the cache already incorporates the same static state.
12
+ */
13
+ staticFingerprint: string;
14
+ }
15
+ export declare function readModelCache<TApi extends Api>(providerId: string, ttlMs: number, now: () => number, dbPath?: string): CacheEntry<TApi> | null;
16
+ export declare function writeModelCache<TApi extends Api>(providerId: string, updatedAt: number, models: Model<TApi>[], authoritative: boolean, staticFingerprint: string, dbPath?: string): void;
17
+ export {};
@@ -0,0 +1,64 @@
1
+ import type { Api, Model, ModelSpec, Provider } from "./types";
2
+ /**
3
+ * Controls when dynamic endpoint models should be fetched.
4
+ */
5
+ export type ModelRefreshStrategy = "online" | "offline" | "online-if-uncached";
6
+ /**
7
+ * Hook for loading and mapping models.dev fallback data into canonical model objects.
8
+ */
9
+ export interface ModelsDevFallback<TApi extends Api = Api, TPayload = unknown> {
10
+ /** Fetches raw fallback payload (for example from models.dev). */
11
+ fetch(): Promise<TPayload>;
12
+ /** Maps payload into provider models. */
13
+ map(payload: TPayload, providerId: Provider): readonly ModelSpec<TApi>[];
14
+ }
15
+ /**
16
+ * Configuration for provider model resolution.
17
+ */
18
+ export interface ModelManagerOptions<TApi extends Api = Api, TModelsDevPayload = unknown> {
19
+ /** Provider id used for static lookup and cache namespacing. */
20
+ providerId: Provider;
21
+ /** Optional static list override. When omitted, bundled models.json is used. */
22
+ staticModels?: readonly ModelSpec<TApi>[];
23
+ /** Optional override for the cache database path. Default: <agent-dir>/models.db. */
24
+ cacheDbPath?: string;
25
+ /** Maximum cache age in milliseconds before considered stale. Default: 24h. */
26
+ cacheTtlMs?: number;
27
+ /** When true, a successful dynamic fetch is the complete provider catalog and prunes static-only models. */
28
+ dynamicModelsAuthoritative?: boolean;
29
+ /** Optional dynamic endpoint fetcher. */
30
+ fetchDynamicModels?: () => Promise<readonly ModelSpec<TApi>[] | null>;
31
+ /** Optional models.dev fallback hook. */
32
+ modelsDev?: ModelsDevFallback<TApi, TModelsDevPayload>;
33
+ /** Clock override for deterministic tests. */
34
+ now?: () => number;
35
+ }
36
+ /**
37
+ * Resolution result.
38
+ *
39
+ * `stale` is false when the resolved catalog is authoritative for the selected provider:
40
+ * - dynamic endpoint data was fetched in this call,
41
+ * - a still-fresh authoritative cache was reused in `online-if-uncached` mode, or
42
+ * - the provider has no dynamic fetcher configured.
43
+ */
44
+ export interface ModelResolutionResult<TApi extends Api = Api> {
45
+ models: Model<TApi>[];
46
+ stale: boolean;
47
+ }
48
+ /**
49
+ * Stateful facade over provider model resolution.
50
+ */
51
+ export interface ModelManager<TApi extends Api = Api> {
52
+ refresh(strategy?: ModelRefreshStrategy): Promise<ModelResolutionResult<TApi>>;
53
+ }
54
+ /**
55
+ * Creates a reusable provider model manager.
56
+ */
57
+ export declare function createModelManager<TApi extends Api = Api, TModelsDevPayload = unknown>(options: ModelManagerOptions<TApi, TModelsDevPayload>): ModelManager<TApi>;
58
+ /**
59
+ * Resolves provider models with source precedence:
60
+ * static -> models.dev -> cache -> dynamic.
61
+ *
62
+ * Later sources override earlier ones by model id.
63
+ */
64
+ export declare function resolveProviderModels<TApi extends Api = Api, TModelsDevPayload = unknown>(options: ModelManagerOptions<TApi, TModelsDevPayload>, strategy?: ModelRefreshStrategy): Promise<ModelResolutionResult<TApi>>;