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.
- package/LICENSE +661 -0
- package/README.md +40 -0
- package/dist/detectors/response-metadata.d.ts +36 -0
- package/dist/detectors/response-metadata.d.ts.map +1 -0
- package/dist/detectors/response-metadata.js +91 -0
- package/dist/detectors/response-metadata.js.map +1 -0
- package/dist/detectors/thinking-signature.d.ts +70 -0
- package/dist/detectors/thinking-signature.d.ts.map +1 -0
- package/dist/detectors/thinking-signature.js +177 -0
- package/dist/detectors/thinking-signature.js.map +1 -0
- package/dist/detectors/throughput.d.ts +51 -0
- package/dist/detectors/throughput.d.ts.map +1 -0
- package/dist/detectors/throughput.js +83 -0
- package/dist/detectors/throughput.js.map +1 -0
- package/dist/detectors/token-truth.d.ts +40 -0
- package/dist/detectors/token-truth.d.ts.map +1 -0
- package/dist/detectors/token-truth.js +145 -0
- package/dist/detectors/token-truth.js.map +1 -0
- package/dist/handshake.d.ts +23 -0
- package/dist/handshake.d.ts.map +1 -0
- package/dist/handshake.js +90 -0
- package/dist/handshake.js.map +1 -0
- package/dist/highlight.d.ts +8 -0
- package/dist/highlight.d.ts.map +1 -0
- package/dist/highlight.js +63 -0
- package/dist/highlight.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/utils.d.ts +6 -0
- package/dist/internal/utils.d.ts.map +1 -0
- package/dist/internal/utils.js +19 -0
- package/dist/internal/utils.js.map +1 -0
- package/dist/models.d.ts +5 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +54 -0
- package/dist/models.js.map +1 -0
- package/dist/nonce.d.ts +4 -0
- package/dist/nonce.d.ts.map +1 -0
- package/dist/nonce.js +12 -0
- package/dist/nonce.js.map +1 -0
- package/dist/patterns.d.ts +16 -0
- package/dist/patterns.d.ts.map +1 -0
- package/dist/patterns.js +63 -0
- package/dist/patterns.js.map +1 -0
- package/dist/probes.d.ts +10 -0
- package/dist/probes.d.ts.map +1 -0
- package/dist/probes.js +54 -0
- package/dist/probes.js.map +1 -0
- package/dist/providers/anthropic.d.ts +3 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +70 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/config.d.ts +34 -0
- package/dist/providers/config.d.ts.map +1 -0
- package/dist/providers/config.js +14 -0
- package/dist/providers/config.js.map +1 -0
- package/dist/providers/gemini.d.ts +3 -0
- package/dist/providers/gemini.d.ts.map +1 -0
- package/dist/providers/gemini.js +58 -0
- package/dist/providers/gemini.js.map +1 -0
- package/dist/providers/openai.d.ts +3 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +56 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/rules.d.ts +6 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/rules.js +28 -0
- package/dist/rules.js.map +1 -0
- package/dist/runner.d.ts +22 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +298 -0
- package/dist/runner.js.map +1 -0
- package/dist/signals.d.ts +11 -0
- package/dist/signals.d.ts.map +1 -0
- package/dist/signals.js +64 -0
- package/dist/signals.js.map +1 -0
- package/dist/substitution.d.ts +24 -0
- package/dist/substitution.d.ts.map +1 -0
- package/dist/substitution.js +35 -0
- package/dist/substitution.js.map +1 -0
- package/dist/transport.d.ts +17 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +79 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +55 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/verdict.d.ts +26 -0
- package/dist/verdict.d.ts.map +1 -0
- package/dist/verdict.js +84 -0
- package/dist/verdict.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token-accounting checks for Anthropic endpoints.
|
|
3
|
+
*
|
|
4
|
+
* The signature check answers "is this really Claude". These answer a different
|
|
5
|
+
* question the signature cannot: "are the numbers you are billing me true".
|
|
6
|
+
* A relay can forward genuine Claude and still inflate `input_tokens` on every
|
|
7
|
+
* call, and nothing in an identity probe would notice.
|
|
8
|
+
*
|
|
9
|
+
* Ported from veridrop (AGPL-3.0) `token_usage.py` / `integrity.py`, whose
|
|
10
|
+
* tolerances were calibrated against the official API. Do not tighten them
|
|
11
|
+
* without re-measuring: the loose-looking bounds exist because real Anthropic
|
|
12
|
+
* responses sat near them.
|
|
13
|
+
*/
|
|
14
|
+
const SHORT_PROMPT = "Reply with exactly: ok";
|
|
15
|
+
/** The long variant adds a fixed run of tokens; the delta is what we check. */
|
|
16
|
+
const LONG_PROMPT = `${SHORT_PROMPT}\n\nReference text:${" apple".repeat(80)}`;
|
|
17
|
+
const MAX_TOKENS = 16;
|
|
18
|
+
/**
|
|
19
|
+
* Expected `input_tokens` growth between the short and long prompt.
|
|
20
|
+
*
|
|
21
|
+
* Two bands because Anthropic changed tokenizer: opus-4-7/4-8 encode that same
|
|
22
|
+
* text into materially more tokens. A relay claiming a new-tokenizer model
|
|
23
|
+
* while serving an older one lands in the wrong band, which makes this a tier
|
|
24
|
+
* check as well as a billing check.
|
|
25
|
+
*/
|
|
26
|
+
const DELTA_OLD = { min: 45, max: 140 };
|
|
27
|
+
const DELTA_NEW = { min: 90, max: 230 };
|
|
28
|
+
const NEW_TOKENIZER_MODELS = ["claude-opus-4-7", "claude-opus-4-8"];
|
|
29
|
+
/** `count_tokens` should agree with the billed `input_tokens` this closely. */
|
|
30
|
+
const countTolerance = (n) => Math.max(4, Math.round(n * 0.2));
|
|
31
|
+
const normalize = (model) => model.toLowerCase().replace(/[._]/g, "-").split("/").pop() ?? "";
|
|
32
|
+
export function expectedInputDelta(model) {
|
|
33
|
+
const m = normalize(model);
|
|
34
|
+
return NEW_TOKENIZER_MODELS.some((p) => m.startsWith(p))
|
|
35
|
+
? DELTA_NEW
|
|
36
|
+
: DELTA_OLD;
|
|
37
|
+
}
|
|
38
|
+
/** Rejects booleans, which are `typeof "number"`-adjacent traps in JS. */
|
|
39
|
+
function intOf(v) {
|
|
40
|
+
return typeof v === "number" && Number.isInteger(v) && v >= 0 ? v : null;
|
|
41
|
+
}
|
|
42
|
+
function usageOf(data) {
|
|
43
|
+
const u = data?.usage;
|
|
44
|
+
return { input: intOf(u?.input_tokens), output: intOf(u?.output_tokens) };
|
|
45
|
+
}
|
|
46
|
+
export async function checkTokenTruth(opts) {
|
|
47
|
+
const base = opts.baseUrl.replace(/\/+$/, "");
|
|
48
|
+
const headers = {
|
|
49
|
+
"Content-Type": "application/json",
|
|
50
|
+
"x-api-key": opts.apiKey,
|
|
51
|
+
"anthropic-version": "2023-06-01",
|
|
52
|
+
};
|
|
53
|
+
const ask = (prompt) => opts.transport({
|
|
54
|
+
mode: "direct",
|
|
55
|
+
url: `${base}/v1/messages`,
|
|
56
|
+
headers,
|
|
57
|
+
reqBody: {
|
|
58
|
+
model: opts.model,
|
|
59
|
+
max_tokens: MAX_TOKENS,
|
|
60
|
+
messages: [{ role: "user", content: prompt }],
|
|
61
|
+
},
|
|
62
|
+
timeoutMs: opts.timeoutMs,
|
|
63
|
+
});
|
|
64
|
+
const [shortRes, longRes] = await Promise.all([
|
|
65
|
+
ask(SHORT_PROMPT),
|
|
66
|
+
ask(LONG_PROMPT),
|
|
67
|
+
]);
|
|
68
|
+
const noCounts = {
|
|
69
|
+
shortInputTokens: null,
|
|
70
|
+
longInputTokens: null,
|
|
71
|
+
countTokens: null,
|
|
72
|
+
};
|
|
73
|
+
if (shortRes.status === null || shortRes.status >= 400)
|
|
74
|
+
return {
|
|
75
|
+
ok: null,
|
|
76
|
+
checks: [],
|
|
77
|
+
...noCounts,
|
|
78
|
+
reason: `probe-failed:${shortRes.status ?? "network"}`,
|
|
79
|
+
};
|
|
80
|
+
const s = usageOf(shortRes.data);
|
|
81
|
+
const l = usageOf(longRes.data);
|
|
82
|
+
const checks = [];
|
|
83
|
+
const usagePresent = s.input !== null && l.input !== null;
|
|
84
|
+
checks.push({
|
|
85
|
+
id: "usage-present",
|
|
86
|
+
pass: usagePresent,
|
|
87
|
+
detail: usagePresent
|
|
88
|
+
? `short=${s.input}, long=${l.input}`
|
|
89
|
+
: "endpoint reported no usage counts",
|
|
90
|
+
});
|
|
91
|
+
// Without usage there is nothing to verify; a missing field is not fraud.
|
|
92
|
+
if (!usagePresent)
|
|
93
|
+
return { ok: null, checks, ...noCounts, reason: "no-usage-reported" };
|
|
94
|
+
const band = expectedInputDelta(opts.model);
|
|
95
|
+
const delta = l.input - s.input;
|
|
96
|
+
const deltaOk = delta >= band.min && delta <= band.max;
|
|
97
|
+
checks.push({
|
|
98
|
+
id: "input-delta",
|
|
99
|
+
pass: deltaOk,
|
|
100
|
+
detail: `delta=${delta}, expected ${band.min}-${band.max}`,
|
|
101
|
+
});
|
|
102
|
+
// Output above the cap we set means the count is invented, not merely padded.
|
|
103
|
+
const outputs = [s.output, l.output].filter((v) => v !== null);
|
|
104
|
+
const outputOk = outputs.every((v) => v > 0 && v <= MAX_TOKENS + 4);
|
|
105
|
+
checks.push({
|
|
106
|
+
id: "output-bounded",
|
|
107
|
+
pass: outputOk,
|
|
108
|
+
detail: `outputs=${outputs.join(",") || "none"} (cap ${MAX_TOKENS})`,
|
|
109
|
+
});
|
|
110
|
+
// The same upstream pricing the same request without generating: the
|
|
111
|
+
// strongest anti-inflation signal available, when the endpoint exposes it.
|
|
112
|
+
let counted = null;
|
|
113
|
+
const countRes = await opts.transport({
|
|
114
|
+
mode: "direct",
|
|
115
|
+
url: `${base}/v1/messages/count_tokens`,
|
|
116
|
+
headers,
|
|
117
|
+
reqBody: {
|
|
118
|
+
model: opts.model,
|
|
119
|
+
messages: [{ role: "user", content: SHORT_PROMPT }],
|
|
120
|
+
},
|
|
121
|
+
timeoutMs: opts.timeoutMs,
|
|
122
|
+
});
|
|
123
|
+
if (countRes.status !== null && countRes.status < 400) {
|
|
124
|
+
counted = intOf(countRes.data?.input_tokens);
|
|
125
|
+
if (counted !== null) {
|
|
126
|
+
const drift = Math.abs(counted - s.input);
|
|
127
|
+
const tol = countTolerance(s.input);
|
|
128
|
+
checks.push({
|
|
129
|
+
id: "count-tokens",
|
|
130
|
+
pass: drift <= tol,
|
|
131
|
+
detail: `count=${counted} vs billed=${s.input}, drift=${drift} (tolerance ${tol})`,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// A missing count_tokens endpoint is common on relays and proves nothing, so
|
|
136
|
+
// it is simply absent from the checks rather than counted as a failure.
|
|
137
|
+
return {
|
|
138
|
+
ok: checks.every((c) => c.pass),
|
|
139
|
+
checks,
|
|
140
|
+
shortInputTokens: s.input,
|
|
141
|
+
longInputTokens: l.input,
|
|
142
|
+
countTokens: counted,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=token-truth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-truth.js","sourceRoot":"","sources":["../../src/detectors/token-truth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type TransportFn } from "./transport";
|
|
2
|
+
import type { TransportMode, VerifyProvider } from "./types";
|
|
3
|
+
export type HandshakeOutcome = {
|
|
4
|
+
ok: true;
|
|
5
|
+
resolvedProvider: VerifyProvider;
|
|
6
|
+
mode: TransportMode;
|
|
7
|
+
status: number;
|
|
8
|
+
} | {
|
|
9
|
+
ok: false;
|
|
10
|
+
reason: "cors-needs-backend" | "unreachable" | "invalid-key" | "no-format";
|
|
11
|
+
status: number | null;
|
|
12
|
+
corsBlocked: boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare function runHandshake(opts: {
|
|
15
|
+
provider: VerifyProvider;
|
|
16
|
+
baseUrl: string;
|
|
17
|
+
apiKey: string;
|
|
18
|
+
model: string;
|
|
19
|
+
mode: TransportMode;
|
|
20
|
+
timeoutMs: number;
|
|
21
|
+
transport?: TransportFn;
|
|
22
|
+
}): Promise<HandshakeOutcome>;
|
|
23
|
+
//# sourceMappingURL=handshake.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handshake.d.ts","sourceRoot":"","sources":["../src/handshake.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE7D,MAAM,MAAM,gBAAgB,GACxB;IACE,EAAE,EAAE,IAAI,CAAC;IACT,gBAAgB,EAAE,cAAc,CAAC;IACjC,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EACJ,oBAAoB,GAAG,aAAa,GAAG,aAAa,GAAG,WAAW,CAAC;IACrE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAwDN,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,aAAa,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,WAAW,CAAC;CACzB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAiD5B"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { PROVIDER_CONFIGS } from "./providers/config";
|
|
2
|
+
import { probeTransport } from "./transport";
|
|
3
|
+
import { isTransientError } from "./signals";
|
|
4
|
+
const HANDSHAKE_PROMPT = "hi";
|
|
5
|
+
const HANDSHAKE_MAX_TOKENS = 1;
|
|
6
|
+
function classifyStatus(status) {
|
|
7
|
+
if (status >= 200 && status < 300)
|
|
8
|
+
return "ok";
|
|
9
|
+
if (status === 401 || status === 403)
|
|
10
|
+
return "auth";
|
|
11
|
+
if (isTransientError(`HTTP ${status}`))
|
|
12
|
+
return "transient";
|
|
13
|
+
if (status >= 400 && status < 500)
|
|
14
|
+
return "format";
|
|
15
|
+
return "transient";
|
|
16
|
+
}
|
|
17
|
+
async function tryFormat(args) {
|
|
18
|
+
const cfg = PROVIDER_CONFIGS[args.provider];
|
|
19
|
+
const built = cfg.buildRequest({
|
|
20
|
+
baseUrl: args.baseUrl,
|
|
21
|
+
apiKey: args.apiKey,
|
|
22
|
+
model: args.model,
|
|
23
|
+
prompt: HANDSHAKE_PROMPT,
|
|
24
|
+
maxTokens: HANDSHAKE_MAX_TOKENS,
|
|
25
|
+
direct: args.mode === "direct",
|
|
26
|
+
});
|
|
27
|
+
const res = await args.transport({
|
|
28
|
+
mode: args.mode,
|
|
29
|
+
url: built.url,
|
|
30
|
+
headers: built.headers,
|
|
31
|
+
reqBody: built.body,
|
|
32
|
+
timeoutMs: args.timeoutMs,
|
|
33
|
+
});
|
|
34
|
+
if (res.corsBlocked)
|
|
35
|
+
return { outcome: "cors", status: null, corsBlocked: true };
|
|
36
|
+
if (res.status === null)
|
|
37
|
+
return { outcome: "transient", status: null, corsBlocked: false };
|
|
38
|
+
return {
|
|
39
|
+
outcome: classifyStatus(res.status),
|
|
40
|
+
status: res.status,
|
|
41
|
+
corsBlocked: false,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export async function runHandshake(opts) {
|
|
45
|
+
const transport = opts.transport ?? probeTransport;
|
|
46
|
+
const order = opts.provider === "openai" ? ["openai"] : [opts.provider, "openai"];
|
|
47
|
+
let sawAuth = false;
|
|
48
|
+
let lastStatus = null;
|
|
49
|
+
for (const provider of order) {
|
|
50
|
+
const r = await tryFormat({ ...opts, provider, transport });
|
|
51
|
+
lastStatus = r.status;
|
|
52
|
+
if (r.outcome === "cors")
|
|
53
|
+
return {
|
|
54
|
+
ok: false,
|
|
55
|
+
reason: "cors-needs-backend",
|
|
56
|
+
status: null,
|
|
57
|
+
corsBlocked: true,
|
|
58
|
+
};
|
|
59
|
+
if (r.outcome === "ok")
|
|
60
|
+
return {
|
|
61
|
+
ok: true,
|
|
62
|
+
resolvedProvider: provider,
|
|
63
|
+
mode: opts.mode,
|
|
64
|
+
status: r.status,
|
|
65
|
+
};
|
|
66
|
+
if (r.outcome === "auth")
|
|
67
|
+
sawAuth = true;
|
|
68
|
+
}
|
|
69
|
+
if (sawAuth)
|
|
70
|
+
return {
|
|
71
|
+
ok: false,
|
|
72
|
+
reason: "invalid-key",
|
|
73
|
+
status: lastStatus,
|
|
74
|
+
corsBlocked: false,
|
|
75
|
+
};
|
|
76
|
+
if (lastStatus === null)
|
|
77
|
+
return {
|
|
78
|
+
ok: false,
|
|
79
|
+
reason: "unreachable",
|
|
80
|
+
status: null,
|
|
81
|
+
corsBlocked: false,
|
|
82
|
+
};
|
|
83
|
+
return {
|
|
84
|
+
ok: false,
|
|
85
|
+
reason: "no-format",
|
|
86
|
+
status: lastStatus,
|
|
87
|
+
corsBlocked: false,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=handshake.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handshake.js","sourceRoot":"","sources":["../src/handshake.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { VerifyProvider } from "./types";
|
|
2
|
+
export type HighlightKind = "foreign" | "cjk" | "coding-tool" | "scam" | "home" | null;
|
|
3
|
+
export type HighlightSegment = {
|
|
4
|
+
text: string;
|
|
5
|
+
kind: HighlightKind;
|
|
6
|
+
};
|
|
7
|
+
export declare function highlightSpans(text: string, providerKind: VerifyProvider, probeLabel: string): HighlightSegment[];
|
|
8
|
+
//# sourceMappingURL=highlight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"highlight.d.ts","sourceRoot":"","sources":["../src/highlight.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,aAAa,GACvB,SAAS,GAAG,KAAK,GAAG,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAE7D,MAAM,MAAM,gBAAgB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAoBrE,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,cAAc,EAC5B,UAAU,EAAE,MAAM,GACjB,gBAAgB,EAAE,CA6CpB"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { CJK_CHAR, CODING_TOOL_NAMES, CODING_TOOL_REFUSAL_PATTERNS, SCAM_PAGE_PATTERNS, } from "./patterns";
|
|
2
|
+
import { PROVIDER_CONFIGS } from "./providers/config";
|
|
3
|
+
function collectPhrase(lower, phrases, kind) {
|
|
4
|
+
const out = [];
|
|
5
|
+
for (const phrase of phrases) {
|
|
6
|
+
if (!phrase)
|
|
7
|
+
continue;
|
|
8
|
+
const needle = phrase.toLowerCase();
|
|
9
|
+
let from = 0;
|
|
10
|
+
for (;;) {
|
|
11
|
+
const idx = lower.indexOf(needle, from);
|
|
12
|
+
if (idx === -1)
|
|
13
|
+
break;
|
|
14
|
+
out.push({ start: idx, end: idx + needle.length, kind });
|
|
15
|
+
from = idx + needle.length;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
export function highlightSpans(text, providerKind, probeLabel) {
|
|
21
|
+
if (!text)
|
|
22
|
+
return [];
|
|
23
|
+
const cfg = PROVIDER_CONFIGS[providerKind];
|
|
24
|
+
if (!cfg)
|
|
25
|
+
return [{ text, kind: null }];
|
|
26
|
+
const lower = text.toLowerCase();
|
|
27
|
+
const matches = [
|
|
28
|
+
...collectPhrase(lower, CODING_TOOL_NAMES, "coding-tool"),
|
|
29
|
+
...collectPhrase(lower, CODING_TOOL_REFUSAL_PATTERNS, "coding-tool"),
|
|
30
|
+
...collectPhrase(lower, SCAM_PAGE_PATTERNS, "scam"),
|
|
31
|
+
...collectPhrase(lower, cfg.foreignIdentityPatterns, "foreign"),
|
|
32
|
+
...collectPhrase(lower, cfg.homeIdentityPatterns, "home"),
|
|
33
|
+
...collectPhrase(lower, cfg.homeModelNamePatterns, "home"),
|
|
34
|
+
];
|
|
35
|
+
if (probeLabel === "model-name")
|
|
36
|
+
matches.push(...collectPhrase(lower, cfg.cloudModelNamePatterns, "foreign"));
|
|
37
|
+
for (const m of text.matchAll(CJK_CHAR))
|
|
38
|
+
if (m.index !== undefined)
|
|
39
|
+
matches.push({ start: m.index, end: m.index + m[0].length, kind: "cjk" });
|
|
40
|
+
if (matches.length === 0)
|
|
41
|
+
return [{ text, kind: null }];
|
|
42
|
+
matches.sort((a, b) => a.start - b.start || b.end - a.end);
|
|
43
|
+
const merged = [];
|
|
44
|
+
let cursor = 0;
|
|
45
|
+
for (const m of matches) {
|
|
46
|
+
if (m.start < cursor)
|
|
47
|
+
continue;
|
|
48
|
+
merged.push(m);
|
|
49
|
+
cursor = m.end;
|
|
50
|
+
}
|
|
51
|
+
const segments = [];
|
|
52
|
+
let pos = 0;
|
|
53
|
+
for (const m of merged) {
|
|
54
|
+
if (m.start > pos)
|
|
55
|
+
segments.push({ text: text.slice(pos, m.start), kind: null });
|
|
56
|
+
segments.push({ text: text.slice(m.start, m.end), kind: m.kind });
|
|
57
|
+
pos = m.end;
|
|
58
|
+
}
|
|
59
|
+
if (pos < text.length)
|
|
60
|
+
segments.push({ text: text.slice(pos), kind: null });
|
|
61
|
+
return segments;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=highlight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"highlight.js","sourceRoot":"","sources":["../src/highlight.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from "./types";
|
|
2
|
+
export * from "./rules";
|
|
3
|
+
export { runVerification } from "./runner";
|
|
4
|
+
export { normalizeProbeBaseUrl } from "./providers/config";
|
|
5
|
+
export type { ProviderConfig, ProbeRequestArgs, BuiltRequest, ProbeMeta, } from "./providers/config";
|
|
6
|
+
export type { TransportFn, TransportArgs, TransportResult } from "./transport";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,SAAS,GACV,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Root export: types, the runner and the rule registry. Providers and detectors
|
|
2
|
+
// have their own entry points so a consumer only bundles what it enables.
|
|
3
|
+
export * from "./types";
|
|
4
|
+
export * from "./rules";
|
|
5
|
+
export { runVerification } from "./runner";
|
|
6
|
+
export { normalizeProbeBaseUrl } from "./providers/config";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,0EAA0E;AAC1E,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function isRecord(v: unknown): v is Record<string, unknown>;
|
|
2
|
+
export declare function rec(v: unknown): Record<string, unknown> | undefined;
|
|
3
|
+
export declare function isOneOf<const T extends readonly unknown[]>(values: T): (v: unknown) => v is T[number];
|
|
4
|
+
export declare function errMessage(err: unknown): string;
|
|
5
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/internal/utils.ts"],"names":[],"mappings":"AAIA,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEjE;AAED,wBAAgB,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAEnE;AAED,wBAAgB,OAAO,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,OAAO,EAAE,EACxD,MAAM,EAAE,CAAC,GACR,CAAC,CAAC,EAAE,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAEhC;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAE/C;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Vendored from unorouter's src/lib/utils/base.ts so the package stays
|
|
2
|
+
// dependency-free. Four helpers, copied verbatim; keep them in step if the
|
|
3
|
+
// originals change.
|
|
4
|
+
export function isRecord(v) {
|
|
5
|
+
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
6
|
+
}
|
|
7
|
+
export function rec(v) {
|
|
8
|
+
return isRecord(v) ? v : undefined;
|
|
9
|
+
}
|
|
10
|
+
export function isOneOf(values) {
|
|
11
|
+
return (v) => values.some((x) => x === v);
|
|
12
|
+
}
|
|
13
|
+
export function errMessage(err) {
|
|
14
|
+
return err instanceof Error ? err.message : String(err);
|
|
15
|
+
}
|
|
16
|
+
export function sleep(ms) {
|
|
17
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/internal/utils.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,2EAA2E;AAC3E,oBAAoB;AAEpB,MAAM,UAAU,QAAQ,CAAC,CAAU;IACjC,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,CAAU;IAC5B,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,OAAO,CACrB,MAAS;IAET,OAAO,CAAC,CAAC,EAAkB,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAY;IACrC,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC"}
|
package/dist/models.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { VerifyProvider } from "./types";
|
|
2
|
+
export declare const CURATED_MODELS: Record<VerifyProvider, readonly string[]>;
|
|
3
|
+
export declare function vendorForRow(provider: VerifyProvider, model?: string): string;
|
|
4
|
+
export declare function providerForModel(model: string): VerifyProvider | null;
|
|
5
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAU9C,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAUpE,CAAC;AAgBF,wBAAgB,YAAY,CAAC,QAAQ,EAAE,cAAc,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAG7E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAerE"}
|
package/dist/models.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { isOneOf } from "./internal/utils";
|
|
2
|
+
const VERIFY_PROVIDERS = [
|
|
3
|
+
"anthropic",
|
|
4
|
+
"openai",
|
|
5
|
+
"gemini",
|
|
6
|
+
];
|
|
7
|
+
const isVerifyProvider = isOneOf(VERIFY_PROVIDERS);
|
|
8
|
+
export const CURATED_MODELS = {
|
|
9
|
+
anthropic: [
|
|
10
|
+
"claude-opus-4-6",
|
|
11
|
+
"claude-opus-4-7",
|
|
12
|
+
"claude-opus-4-8",
|
|
13
|
+
"claude-sonnet-4-6",
|
|
14
|
+
"claude-haiku-4-5",
|
|
15
|
+
],
|
|
16
|
+
openai: ["gpt-5.5", "gpt-5.4", "gpt-5.1", "o3", "o4-mini"],
|
|
17
|
+
gemini: ["gemini-3.1-pro-preview", "gemini-3.1-flash", "gemini-2.5-pro"],
|
|
18
|
+
};
|
|
19
|
+
const MODEL_TO_PROVIDER = {};
|
|
20
|
+
for (const provider of Object.keys(CURATED_MODELS)) {
|
|
21
|
+
if (!isVerifyProvider(provider))
|
|
22
|
+
continue;
|
|
23
|
+
for (const model of CURATED_MODELS[provider]) {
|
|
24
|
+
MODEL_TO_PROVIDER[model] = provider;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const PROVIDER_VENDOR = {
|
|
28
|
+
anthropic: "anthropic",
|
|
29
|
+
openai: "openai",
|
|
30
|
+
gemini: "google",
|
|
31
|
+
};
|
|
32
|
+
export function vendorForRow(provider, model) {
|
|
33
|
+
const inferred = model ? providerForModel(model) : null;
|
|
34
|
+
return PROVIDER_VENDOR[inferred ?? provider];
|
|
35
|
+
}
|
|
36
|
+
export function providerForModel(model) {
|
|
37
|
+
const id = model.trim().toLowerCase();
|
|
38
|
+
if (!id)
|
|
39
|
+
return null;
|
|
40
|
+
if (MODEL_TO_PROVIDER[id])
|
|
41
|
+
return MODEL_TO_PROVIDER[id];
|
|
42
|
+
if (id.includes("claude"))
|
|
43
|
+
return "anthropic";
|
|
44
|
+
if (id.includes("gemini"))
|
|
45
|
+
return "gemini";
|
|
46
|
+
if (id.startsWith("gpt-") ||
|
|
47
|
+
id.startsWith("o1") ||
|
|
48
|
+
id.startsWith("o3") ||
|
|
49
|
+
id.startsWith("o4") ||
|
|
50
|
+
id.startsWith("chatgpt"))
|
|
51
|
+
return "openai";
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAG3C,MAAM,gBAAgB,GAA8B;IAClD,WAAW;IACX,QAAQ;IACR,QAAQ;CACT,CAAC;AAEF,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAEnD,MAAM,CAAC,MAAM,cAAc,GAA8C;IACvE,SAAS,EAAE;QACT,iBAAiB;QACjB,iBAAiB;QACjB,iBAAiB;QACjB,mBAAmB;QACnB,kBAAkB;KACnB;IACD,MAAM,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC;IAC1D,MAAM,EAAE,CAAC,wBAAwB,EAAE,kBAAkB,EAAE,gBAAgB,CAAC;CACzE,CAAC;AAEF,MAAM,iBAAiB,GAAmC,EAAE,CAAC;AAC7D,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;IACnD,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;QAAE,SAAS;IAC1C,KAAK,MAAM,KAAK,IAAI,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7C,iBAAiB,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;IACtC,CAAC;AACH,CAAC;AAED,MAAM,eAAe,GAAmC;IACtD,SAAS,EAAE,WAAW;IACtB,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;CACjB,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,QAAwB,EAAE,KAAc;IACnE,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACxD,OAAO,eAAe,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACtC,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACrB,IAAI,iBAAiB,CAAC,EAAE,CAAC;QAAE,OAAO,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACxD,IAAI,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,WAAW,CAAC;IAC9C,IAAI,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC3C,IACE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QACrB,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QACnB,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QACnB,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QACnB,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;QAExB,OAAO,QAAQ,CAAC;IAClB,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/nonce.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nonce.d.ts","sourceRoot":"","sources":["../src/nonce.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,IAAI,MAAM,CAIlC;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAEhE"}
|
package/dist/nonce.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function makeNonce() {
|
|
2
|
+
const bytes = new Uint8Array(4);
|
|
3
|
+
crypto.getRandomValues(bytes);
|
|
4
|
+
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
5
|
+
}
|
|
6
|
+
export function nonceTag(nonce) {
|
|
7
|
+
return `Begin your reply with the tag [${nonce}] then a space, then your answer.`;
|
|
8
|
+
}
|
|
9
|
+
export function echoesNonce(text, nonce) {
|
|
10
|
+
return text.includes(nonce.toLowerCase());
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=nonce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nonce.js","sourceRoot":"","sources":["../src/nonce.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,SAAS;IACvB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAa;IACpC,OAAO,kCAAkC,KAAK,mCAAmC,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,KAAa;IACrD,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const CODING_TOOL_REFUSAL_PATTERNS: string[];
|
|
2
|
+
export declare const CODING_TOOL_NAMES: string[];
|
|
3
|
+
export declare const SCAM_PAGE_PATTERNS: string[];
|
|
4
|
+
export declare const VENDOR_PATTERNS: {
|
|
5
|
+
readonly anthropic: readonly ["anthropic", "claude"];
|
|
6
|
+
readonly openai: readonly ["openai", "chatgpt", "gpt-3", "gpt-4", "gpt-5", "o1-", "o3-", "o4-"];
|
|
7
|
+
readonly google: readonly ["google", "deepmind", "gemini"];
|
|
8
|
+
readonly other: readonly ["deepseek", "qwen", "moonshot", "kimi", "mistral", "llama", "meta", "grok", "xai", "zhipu"];
|
|
9
|
+
};
|
|
10
|
+
export type VendorKey = keyof typeof VENDOR_PATTERNS;
|
|
11
|
+
export declare function foreignPatternsExcept(home: VendorKey): string[];
|
|
12
|
+
export declare const CLOUD_HOST_PATTERNS: string[];
|
|
13
|
+
export declare const FAKE_RESPONSE_SIGNATURES: string[];
|
|
14
|
+
export declare const CJK_CHAR: RegExp;
|
|
15
|
+
export declare const CJK_LEAK_MIN_CHARS = 4;
|
|
16
|
+
//# sourceMappingURL=patterns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../src/patterns.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,UA2BxC,CAAC;AAEF,eAAO,MAAM,iBAAiB,UAAiC,CAAC;AAEhE,eAAO,MAAM,kBAAkB,UAM9B,CAAC;AAEF,eAAO,MAAM,eAAe;aAC1B,SAAS,YAAG,WAAW,EAAE,QAAQ;aACjC,MAAM,YAAG,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;aAC5E,MAAM,YAAG,QAAQ,EAAE,UAAU,EAAE,QAAQ;aACvC,KAAK,YACH,UAAU,EACV,MAAM,EACN,UAAU,EACV,MAAM,EACN,SAAS,EACT,OAAO,EACP,MAAM,EACN,MAAM,EACN,KAAK,EACL,OAAO;CAED,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,eAAe,CAAC;AAErD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,EAAE,CAK/D;AAGD,eAAO,MAAM,mBAAmB,UAA6E,CAAC;AAE9G,eAAO,MAAM,wBAAwB,UAA0B,CAAC;AAEhE,eAAO,MAAM,QAAQ,QAAuB,CAAC;AAE7C,eAAO,MAAM,kBAAkB,IAAI,CAAC"}
|
package/dist/patterns.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export const CODING_TOOL_REFUSAL_PATTERNS = [
|
|
2
|
+
"assist with development",
|
|
3
|
+
"here to assist with development tasks",
|
|
4
|
+
"sensitive, personal, or emotional",
|
|
5
|
+
"i'm here to help with coding",
|
|
6
|
+
"i'm here to help with development",
|
|
7
|
+
"i'm designed to help with development",
|
|
8
|
+
"let me help you with your code",
|
|
9
|
+
"i'm a coding assistant",
|
|
10
|
+
"development tasks, writing, analysis",
|
|
11
|
+
"infrastructure and configuration",
|
|
12
|
+
"falls outside what i can help with",
|
|
13
|
+
"i'm focused on software development",
|
|
14
|
+
"focused on software development and coding",
|
|
15
|
+
"best suited for software development",
|
|
16
|
+
"i'm built to help with software development",
|
|
17
|
+
"i'm built to help with coding",
|
|
18
|
+
"help with software development, coding",
|
|
19
|
+
"what can i help you build",
|
|
20
|
+
"got a tricky bug",
|
|
21
|
+
"got a coding challenge",
|
|
22
|
+
"got any code challenges",
|
|
23
|
+
"i'm here to help with software",
|
|
24
|
+
"i'm here for coding",
|
|
25
|
+
"i'm droid",
|
|
26
|
+
"development workflows, cli commands",
|
|
27
|
+
"here to help with coding, development workflows",
|
|
28
|
+
];
|
|
29
|
+
export const CODING_TOOL_NAMES = ["kiro", "cascade", "codeium"];
|
|
30
|
+
export const SCAM_PAGE_PATTERNS = [
|
|
31
|
+
"token被盗",
|
|
32
|
+
"token被人盗刷",
|
|
33
|
+
"本站token",
|
|
34
|
+
"盗取token",
|
|
35
|
+
"微信jemes",
|
|
36
|
+
];
|
|
37
|
+
export const VENDOR_PATTERNS = {
|
|
38
|
+
anthropic: ["anthropic", "claude"],
|
|
39
|
+
openai: ["openai", "chatgpt", "gpt-3", "gpt-4", "gpt-5", "o1-", "o3-", "o4-"],
|
|
40
|
+
google: ["google", "deepmind", "gemini"],
|
|
41
|
+
other: [
|
|
42
|
+
"deepseek",
|
|
43
|
+
"qwen",
|
|
44
|
+
"moonshot",
|
|
45
|
+
"kimi",
|
|
46
|
+
"mistral",
|
|
47
|
+
"llama",
|
|
48
|
+
"meta",
|
|
49
|
+
"grok",
|
|
50
|
+
"xai",
|
|
51
|
+
"zhipu",
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
export function foreignPatternsExcept(home) {
|
|
55
|
+
const keys = Object.keys(VENDOR_PATTERNS).filter((k) => k in VENDOR_PATTERNS);
|
|
56
|
+
return keys.filter((k) => k !== home).flatMap((k) => [...VENDOR_PATTERNS[k]]);
|
|
57
|
+
}
|
|
58
|
+
// prettier-ignore
|
|
59
|
+
export const CLOUD_HOST_PATTERNS = ["amazon", "aws", "bedrock", "google", "vertex", "microsoft", "azure", "foundry"];
|
|
60
|
+
export const FAKE_RESPONSE_SIGNATURES = ["claude sonnet (4.0)"];
|
|
61
|
+
export const CJK_CHAR = /[-ヿ㐀-䶿一-鿿豈-가-]/g;
|
|
62
|
+
export const CJK_LEAK_MIN_CHARS = 4;
|
|
63
|
+
//# sourceMappingURL=patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.js","sourceRoot":"","sources":["../src/patterns.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,4BAA4B,GAAG;IAC1C,yBAAyB;IACzB,uCAAuC;IACvC,mCAAmC;IACnC,8BAA8B;IAC9B,mCAAmC;IACnC,uCAAuC;IACvC,gCAAgC;IAChC,wBAAwB;IACxB,sCAAsC;IACtC,kCAAkC;IAClC,oCAAoC;IACpC,qCAAqC;IACrC,4CAA4C;IAC5C,sCAAsC;IACtC,6CAA6C;IAC7C,+BAA+B;IAC/B,wCAAwC;IACxC,2BAA2B;IAC3B,kBAAkB;IAClB,wBAAwB;IACxB,yBAAyB;IACzB,gCAAgC;IAChC,qBAAqB;IACrB,WAAW;IACX,qCAAqC;IACrC,iDAAiD;CAClD,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AAEhE,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,SAAS;IACT,WAAW;IACX,SAAS;IACT,SAAS;IACT,SAAS;CACV,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,SAAS,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC;IAClC,MAAM,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IAC7E,MAAM,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC;IACxC,KAAK,EAAE;QACL,UAAU;QACV,MAAM;QACN,UAAU;QACV,MAAM;QACN,SAAS;QACT,OAAO;QACP,MAAM;QACN,MAAM;QACN,KAAK;QACL,OAAO;KACR;CACO,CAAC;AAIX,MAAM,UAAU,qBAAqB,CAAC,IAAe;IACnD,MAAM,IAAI,GAAgB,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,CAC3D,CAAC,CAAC,EAAkB,EAAE,CAAC,CAAC,IAAI,eAAe,CAC5C,CAAC;IACF,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC;AAED,kBAAkB;AAClB,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAC,KAAK,EAAC,SAAS,EAAC,QAAQ,EAAC,QAAQ,EAAC,WAAW,EAAC,OAAO,EAAC,SAAS,CAAC,CAAC;AAE9G,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,qBAAqB,CAAC,CAAC;AAEhE,MAAM,CAAC,MAAM,QAAQ,GAAG,oBAAoB,CAAC;AAE7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC"}
|
package/dist/probes.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ProviderConfig } from "./providers/config";
|
|
2
|
+
import type { ProbeLabel } from "./types";
|
|
3
|
+
export type ProbeDef = {
|
|
4
|
+
label: ProbeLabel;
|
|
5
|
+
maxTokens: number;
|
|
6
|
+
buildPrompt: (nonce: string) => string;
|
|
7
|
+
evaluate: (text: string, cfg: ProviderConfig) => boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare const PROBES: readonly ProbeDef[];
|
|
10
|
+
//# sourceMappingURL=probes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probes.d.ts","sourceRoot":"","sources":["../src/probes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAUzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACvC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC;CAC1D,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,SAAS,QAAQ,EAkErC,CAAC"}
|