@oh-my-pi/pi-catalog 17.4.1 → 18.0.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 +16 -0
- package/dist/types/identity/family.d.ts +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/provider-models/cache-provider-id.d.ts +2 -0
- package/dist/types/types.d.ts +7 -1
- package/dist/types/variant-collapse.d.ts +18 -16
- package/dist/types/wire/image-fetchers.d.ts +76 -0
- package/package.json +4 -4
- package/src/build.ts +2 -0
- package/src/identity/family.ts +1 -1
- package/src/index.ts +1 -0
- package/src/models.json +10352 -3845
- package/src/provider-models/cache-provider-id.ts +11 -0
- package/src/types.ts +7 -1
- package/src/variant-collapse.ts +295 -51
- package/src/wire/image-fetchers.ts +159 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.0.0] - 2026-08-22
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added model capability metadata for reversible private-use glyph tokenization on Claude-compatible models, so provider request handling can apply the compatibility layer without inferring from transport details.
|
|
10
|
+
|
|
11
|
+
## [17.4.2] - 2026-08-21
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Added identification of provider-side image fetchers (OpenAI, Anthropic, xAI, Google), so a server hosting images by URL can attribute an inbound fetch to the vendor that issued it.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Fixed Cursor model discovery showing separate picker rows for pure effort-suffixed models beyond GPT-5.6 by collapsing each standard and Fast lane into one reasoning-effort model ([#9237](https://github.com/can1357/oh-my-pi/issues/9237)).
|
|
20
|
+
|
|
5
21
|
## [17.4.1] - 2026-08-21
|
|
6
22
|
|
|
7
23
|
### Added
|
|
@@ -212,7 +212,7 @@ export declare const supportsMidConversationSystemMessages: (modelId: string) =>
|
|
|
212
212
|
* Models that reliably follow the hashline line-anchored edit dialect
|
|
213
213
|
* (`[path#TAG]` headers plus 1-indexed anchors). Kimi, MiMo, DeepSeek V4
|
|
214
214
|
* Flash, and Step 3.7 Flash miscount anchors or drop the tag header often
|
|
215
|
-
* enough that hosts fall back to
|
|
215
|
+
* enough that hosts fall back to the sloppy edit format for
|
|
216
216
|
* them.
|
|
217
217
|
*/
|
|
218
218
|
export declare const supportsHashlineEdits: (modelId: string) => boolean;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ export interface ModelCacheProviderIdOptions {
|
|
|
2
2
|
apiKey?: string;
|
|
3
3
|
baseUrl?: string;
|
|
4
4
|
}
|
|
5
|
+
/** Whether a provider's model-cache namespace requires its resolved credential. */
|
|
6
|
+
export declare function isCredentialScopedModelCacheProvider(providerId: string): boolean;
|
|
5
7
|
export declare function getDefaultModelDiscoveryBaseUrl(providerId: string): string | undefined;
|
|
6
8
|
/** Resolve an Ollama model-cache namespace scoped to the normalized discovery endpoint. */
|
|
7
9
|
export declare function resolveOllamaModelCacheProviderId(providerId: string, baseUrl?: string): string;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -727,6 +727,12 @@ export interface ModelCost extends TokenCost {
|
|
|
727
727
|
export type ModelTokenizer = "claude-v3" | "claude-v47" | "claude-v5" | "claude-v5-sonnet" | "qwen3" | "deepseek-v3" | "kimi-k2" | "glm5";
|
|
728
728
|
export interface Model<TApi extends Api = Api> {
|
|
729
729
|
id: string;
|
|
730
|
+
/**
|
|
731
|
+
* Whether provider-bound private-use glyphs require reversible ASCII tokenization.
|
|
732
|
+
* Materialized by `buildModel`; request handlers read this capability instead of
|
|
733
|
+
* inferring it from the transport API.
|
|
734
|
+
*/
|
|
735
|
+
requiresGlyphTokenization?: boolean;
|
|
730
736
|
/**
|
|
731
737
|
* Model id to send on the wire when it differs from `id`. Used by catalog
|
|
732
738
|
* variants that present one upstream model under several local entries —
|
|
@@ -852,7 +858,7 @@ export interface Model<TApi extends Api = Api> {
|
|
|
852
858
|
* vocabulary of `buildModel`. Identical to `Model` except `compat` carries the
|
|
853
859
|
* sparse override shape and nothing is resolved yet.
|
|
854
860
|
*/
|
|
855
|
-
export interface ModelSpec<TApi extends Api = Api> extends Omit<Model<TApi>, "compat" | "compatConfig" | "supportsComputerUseConfig"> {
|
|
861
|
+
export interface ModelSpec<TApi extends Api = Api> extends Omit<Model<TApi>, "compat" | "compatConfig" | "requiresGlyphTokenization" | "supportsComputerUseConfig"> {
|
|
856
862
|
/** Sparse compatibility overrides; resolved into `Model.compat` by `buildModel`. */
|
|
857
863
|
compat?: CompatConfigOf<TApi>;
|
|
858
864
|
}
|
|
@@ -91,10 +91,11 @@ export declare function isVariantCollapsedSpec(spec: VariantSpecLike): boolean;
|
|
|
91
91
|
*/
|
|
92
92
|
export declare function collapseEffortVariants<TSpec extends VariantSpecLike>(specs: readonly TSpec[], table: VariantCollapseTable): TSpec[];
|
|
93
93
|
/**
|
|
94
|
-
* Collapse a full mixed-provider list: per provider, the hand table
|
|
95
|
-
*
|
|
96
|
-
* catalog generator; the runtime equivalent lives at
|
|
97
|
-
* point. Output is regrouped by provider — callers
|
|
94
|
+
* Collapse a full mixed-provider list: per provider, the hand table, Cursor's
|
|
95
|
+
* conservative live effort-sibling rule, and the automatic `X`/`X-thinking`
|
|
96
|
+
* pair rule. Used by the catalog generator; the runtime equivalent lives at
|
|
97
|
+
* the model-manager merge point. Output is regrouped by provider — callers
|
|
98
|
+
* re-sort.
|
|
98
99
|
*/
|
|
99
100
|
export declare function collapseEffortVariantsAcrossProviders<TSpec extends VariantSpecLike>(specs: readonly TSpec[]): TSpec[];
|
|
100
101
|
/**
|
|
@@ -107,29 +108,30 @@ export declare function collapseEffortVariantsAcrossProviders<TSpec extends Vari
|
|
|
107
108
|
export declare function collapseBuiltModelVariants<TApi extends Api>(models: readonly Model<TApi>[]): Model<TApi>[];
|
|
108
109
|
/**
|
|
109
110
|
* Resolve a retired effort-tier variant id (collapsed member, recycled id) to
|
|
110
|
-
* its replacement model id for `provider` via
|
|
111
|
-
* `undefined` when the id is not a known alias; derived
|
|
112
|
-
*
|
|
113
|
-
* exact model lookup first — a live model always wins over
|
|
111
|
+
* its replacement model id for `provider` via hand-table or registered live
|
|
112
|
+
* aliases. Returns `undefined` when the id is not a known alias; derived
|
|
113
|
+
* `X-thinking` members also resolve through `stripThinkingVariantToken`.
|
|
114
|
+
* Callers must try an exact model lookup first — a live model always wins over
|
|
115
|
+
* an alias.
|
|
114
116
|
*/
|
|
115
117
|
export declare function resolveVariantAlias(provider: Provider, modelId: string): string | undefined;
|
|
116
118
|
/** Bare-id alias hit: replacement id plus the providers declaring it. */
|
|
117
119
|
export interface BareVariantAliasHit {
|
|
118
120
|
id: string;
|
|
119
|
-
/** Providers
|
|
121
|
+
/** Providers declaring the alias — candidates from these win ties. */
|
|
120
122
|
providers: readonly Provider[];
|
|
121
123
|
}
|
|
122
124
|
/**
|
|
123
|
-
* Provider-agnostic
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
125
|
+
* Provider-agnostic alias lookup for bare-id selectors. Returns the declaring
|
|
126
|
+
* providers so callers can prefer their models when the replacement id exists
|
|
127
|
+
* on unrelated providers too (e.g. a retired Cursor tier id must not resolve
|
|
128
|
+
* to `openai/gpt-5.4`).
|
|
127
129
|
*/
|
|
128
130
|
export declare function resolveBareVariantAlias(modelId: string): BareVariantAliasHit | undefined;
|
|
129
131
|
/**
|
|
130
132
|
* Reverse alias lookup: the retired ids that resolve to `modelId` for
|
|
131
|
-
* `provider` via
|
|
132
|
-
* ids (models.yml `modelOverrides`, suppressed selectors)
|
|
133
|
-
*
|
|
133
|
+
* `provider` via hand-table or registered live aliases. Used to re-key config
|
|
134
|
+
* keyed by raw member ids (models.yml `modelOverrides`, suppressed selectors)
|
|
135
|
+
* onto the collapsed model.
|
|
134
136
|
*/
|
|
135
137
|
export declare function getVariantAliasSources(provider: Provider, modelId: string): readonly string[];
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identification of provider-side image fetchers.
|
|
3
|
+
*
|
|
4
|
+
* A request may carry an image either inline (base64) or as a URL. With a URL,
|
|
5
|
+
* the provider's backend performs its own server-side GET against that URL, so
|
|
6
|
+
* a local blob server sees an inbound request from vendor infrastructure rather
|
|
7
|
+
* than from the client. This module names those fetchers, letting a blob server
|
|
8
|
+
* attribute an inbound GET to the vendor that issued it — which is how a caller
|
|
9
|
+
* learns where a request actually landed when a router sits between them and
|
|
10
|
+
* the model.
|
|
11
|
+
*
|
|
12
|
+
* NOT an authentication mechanism. Every value here is a request header chosen
|
|
13
|
+
* by the caller and is trivially forged. Authorize blob reads with an
|
|
14
|
+
* unguessable URL (single-use capability token, short TTL) and treat a fetcher
|
|
15
|
+
* match as attribution/telemetry only.
|
|
16
|
+
*
|
|
17
|
+
* Each entry was captured from a live fetch triggered by handing that vendor's
|
|
18
|
+
* API a URL-sourced image.
|
|
19
|
+
*/
|
|
20
|
+
/** Vendor whose infrastructure performed an inbound fetch. */
|
|
21
|
+
export type ImageFetcherVendor = "openai" | "anthropic" | "xai" | "google";
|
|
22
|
+
/** Registry key for a known fetcher. */
|
|
23
|
+
export type ImageFetcherId = "openai-file-downloader" | "anthropic-claude-user" | "anthropic-claude-user-preview" | "xai-image-api-fetch" | "google";
|
|
24
|
+
/** Request signature of one provider-side fetcher. */
|
|
25
|
+
export interface ImageFetcherIdentity {
|
|
26
|
+
vendor: ImageFetcherVendor;
|
|
27
|
+
/** Human-readable name for logs and UI. */
|
|
28
|
+
label: string;
|
|
29
|
+
/**
|
|
30
|
+
* `User-Agent` contract: an exact string for fetchers that send a fixed
|
|
31
|
+
* value, or a pattern for those embedding a client version.
|
|
32
|
+
*/
|
|
33
|
+
userAgent: string | RegExp;
|
|
34
|
+
/**
|
|
35
|
+
* Vendor-proprietary headers observed alongside the agent, used to
|
|
36
|
+
* corroborate a `User-Agent` claim. Generic infrastructure headers
|
|
37
|
+
* (`traceparent`, `x-cloud-trace-context`) are deliberately excluded: they
|
|
38
|
+
* are emitted by unrelated infrastructure and corroborate nothing. Empty
|
|
39
|
+
* means the agent string is the only available signal, so
|
|
40
|
+
* {@link ImageFetcherMatch.corroborated} can never be true for that entry.
|
|
41
|
+
*/
|
|
42
|
+
markerHeaders: readonly string[];
|
|
43
|
+
/** API surface the capture came from. */
|
|
44
|
+
observedVia: string;
|
|
45
|
+
/** Operational caveats a blob server should account for. */
|
|
46
|
+
note?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Known provider-side fetchers.
|
|
50
|
+
*
|
|
51
|
+
* Agent contracts do not overlap — exact strings never collide with the
|
|
52
|
+
* versioned patterns — so lookup order carries no meaning.
|
|
53
|
+
*/
|
|
54
|
+
export declare const IMAGE_FETCHERS: Readonly<Record<ImageFetcherId, ImageFetcherIdentity>>;
|
|
55
|
+
/** Attribution outcome for one inbound request. */
|
|
56
|
+
export interface ImageFetcherMatch {
|
|
57
|
+
id: ImageFetcherId;
|
|
58
|
+
identity: ImageFetcherIdentity;
|
|
59
|
+
/**
|
|
60
|
+
* Whether every proprietary marker header for the matched identity is
|
|
61
|
+
* present. Always false for identities declaring no markers — absence of
|
|
62
|
+
* corroboration is not evidence against the match.
|
|
63
|
+
*/
|
|
64
|
+
corroborated: boolean;
|
|
65
|
+
}
|
|
66
|
+
/** Inbound header bag, as exposed by either `fetch` or a Node-style server. */
|
|
67
|
+
export type InboundHeaders = Headers | Readonly<Record<string, string | readonly string[] | undefined>>;
|
|
68
|
+
/**
|
|
69
|
+
* Attribute an inbound blob request to a known provider-side fetcher, or
|
|
70
|
+
* `null` when the agent matches none.
|
|
71
|
+
*
|
|
72
|
+
* Matches on `User-Agent` alone and reports marker-header corroboration
|
|
73
|
+
* separately; callers MUST NOT treat either as proof of origin. Gate access on
|
|
74
|
+
* the unguessable URL.
|
|
75
|
+
*/
|
|
76
|
+
export declare function identifyImageFetcher(headers: InboundHeaders): ImageFetcherMatch | null;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-catalog",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "18.0.0",
|
|
5
5
|
"description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Stencil Labs, Inc.",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"gen:proto": "bun scripts/generate-protocols.ts"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@oh-my-pi/omptype": "
|
|
38
|
-
"@oh-my-pi/pi-utils": "
|
|
37
|
+
"@oh-my-pi/omptype": "18.0.0",
|
|
38
|
+
"@oh-my-pi/pi-utils": "18.0.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@oh-my-pi/pi-ai": "
|
|
41
|
+
"@oh-my-pi/pi-ai": "18.0.0",
|
|
42
42
|
"@types/bun": "^1.3.14"
|
|
43
43
|
},
|
|
44
44
|
"engines": {
|
package/src/build.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { buildBedrockCompat } from "./compat/bedrock";
|
|
|
15
15
|
import { buildDevinCompat } from "./compat/devin";
|
|
16
16
|
import { buildOpenAICompat, buildOpenAIResponsesCompat, buildOpenRouterCompat } from "./compat/openai";
|
|
17
17
|
import { bareModelId, parseOpenAIModel, semverGte } from "./identity/classify";
|
|
18
|
+
import { isClaudeModelId } from "./identity/family";
|
|
18
19
|
import { resolveModelThinking } from "./model-thinking";
|
|
19
20
|
import { resolveModelTokenizer } from "./model-tokenizer";
|
|
20
21
|
import type { Api, CompatOf, Model, ModelSpec } from "./types";
|
|
@@ -70,6 +71,7 @@ export function buildModel<TApi extends Api>(spec: ModelSpec<TApi>): Model<TApi>
|
|
|
70
71
|
return {
|
|
71
72
|
...spec,
|
|
72
73
|
name: cleanModelName(spec.name),
|
|
74
|
+
requiresGlyphTokenization: isClaudeModelId(spec.id),
|
|
73
75
|
tokenizer: spec.tokenizer ?? resolveModelTokenizer(spec.requestModelId ?? spec.id),
|
|
74
76
|
thinking: resolveModelThinking(spec, compat),
|
|
75
77
|
supportsComputerUse: supportsOpenAIGAComputerUse(spec, supportsComputerUseConfig),
|
package/src/identity/family.ts
CHANGED
|
@@ -418,7 +418,7 @@ export const supportsMidConversationSystemMessages = memo((modelId: string): boo
|
|
|
418
418
|
* Models that reliably follow the hashline line-anchored edit dialect
|
|
419
419
|
* (`[path#TAG]` headers plus 1-indexed anchors). Kimi, MiMo, DeepSeek V4
|
|
420
420
|
* Flash, and Step 3.7 Flash miscount anchors or drop the tag header often
|
|
421
|
-
* enough that hosts fall back to
|
|
421
|
+
* enough that hosts fall back to the sloppy edit format for
|
|
422
422
|
* them.
|
|
423
423
|
*/
|
|
424
424
|
export const supportsHashlineEdits = memo((modelId: string): boolean => {
|
package/src/index.ts
CHANGED