ai-model-verifier 1.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.
Files changed (95) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +40 -0
  3. package/dist/detectors/response-metadata.d.ts +36 -0
  4. package/dist/detectors/response-metadata.d.ts.map +1 -0
  5. package/dist/detectors/response-metadata.js +91 -0
  6. package/dist/detectors/response-metadata.js.map +1 -0
  7. package/dist/detectors/thinking-signature.d.ts +70 -0
  8. package/dist/detectors/thinking-signature.d.ts.map +1 -0
  9. package/dist/detectors/thinking-signature.js +177 -0
  10. package/dist/detectors/thinking-signature.js.map +1 -0
  11. package/dist/detectors/throughput.d.ts +51 -0
  12. package/dist/detectors/throughput.d.ts.map +1 -0
  13. package/dist/detectors/throughput.js +83 -0
  14. package/dist/detectors/throughput.js.map +1 -0
  15. package/dist/detectors/token-truth.d.ts +40 -0
  16. package/dist/detectors/token-truth.d.ts.map +1 -0
  17. package/dist/detectors/token-truth.js +145 -0
  18. package/dist/detectors/token-truth.js.map +1 -0
  19. package/dist/handshake.d.ts +23 -0
  20. package/dist/handshake.d.ts.map +1 -0
  21. package/dist/handshake.js +90 -0
  22. package/dist/handshake.js.map +1 -0
  23. package/dist/highlight.d.ts +8 -0
  24. package/dist/highlight.d.ts.map +1 -0
  25. package/dist/highlight.js +63 -0
  26. package/dist/highlight.js.map +1 -0
  27. package/dist/index.d.ts +7 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +7 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/internal/utils.d.ts +6 -0
  32. package/dist/internal/utils.d.ts.map +1 -0
  33. package/dist/internal/utils.js +19 -0
  34. package/dist/internal/utils.js.map +1 -0
  35. package/dist/models.d.ts +5 -0
  36. package/dist/models.d.ts.map +1 -0
  37. package/dist/models.js +54 -0
  38. package/dist/models.js.map +1 -0
  39. package/dist/nonce.d.ts +4 -0
  40. package/dist/nonce.d.ts.map +1 -0
  41. package/dist/nonce.js +12 -0
  42. package/dist/nonce.js.map +1 -0
  43. package/dist/patterns.d.ts +16 -0
  44. package/dist/patterns.d.ts.map +1 -0
  45. package/dist/patterns.js +63 -0
  46. package/dist/patterns.js.map +1 -0
  47. package/dist/probes.d.ts +10 -0
  48. package/dist/probes.d.ts.map +1 -0
  49. package/dist/probes.js +54 -0
  50. package/dist/probes.js.map +1 -0
  51. package/dist/providers/anthropic.d.ts +3 -0
  52. package/dist/providers/anthropic.d.ts.map +1 -0
  53. package/dist/providers/anthropic.js +70 -0
  54. package/dist/providers/anthropic.js.map +1 -0
  55. package/dist/providers/config.d.ts +34 -0
  56. package/dist/providers/config.d.ts.map +1 -0
  57. package/dist/providers/config.js +14 -0
  58. package/dist/providers/config.js.map +1 -0
  59. package/dist/providers/gemini.d.ts +3 -0
  60. package/dist/providers/gemini.d.ts.map +1 -0
  61. package/dist/providers/gemini.js +58 -0
  62. package/dist/providers/gemini.js.map +1 -0
  63. package/dist/providers/openai.d.ts +3 -0
  64. package/dist/providers/openai.d.ts.map +1 -0
  65. package/dist/providers/openai.js +56 -0
  66. package/dist/providers/openai.js.map +1 -0
  67. package/dist/rules.d.ts +6 -0
  68. package/dist/rules.d.ts.map +1 -0
  69. package/dist/rules.js +28 -0
  70. package/dist/rules.js.map +1 -0
  71. package/dist/runner.d.ts +22 -0
  72. package/dist/runner.d.ts.map +1 -0
  73. package/dist/runner.js +298 -0
  74. package/dist/runner.js.map +1 -0
  75. package/dist/signals.d.ts +11 -0
  76. package/dist/signals.d.ts.map +1 -0
  77. package/dist/signals.js +64 -0
  78. package/dist/signals.js.map +1 -0
  79. package/dist/substitution.d.ts +24 -0
  80. package/dist/substitution.d.ts.map +1 -0
  81. package/dist/substitution.js +35 -0
  82. package/dist/substitution.js.map +1 -0
  83. package/dist/transport.d.ts +17 -0
  84. package/dist/transport.d.ts.map +1 -0
  85. package/dist/transport.js +79 -0
  86. package/dist/transport.js.map +1 -0
  87. package/dist/types.d.ts +55 -0
  88. package/dist/types.d.ts.map +1 -0
  89. package/dist/types.js +2 -0
  90. package/dist/types.js.map +1 -0
  91. package/dist/verdict.d.ts +26 -0
  92. package/dist/verdict.d.ts.map +1 -0
  93. package/dist/verdict.js +84 -0
  94. package/dist/verdict.js.map +1 -0
  95. package/package.json +56 -0
