@oh-my-pi/pi-catalog 17.4.0 → 17.4.2
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 +32 -0
- package/LICENSE +22 -0
- package/THIRD-PARTY-NOTICES.txt +22909 -0
- package/dist/types/discovery/cursor-proto.d.ts +6 -0
- package/dist/types/identity/family.d.ts +7 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/model-manager.d.ts +5 -5
- package/dist/types/provider-models/cache-provider-id.d.ts +2 -0
- package/dist/types/provider-models/descriptors.d.ts +1 -1
- package/dist/types/provider-models/openai-compat.d.ts +3 -1
- package/dist/types/types.d.ts +3 -1
- package/dist/types/variant-collapse.d.ts +19 -17
- package/dist/types/wire/codex.d.ts +21 -0
- package/dist/types/wire/image-fetchers.d.ts +76 -0
- package/package.json +7 -5
- package/src/compat/openai.ts +1 -1
- package/src/discovery/codex.ts +4 -0
- package/src/discovery/cursor-proto.ts +7 -0
- package/src/identity/family.ts +10 -0
- package/src/index.ts +1 -0
- package/src/model-cache.ts +3 -3
- package/src/model-manager.ts +5 -5
- package/src/models.json +599 -1651
- package/src/provider-models/cache-provider-id.ts +15 -2
- package/src/provider-models/google.ts +8 -6
- package/src/provider-models/openai-compat.ts +151 -48
- package/src/types.ts +3 -1
- package/src/variant-collapse.ts +332 -52
- package/src/wire/codex.ts +54 -0
- package/src/wire/image-fetchers.ts +159 -0
|
@@ -0,0 +1,159 @@
|
|
|
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
|
+
|
|
21
|
+
/** Vendor whose infrastructure performed an inbound fetch. */
|
|
22
|
+
export type ImageFetcherVendor = "openai" | "anthropic" | "xai" | "google";
|
|
23
|
+
|
|
24
|
+
/** Registry key for a known fetcher. */
|
|
25
|
+
export type ImageFetcherId =
|
|
26
|
+
| "openai-file-downloader"
|
|
27
|
+
| "anthropic-claude-user"
|
|
28
|
+
| "anthropic-claude-user-preview"
|
|
29
|
+
| "xai-image-api-fetch"
|
|
30
|
+
| "google";
|
|
31
|
+
|
|
32
|
+
/** Request signature of one provider-side fetcher. */
|
|
33
|
+
export interface ImageFetcherIdentity {
|
|
34
|
+
vendor: ImageFetcherVendor;
|
|
35
|
+
/** Human-readable name for logs and UI. */
|
|
36
|
+
label: string;
|
|
37
|
+
/**
|
|
38
|
+
* `User-Agent` contract: an exact string for fetchers that send a fixed
|
|
39
|
+
* value, or a pattern for those embedding a client version.
|
|
40
|
+
*/
|
|
41
|
+
userAgent: string | RegExp;
|
|
42
|
+
/**
|
|
43
|
+
* Vendor-proprietary headers observed alongside the agent, used to
|
|
44
|
+
* corroborate a `User-Agent` claim. Generic infrastructure headers
|
|
45
|
+
* (`traceparent`, `x-cloud-trace-context`) are deliberately excluded: they
|
|
46
|
+
* are emitted by unrelated infrastructure and corroborate nothing. Empty
|
|
47
|
+
* means the agent string is the only available signal, so
|
|
48
|
+
* {@link ImageFetcherMatch.corroborated} can never be true for that entry.
|
|
49
|
+
*/
|
|
50
|
+
markerHeaders: readonly string[];
|
|
51
|
+
/** API surface the capture came from. */
|
|
52
|
+
observedVia: string;
|
|
53
|
+
/** Operational caveats a blob server should account for. */
|
|
54
|
+
note?: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Known provider-side fetchers.
|
|
59
|
+
*
|
|
60
|
+
* Agent contracts do not overlap — exact strings never collide with the
|
|
61
|
+
* versioned patterns — so lookup order carries no meaning.
|
|
62
|
+
*/
|
|
63
|
+
export const IMAGE_FETCHERS: Readonly<Record<ImageFetcherId, ImageFetcherIdentity>> = {
|
|
64
|
+
"openai-file-downloader": {
|
|
65
|
+
vendor: "openai",
|
|
66
|
+
label: "OpenAI File Downloader",
|
|
67
|
+
userAgent: "OpenAI File Downloader",
|
|
68
|
+
markerHeaders: ["openai-internal-smokescreener"],
|
|
69
|
+
observedVia: "chatgpt.com/backend-api/codex/responses, input_image.image_url",
|
|
70
|
+
note: "Issues two near-simultaneous GETs per image; a blob server must treat a duplicate hit as expected rather than as replay.",
|
|
71
|
+
},
|
|
72
|
+
"anthropic-claude-user": {
|
|
73
|
+
vendor: "anthropic",
|
|
74
|
+
label: "Claude image fetcher",
|
|
75
|
+
userAgent: "Claude-User",
|
|
76
|
+
markerHeaders: [],
|
|
77
|
+
observedVia: "api.anthropic.com/v1/messages, image.source.type=url",
|
|
78
|
+
note: "Sends only generic trace headers, so the bare agent string is the sole signal. Distinct from the versioned Claude-User/<version> agent used for links appearing in conversation text.",
|
|
79
|
+
},
|
|
80
|
+
"anthropic-claude-user-preview": {
|
|
81
|
+
vendor: "anthropic",
|
|
82
|
+
label: "Claude link fetcher",
|
|
83
|
+
userAgent: /\bClaude-User\/\d+(?:\.\d+)*\b/,
|
|
84
|
+
markerHeaders: [],
|
|
85
|
+
observedVia:
|
|
86
|
+
"unsolicited fetch after a URL appeared in assistant output; never observed serving an image request",
|
|
87
|
+
note: "Not an image fetcher. Listed so a blob server can separate it from the image path instead of counting it as a provider image fetch.",
|
|
88
|
+
},
|
|
89
|
+
"xai-image-api-fetch": {
|
|
90
|
+
vendor: "xai",
|
|
91
|
+
label: "xAI image API fetch",
|
|
92
|
+
userAgent: /^XaiImageApiFetch\/\d+(?:\.\d+)*\s/,
|
|
93
|
+
markerHeaders: ["x-xaifetchid"],
|
|
94
|
+
observedVia: "api.x.ai/v1/responses, input_image.image_url",
|
|
95
|
+
note: "Sends an image-only `accept` allowlist and rejects any other content type before the model sees the response.",
|
|
96
|
+
},
|
|
97
|
+
google: {
|
|
98
|
+
vendor: "google",
|
|
99
|
+
label: "Google",
|
|
100
|
+
userAgent: "Google",
|
|
101
|
+
markerHeaders: [],
|
|
102
|
+
observedVia: "cloudcode-pa.googleapis.com v1internal:streamGenerateContent, fileData.fileUri",
|
|
103
|
+
note: "Weakest signal of the set: the agent string is a bare vendor name with no version and no proprietary header.",
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/** Attribution outcome for one inbound request. */
|
|
108
|
+
export interface ImageFetcherMatch {
|
|
109
|
+
id: ImageFetcherId;
|
|
110
|
+
identity: ImageFetcherIdentity;
|
|
111
|
+
/**
|
|
112
|
+
* Whether every proprietary marker header for the matched identity is
|
|
113
|
+
* present. Always false for identities declaring no markers — absence of
|
|
114
|
+
* corroboration is not evidence against the match.
|
|
115
|
+
*/
|
|
116
|
+
corroborated: boolean;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Inbound header bag, as exposed by either `fetch` or a Node-style server. */
|
|
120
|
+
export type InboundHeaders = Headers | Readonly<Record<string, string | readonly string[] | undefined>>;
|
|
121
|
+
|
|
122
|
+
function headerValue(headers: InboundHeaders, name: string): string | undefined {
|
|
123
|
+
if (headers instanceof Headers) return headers.get(name) ?? undefined;
|
|
124
|
+
const direct = headers[name];
|
|
125
|
+
if (direct !== undefined) return Array.isArray(direct) ? direct[0] : (direct as string);
|
|
126
|
+
for (const key in headers) {
|
|
127
|
+
if (key.toLowerCase() !== name) continue;
|
|
128
|
+
const value = headers[key];
|
|
129
|
+
return Array.isArray(value) ? value[0] : (value as string | undefined);
|
|
130
|
+
}
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Attribute an inbound blob request to a known provider-side fetcher, or
|
|
136
|
+
* `null` when the agent matches none.
|
|
137
|
+
*
|
|
138
|
+
* Matches on `User-Agent` alone and reports marker-header corroboration
|
|
139
|
+
* separately; callers MUST NOT treat either as proof of origin. Gate access on
|
|
140
|
+
* the unguessable URL.
|
|
141
|
+
*/
|
|
142
|
+
export function identifyImageFetcher(headers: InboundHeaders): ImageFetcherMatch | null {
|
|
143
|
+
const agent = headerValue(headers, "user-agent");
|
|
144
|
+
if (!agent) return null;
|
|
145
|
+
for (const id in IMAGE_FETCHERS) {
|
|
146
|
+
const identity = IMAGE_FETCHERS[id as ImageFetcherId];
|
|
147
|
+
const { userAgent } = identity;
|
|
148
|
+
const matched = typeof userAgent === "string" ? agent === userAgent : userAgent.test(agent);
|
|
149
|
+
if (!matched) continue;
|
|
150
|
+
return {
|
|
151
|
+
id: id as ImageFetcherId,
|
|
152
|
+
identity,
|
|
153
|
+
corroborated:
|
|
154
|
+
identity.markerHeaders.length > 0 &&
|
|
155
|
+
identity.markerHeaders.every(header => headerValue(headers, header) !== undefined),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
return null;
|
|
159
|
+
}
|