package/dist/runner.js ADDED
@@ -0,0 +1,298 @@
1
+ import { checkThinkingSignature } from "./detectors/thinking-signature";
2
+ import { checkTokenTruth } from "./detectors/token-truth";
3
+ import { readResponseMetadata } from "./detectors/response-metadata";
4
+ import { sampleThroughput } from "./detectors/throughput";
5
+ import { sleep } from "./internal/utils";
6
+ import { echoesNonce, makeNonce } from "./nonce";
7
+ import { runHandshake } from "./handshake";
8
+ import { PROBES } from "./probes";
9
+ import { normalizeProbeBaseUrl, PROVIDER_CONFIGS, } from "./providers/config";
10
+ import { detectSignal, isTransientError } from "./signals";
11
+ import { probeTransport } from "./transport";
12
+ import { aggregateVerdict, probeReason } from "./verdict";
13
+ const NONCE_MISMATCH_RETRIES = 2;
14
+ const NONCE_MISMATCH_BACKOFF_MS = 500;
15
+ const DEFAULT_TIMEOUT_MS = 30_000;
16
+ const RESPONSE_CAP = 2000;
17
+ const cap = (text) => text.length > RESPONSE_CAP ? `${text.slice(0, RESPONSE_CAP)}...` : text;
18
+ async function runProbe(args) {
19
+ const probe = args.probe;
20
+ const started = performance.now();
21
+ let lastPrompt = "";
22
+ let weakNonce = null;
23
+ for (let attempt = 0; attempt <= NONCE_MISMATCH_RETRIES; attempt++) {
24
+ if (attempt > 0)
25
+ await sleep(NONCE_MISMATCH_BACKOFF_MS);
26
+ const nonce = makeNonce();
27
+ lastPrompt = probe.buildPrompt(nonce);
28
+ const built = args.cfg.buildRequest({
29
+ baseUrl: args.baseUrl,
30
+ apiKey: args.apiKey,
31
+ model: args.model,
32
+ prompt: lastPrompt,
33
+ maxTokens: probe.maxTokens,
34
+ direct: args.mode === "direct",
35
+ });
36
+ const res = await args.transport({
37
+ mode: args.mode,
38
+ url: built.url,
39
+ headers: built.headers,
40
+ reqBody: built.body,
41
+ timeoutMs: args.timeoutMs,
42
+ });
43
+ if (res.error !== null) {
44
+ const transient = res.corsBlocked ||
45
+ isTransientError(res.error) ||
46
+ (res.status !== null && isTransientError(`HTTP ${res.status}`));
47
+ return {
48
+ label: probe.label,
49
+ pass: false,
50
+ signal: null,
51
+ muxFailure: false,
52
+ transient,
53
+ latencyMs: Math.round(performance.now() - started),
54
+ prompt: lastPrompt,
55
+ responseText: null,
56
+ httpStatus: res.status,
57
+ usage: null,
58
+ detectedModel: null,
59
+ reason: probeReason(false, null, false, transient),
60
+ text: undefined,
61
+ corsBlocked: res.corsBlocked,
62
+ };
63
+ }
64
+ const text = args.cfg.extractText(res.data);
65
+ if (text === null) {
66
+ return {
67
+ label: probe.label,
68
+ pass: false,
69
+ signal: null,
70
+ muxFailure: false,
71
+ transient: false,
72
+ latencyMs: Math.round(performance.now() - started),
73
+ prompt: lastPrompt,
74
+ responseText: null,
75
+ httpStatus: res.status,
76
+ usage: null,
77
+ detectedModel: null,
78
+ reason: "upstream error envelope",
79
+ text: undefined,
80
+ corsBlocked: false,
81
+ };
82
+ }
83
+ if (!echoesNonce(text, nonce)) {
84
+ if (text.trim().length > 0)
85
+ weakNonce = { text, res: { data: res.data, status: res.status } };
86
+ continue; // retry for a clean nonce echo first
87
+ }
88
+ const signal = detectSignal(text, probe.label, args.cfg.foreignIdentityPatterns, args.cfg.cloudModelNamePatterns, args.cfg.acceptsCloudHostIdentity);
89
+ const meta = args.cfg.extractMeta(res.data);
90
+ const pass = probe.evaluate(text, args.cfg);
91
+ return {
92
+ // Derived here because this is the only scope holding the raw payload;
93
+ // the envelope facts are small, the payload itself is not carried.
94
+ envelope: readResponseMetadata(res.data, args.cfg.provider),
95
+ label: probe.label,
96
+ pass,
97
+ signal,
98
+ muxFailure: false,
99
+ transient: false,
100
+ latencyMs: Math.round(performance.now() - started),
101
+ prompt: lastPrompt,
102
+ responseText: cap(text),
103
+ httpStatus: res.status,
104
+ usage: meta.usage,
105
+ detectedModel: meta.detectedModel,
106
+ reason: probeReason(pass, signal, false, false),
107
+ text,
108
+ corsBlocked: false,
109
+ };
110
+ }
111
+ if (weakNonce) {
112
+ const text = weakNonce.text;
113
+ const signal = detectSignal(text, probe.label, args.cfg.foreignIdentityPatterns, args.cfg.cloudModelNamePatterns, args.cfg.acceptsCloudHostIdentity);
114
+ const meta = args.cfg.extractMeta(weakNonce.res.data);
115
+ const pass = probe.evaluate(text, args.cfg);
116
+ return {
117
+ label: probe.label,
118
+ pass,
119
+ signal,
120
+ muxFailure: false,
121
+ transient: false,
122
+ latencyMs: Math.round(performance.now() - started),
123
+ prompt: lastPrompt,
124
+ responseText: cap(text),
125
+ httpStatus: weakNonce.res.status,
126
+ usage: meta.usage,
127
+ detectedModel: meta.detectedModel,
128
+ reason: pass
129
+ ? "passed (no nonce echo)"
130
+ : probeReason(pass, signal, false, false),
131
+ text,
132
+ corsBlocked: false,
133
+ };
134
+ }
135
+ return {
136
+ label: probe.label,
137
+ pass: false,
138
+ signal: null,
139
+ muxFailure: true,
140
+ transient: false,
141
+ latencyMs: Math.round(performance.now() - started),
142
+ prompt: lastPrompt,
143
+ responseText: null,
144
+ httpStatus: null,
145
+ usage: null,
146
+ detectedModel: null,
147
+ reason: probeReason(false, null, true, false),
148
+ text: undefined,
149
+ corsBlocked: false,
150
+ };
151
+ }
152
+ function sumUsage(usages) {
153
+ const present = usages.filter((u) => u !== null);
154
+ if (present.length === 0)
155
+ return null;
156
+ const add = (key) => {
157
+ const vals = present
158
+ .map((u) => u[key])
159
+ .filter((v) => v !== null);
160
+ return vals.length > 0 ? vals.reduce((a, b) => a + b, 0) : null;
161
+ };
162
+ return {
163
+ prompt: add("prompt"),
164
+ completion: add("completion"),
165
+ total: add("total"),
166
+ };
167
+ }
168
+ function hostOf(baseUrl) {
169
+ try {
170
+ return new URL(baseUrl).host;
171
+ }
172
+ catch {
173
+ return baseUrl;
174
+ }
175
+ }
176
+ function connectivityResult(opts, error, corsBlocked, startedAt) {
177
+ return {
178
+ provider: opts.provider,
179
+ model: opts.model,
180
+ baseUrlHost: hostOf(opts.baseUrl),
181
+ verdict: "unverified",
182
+ versionUnverifiable: false,
183
+ probes: [],
184
+ reasons: [error],
185
+ probesPassed: 0,
186
+ probesTotal: 0,
187
+ latencyMs: Math.round(performance.now() - startedAt),
188
+ transport: opts.mode,
189
+ corsBlocked,
190
+ detectedModel: null,
191
+ totalUsage: null,
192
+ resolvedProvider: opts.provider,
193
+ connectivityError: error,
194
+ };
195
+ }
196
+ export async function runVerification(opts) {
197
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
198
+ const transport = opts.transport ?? probeTransport;
199
+ const started = performance.now();
200
+ const hs = await runHandshake({
201
+ provider: opts.provider,
202
+ baseUrl: opts.baseUrl,
203
+ apiKey: opts.apiKey,
204
+ model: opts.model,
205
+ mode: opts.mode,
206
+ timeoutMs,
207
+ transport,
208
+ });
209
+ if (!hs.ok)
210
+ return connectivityResult(opts, hs.reason, hs.corsBlocked, started);
211
+ const resolvedProvider = hs.resolvedProvider;
212
+ const cfg = PROVIDER_CONFIGS[resolvedProvider];
213
+ const results = await Promise.all(PROBES.map((probe) => runProbe({
214
+ probe,
215
+ cfg,
216
+ baseUrl: opts.baseUrl,
217
+ apiKey: opts.apiKey,
218
+ model: opts.model,
219
+ mode: hs.mode,
220
+ timeoutMs,
221
+ transport,
222
+ })));
223
+ // Runs concurrently with nothing else pending, after the probes, so a
224
+ // signature failure can never mask a probe result.
225
+ const signature = opts.checkSignature && resolvedProvider === "anthropic"
226
+ ? await checkThinkingSignature({
227
+ transport,
228
+ baseUrl: normalizeProbeBaseUrl(opts.baseUrl),
229
+ apiKey: opts.apiKey,
230
+ model: opts.model,
231
+ timeoutMs,
232
+ })
233
+ : undefined;
234
+ const tokenTruth = opts.checkTokenTruth && resolvedProvider === "anthropic"
235
+ ? await checkTokenTruth({
236
+ transport,
237
+ baseUrl: normalizeProbeBaseUrl(opts.baseUrl),
238
+ apiKey: opts.apiKey,
239
+ model: opts.model,
240
+ timeoutMs,
241
+ })
242
+ : undefined;
243
+ // Free metadata: derived from probe responses we already paid for.
244
+ const richest = results.reduce((best, r) => (r.usage?.completion ?? 0) > (best?.usage?.completion ?? 0) ? r : best, null);
245
+ const responseMetadata = richest?.envelope;
246
+ const throughput = richest
247
+ ? sampleThroughput({
248
+ lane: hostOf(opts.baseUrl),
249
+ model: opts.model,
250
+ outputTokens: richest.usage?.completion ?? null,
251
+ elapsedMs: richest.latencyMs,
252
+ })
253
+ : null;
254
+ const detectedModel = results.find((r) => r.detectedModel)?.detectedModel ?? null;
255
+ const verdict = aggregateVerdict({
256
+ model: opts.model,
257
+ cfg,
258
+ results,
259
+ detectedModel,
260
+ });
261
+ const corsBlocked = hs.mode === "direct" && results.some((r) => r.corsBlocked);
262
+ return {
263
+ provider: opts.provider,
264
+ model: opts.model,
265
+ baseUrlHost: hostOf(opts.baseUrl),
266
+ verdict: verdict.verdict,
267
+ versionUnverifiable: verdict.versionUnverifiable,
268
+ probes: results.map((r) => ({
269
+ label: r.label,
270
+ pass: r.pass,
271
+ signal: r.signal,
272
+ muxFailure: r.muxFailure,
273
+ transient: r.transient,
274
+ latencyMs: r.latencyMs,
275
+ prompt: r.prompt,
276
+ responseText: r.responseText,
277
+ httpStatus: r.httpStatus,
278
+ usage: r.usage,
279
+ detectedModel: r.detectedModel,
280
+ reason: r.reason,
281
+ })),
282
+ reasons: verdict.reasons,
283
+ probesPassed: results.filter((r) => r.pass).length,
284
+ probesTotal: results.length,
285
+ latencyMs: Math.round(performance.now() - started),
286
+ transport: hs.mode,
287
+ corsBlocked,
288
+ detectedModel,
289
+ totalUsage: sumUsage(results.map((r) => r.usage)),
290
+ resolvedProvider,
291
+ ...(signature ? { signature } : {}),
292
+ ...(tokenTruth ? { tokenTruth } : {}),
293
+ ...(responseMetadata ? { responseMetadata } : {}),
294
+ ...(throughput ? { throughput } : {}),
295
+ connectivityError: null,
296
+ };
297
+ }
298
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { ProbeLabel, ProbeSignal } from "./types";
2
+ export declare const includesAny: (text: string, patterns: string[]) => boolean;
3
+ export declare const hasCodingToolRefusal: (text: string) => boolean;
4
+ export declare const hasScamPage: (text: string) => boolean;
5
+ export declare function cjkLeak(text: string): boolean;
6
+ export declare function hasForeignIdentity(text: string, foreignPatterns: string[], cloudModelNamePatterns: string[], probe: ProbeLabel): boolean;
7
+ export declare function tierOf(text: string, tiers: readonly string[]): string | null;
8
+ export declare function detectTierMismatch(requestedModel: string, modelNameText: string | undefined, tiers: readonly string[]): string | null;
9
+ export declare function detectSignal(text: string, probeLabel: ProbeLabel, foreignPatterns: string[], cloudModelNamePatterns: string[], acceptsCloudHostIdentity: boolean): ProbeSignal;
10
+ export declare function isTransientError(msg: string): boolean;
11
+ //# sourceMappingURL=signals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../src/signals.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEvD,eAAO,MAAM,WAAW,SAAU,MAAM,YAAY,MAAM,EAAE,YACpB,CAAC;AAEzC,eAAO,MAAM,oBAAoB,SAAU,MAAM,YAEA,CAAC;AAElD,eAAO,MAAM,WAAW,SAAU,MAAM,YACD,CAAC;AAExC,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAG7C;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,MAAM,EAAE,EACzB,sBAAsB,EAAE,MAAM,EAAE,EAChC,KAAK,EAAE,UAAU,GAChB,OAAO,CAKT;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAG5E;AAED,wBAAgB,kBAAkB,CAChC,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,MAAM,GAAG,IAAI,CAOf;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,MAAM,EAAE,EACzB,sBAAsB,EAAE,MAAM,EAAE,EAChC,wBAAwB,EAAE,OAAO,GAChC,WAAW,CAuBb;AAID,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAYrD"}
@@ -0,0 +1,64 @@
1
+ import { CJK_CHAR, CJK_LEAK_MIN_CHARS, CLOUD_HOST_PATTERNS, CODING_TOOL_NAMES, CODING_TOOL_REFUSAL_PATTERNS, SCAM_PAGE_PATTERNS, } from "./patterns";
2
+ export const includesAny = (text, patterns) => patterns.some((p) => text.includes(p));
3
+ export const hasCodingToolRefusal = (text) => includesAny(text, CODING_TOOL_NAMES) ||
4
+ includesAny(text, CODING_TOOL_REFUSAL_PATTERNS);
5
+ export const hasScamPage = (text) => includesAny(text, SCAM_PAGE_PATTERNS);
6
+ export function cjkLeak(text) {
7
+ const m = text.match(CJK_CHAR);
8
+ return m !== null && m.length >= CJK_LEAK_MIN_CHARS;
9
+ }
10
+ export function hasForeignIdentity(text, foreignPatterns, cloudModelNamePatterns, probe) {
11
+ if (includesAny(text, foreignPatterns))
12
+ return true;
13
+ if (probe === "model-name" && includesAny(text, cloudModelNamePatterns))
14
+ return true;
15
+ return false;
16
+ }
17
+ export function tierOf(text, tiers) {
18
+ const found = tiers.filter((tier) => text.includes(tier));
19
+ return found.length === 1 ? found[0] : null;
20
+ }
21
+ export function detectTierMismatch(requestedModel, modelNameText, tiers) {
22
+ const reqTier = tierOf(requestedModel.toLowerCase(), tiers);
23
+ if (!reqTier)
24
+ return null;
25
+ if (!modelNameText)
26
+ return null;
27
+ const saidTier = tierOf(modelNameText, tiers);
28
+ if (saidTier && saidTier !== reqTier)
29
+ return saidTier;
30
+ return null;
31
+ }
32
+ export function detectSignal(text, probeLabel, foreignPatterns, cloudModelNamePatterns, acceptsCloudHostIdentity) {
33
+ if (text.length === 0)
34
+ return "blank";
35
+ if (hasCodingToolRefusal(text))
36
+ return "coding-tool";
37
+ if (hasScamPage(text))
38
+ return "scam";
39
+ if (cjkLeak(text))
40
+ return "cjk-leak";
41
+ if (probeLabel === "identity" || probeLabel === "model-name") {
42
+ if (hasForeignIdentity(text, foreignPatterns, cloudModelNamePatterns, probeLabel))
43
+ return "foreign";
44
+ if (probeLabel === "identity" &&
45
+ acceptsCloudHostIdentity &&
46
+ includesAny(text, CLOUD_HOST_PATTERNS))
47
+ return "cloud-host";
48
+ }
49
+ return null;
50
+ }
51
+ const TRANSIENT_HTTP = [408, 425, 429, 500, 502, 503, 504, 520, 522, 524];
52
+ export function isTransientError(msg) {
53
+ const m = msg.match(/HTTP (\d{3})/);
54
+ if (m && TRANSIENT_HTTP.includes(Number(m[1])))
55
+ return true;
56
+ const lower = msg.toLowerCase();
57
+ return (lower.includes("timeout") ||
58
+ lower.includes("timed out") ||
59
+ lower.includes("econnreset") ||
60
+ lower.includes("socket") ||
61
+ lower.includes("network") ||
62
+ lower.includes("fetch failed"));
63
+ }
64
+ //# sourceMappingURL=signals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals.js","sourceRoot":"","sources":["../src/signals.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Envelope-level model substitution: the endpoint answers with a different
3
+ * model id than the one requested.
4
+ *
5
+ * This catches the fraud that every behavioural probe passes, because the reply
6
+ * genuinely IS the vendor's model, just a cheaper one than billed for. It costs
7
+ * nothing: the id is already in the response every probe makes.
8
+ */
9
+ /**
10
+ * Ported from new-api-sync (`core/testing/runner.ts`), where the leniency is
11
+ * load-bearing. A strict comparison once condemned an honest upstream and cost
12
+ * it all ten of its Claude models, so this tolerates the three ways vendors
13
+ * legitimately spell the same model:
14
+ * - separator drift claude-opus-4.8 vs claude-opus-4-8
15
+ * - vendor-qualified ids anthropic/claude-opus-5 vs claude-opus-5
16
+ * - dated snapshots claude-haiku-4-5 vs claude-haiku-4-5-20251001
17
+ */
18
+ export declare function modelsMatch(requested: string, served: string): boolean;
19
+ /**
20
+ * The served id when it contradicts the request, else null. A missing id is not
21
+ * evidence: plenty of honest relays omit it.
22
+ */
23
+ export declare function detectSubstitution(requested: string, detectedModel: string | null | undefined): string | null;
24
+ //# sourceMappingURL=substitution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"substitution.d.ts","sourceRoot":"","sources":["../src/substitution.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAOtE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACvC,MAAM,GAAG,IAAI,CAGf"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Envelope-level model substitution: the endpoint answers with a different
3
+ * model id than the one requested.
4
+ *
5
+ * This catches the fraud that every behavioural probe passes, because the reply
6
+ * genuinely IS the vendor's model, just a cheaper one than billed for. It costs
7
+ * nothing: the id is already in the response every probe makes.
8
+ */
9
+ /**
10
+ * Ported from new-api-sync (`core/testing/runner.ts`), where the leniency is
11
+ * load-bearing. A strict comparison once condemned an honest upstream and cost
12
+ * it all ten of its Claude models, so this tolerates the three ways vendors
13
+ * legitimately spell the same model:
14
+ * - separator drift claude-opus-4.8 vs claude-opus-4-8
15
+ * - vendor-qualified ids anthropic/claude-opus-5 vs claude-opus-5
16
+ * - dated snapshots claude-haiku-4-5 vs claude-haiku-4-5-20251001
17
+ */
18
+ export function modelsMatch(requested, served) {
19
+ const norm = (s) => s.toLowerCase().replace(/[.]/g, "-").split("/").pop() ?? "";
20
+ const a = norm(requested);
21
+ const b = norm(served);
22
+ if (!a || !b)
23
+ return true;
24
+ return a === b || a.startsWith(b) || b.startsWith(a);
25
+ }
26
+ /**
27
+ * The served id when it contradicts the request, else null. A missing id is not
28
+ * evidence: plenty of honest relays omit it.
29
+ */
30
+ export function detectSubstitution(requested, detectedModel) {
31
+ if (!detectedModel)
32
+ return null;
33
+ return modelsMatch(requested, detectedModel) ? null : detectedModel;
34
+ }
35
+ //# sourceMappingURL=substitution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"substitution.js","sourceRoot":"","sources":["../src/substitution.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,SAAiB,EAAE,MAAc;IAC3D,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CACzB,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IAC9D,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1B,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1B,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACvD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,SAAiB,EACjB,aAAwC;IAExC,IAAI,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,WAAW,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC;AACtE,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { TransportMode } from "./types";
2
+ export type TransportResult = {
3
+ status: number | null;
4
+ data: unknown;
5
+ error: string | null;
6
+ corsBlocked: boolean;
7
+ };
8
+ export type TransportArgs = {
9
+ mode: TransportMode;
10
+ url: string;
11
+ headers: Record<string, string>;
12
+ reqBody: unknown;
13
+ timeoutMs: number;
14
+ };
15
+ export type TransportFn = (args: TransportArgs) => Promise<TransportResult>;
16
+ export declare function probeTransport(args: TransportArgs): Promise<TransportResult>;
17
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,aAAa,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;AAgF5E,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAE5E"}
@@ -0,0 +1,79 @@
1
+ import { errMessage, rec } from "./internal/utils";
2
+ // CORS block and dead host both surface as an opaque TypeError
3
+ // (whatwg/fetch#1123). no-cors strips Authorization, so this proves reachability
4
+ // ONLY and its opaque response must never be inspected.
5
+ async function corsBlockedNotUnreachable(url, timeoutMs) {
6
+ try {
7
+ await fetch(url, {
8
+ method: "POST",
9
+ mode: "no-cors",
10
+ body: "{}",
11
+ signal: AbortSignal.timeout(timeoutMs),
12
+ });
13
+ return true;
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ }
19
+ async function direct(args) {
20
+ try {
21
+ const res = await fetch(args.url, {
22
+ method: "POST",
23
+ headers: args.headers,
24
+ body: JSON.stringify(args.reqBody),
25
+ signal: AbortSignal.timeout(args.timeoutMs),
26
+ });
27
+ const data = await res.json().catch(() => null);
28
+ return { status: res.status, data, error: null, corsBlocked: false };
29
+ }
30
+ catch (err) {
31
+ const isAbort = err instanceof DOMException && err.name === "AbortError";
32
+ const msg = errMessage(err);
33
+ return {
34
+ status: null,
35
+ data: null,
36
+ error: isAbort ? "timeout" : msg,
37
+ corsBlocked: !isAbort &&
38
+ err instanceof TypeError &&
39
+ (await corsBlockedNotUnreachable(args.url, args.timeoutMs)),
40
+ };
41
+ }
42
+ }
43
+ async function viaServer(args) {
44
+ try {
45
+ const res = await fetch("/api/models/verify/probe", {
46
+ method: "POST",
47
+ headers: { "content-type": "application/json" },
48
+ body: JSON.stringify({
49
+ url: args.url,
50
+ headers: args.headers,
51
+ reqBody: args.reqBody,
52
+ }),
53
+ signal: AbortSignal.timeout(args.timeoutMs + 5000),
54
+ });
55
+ const wrapped = rec(await res.json().catch(() => null));
56
+ const inner = rec(wrapped?.data);
57
+ if (!inner || typeof inner.status !== "number")
58
+ return {
59
+ status: null,
60
+ data: null,
61
+ error: `proxy HTTP ${res.status}`,
62
+ corsBlocked: false,
63
+ };
64
+ return {
65
+ status: inner.status,
66
+ data: inner.data,
67
+ error: null,
68
+ corsBlocked: false,
69
+ };
70
+ }
71
+ catch (err) {
72
+ const msg = errMessage(err);
73
+ return { status: null, data: null, error: msg, corsBlocked: false };
74
+ }
75
+ }
76
+ export function probeTransport(args) {
77
+ return args.mode === "server" ? viaServer(args) : direct(args);
78
+ }
79
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import type { SignatureResult } from "./detectors/thinking-signature";
2
+ import type { TokenTruthResult } from "./detectors/token-truth";
3
+ import type { ResponseMetadata } from "./detectors/response-metadata";
4
+ import type { ThroughputSample } from "./detectors/throughput";
5
+ export type VerifyProvider = "anthropic" | "openai" | "gemini";
6
+ export type VerifyVerdict = "genuine" | "suspicious" | "unverified";
7
+ export type ProbeLabel = "emotional" | "creative" | "identity" | "model-name";
8
+ export type ProbeSignal = "coding-tool" | "scam" | "foreign" | "cloud-host" | "cjk-leak" | "blank" | null;
9
+ export type TransportMode = "direct" | "server";
10
+ export type ProbeUsage = {
11
+ prompt: number | null;
12
+ completion: number | null;
13
+ total: number | null;
14
+ };
15
+ export type ProbeOutcome = {
16
+ label: ProbeLabel;
17
+ pass: boolean;
18
+ signal: ProbeSignal;
19
+ muxFailure: boolean;
20
+ transient: boolean;
21
+ latencyMs: number;
22
+ prompt: string;
23
+ responseText: string | null;
24
+ httpStatus: number | null;
25
+ usage: ProbeUsage | null;
26
+ detectedModel: string | null;
27
+ reason: string | null;
28
+ };
29
+ export type VerifyResult = {
30
+ provider: VerifyProvider;
31
+ model: string;
32
+ baseUrlHost: string;
33
+ verdict: VerifyVerdict;
34
+ versionUnverifiable: boolean;
35
+ probes: ProbeOutcome[];
36
+ reasons: string[];
37
+ probesPassed: number;
38
+ probesTotal: number;
39
+ latencyMs: number;
40
+ transport: TransportMode;
41
+ corsBlocked: boolean;
42
+ detectedModel: string | null;
43
+ totalUsage: ProbeUsage | null;
44
+ resolvedProvider: VerifyProvider;
45
+ /** Present only when the signature check was requested and could run. */
46
+ signature?: SignatureResult;
47
+ /** Present only when the token-accounting check was requested. */
48
+ tokenTruth?: TokenTruthResult;
49
+ /** Envelope observations, free: read from responses already collected. */
50
+ responseMetadata?: ResponseMetadata;
51
+ /** Output rate, when a probe generated enough tokens to measure one. */
52
+ throughput?: ThroughputSample | null;
53
+ connectivityError: "cors-needs-backend" | "unreachable" | "invalid-key" | "no-format" | null;
54
+ };
55
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE/D,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,YAAY,GAAG,YAAY,CAAC;AAEpE,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,UAAU,GAAG,YAAY,CAAC;AAE9E,MAAM,MAAM,WAAW,GACnB,aAAa,GACb,MAAM,GACN,SAAS,GACT,YAAY,GACZ,UAAU,GACV,OAAO,GACP,IAAI,CAAC;AAET,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEhD,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,aAAa,CAAC;IACvB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,aAAa,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,gBAAgB,EAAE,cAAc,CAAC;IACjC,yEAAyE;IACzE,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,kEAAkE;IAClE,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,wEAAwE;IACxE,UAAU,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACrC,iBAAiB,EACf,oBAAoB,GAAG,aAAa,GAAG,aAAa,GAAG,WAAW,GAAG,IAAI,CAAC;CAC7E,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}