@kya-os/agentshield-nextjs 0.1.40 → 0.1.41

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/dist/index.mjs CHANGED
@@ -1,6 +1,468 @@
1
1
  import { NextResponse } from 'next/server';
2
2
 
3
- // src/create-middleware.ts
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __esm = (fn, res) => function __init() {
6
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
7
+ };
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+
13
+ // src/wasm-loader.ts
14
+ function setWasmBaseUrl(url) {
15
+ baseUrl = url;
16
+ }
17
+ function getWasmUrl() {
18
+ if (baseUrl) {
19
+ try {
20
+ const url = new URL(baseUrl);
21
+ return `${url.origin}${WASM_PATH}`;
22
+ } catch {
23
+ return WASM_PATH;
24
+ }
25
+ }
26
+ return WASM_PATH;
27
+ }
28
+ async function initWasm() {
29
+ if (wasmExports) return true;
30
+ if (initPromise) {
31
+ await initPromise;
32
+ return !!wasmExports;
33
+ }
34
+ initPromise = (async () => {
35
+ try {
36
+ const controller = new AbortController();
37
+ const timeout = setTimeout(() => controller.abort(), 3e3);
38
+ try {
39
+ const wasmUrl = getWasmUrl();
40
+ if (typeof WebAssembly.instantiateStreaming === "function") {
41
+ try {
42
+ const response2 = await fetch(wasmUrl, { signal: controller.signal });
43
+ clearTimeout(timeout);
44
+ if (!response2.ok) {
45
+ throw new Error(`Failed to fetch WASM: ${response2.status}`);
46
+ }
47
+ const streamResponse = response2.clone();
48
+ const { instance } = await WebAssembly.instantiateStreaming(
49
+ streamResponse,
50
+ {
51
+ wbg: {
52
+ __wbg_log_1d3ae13c3d5e6b8e: (ptr, len) => {
53
+ console.log("WASM:", ptr, len);
54
+ },
55
+ __wbindgen_throw: (ptr, len) => {
56
+ throw new Error(`WASM Error at ${ptr}, length ${len}`);
57
+ }
58
+ }
59
+ }
60
+ );
61
+ wasmInstance = instance;
62
+ wasmExports = instance.exports;
63
+ console.log("[AgentShield] \u2705 WASM module initialized with streaming");
64
+ return;
65
+ } catch (streamError) {
66
+ if (!controller.signal.aborted) {
67
+ console.log("[AgentShield] Streaming compilation failed, falling back to standard compilation");
68
+ } else {
69
+ throw streamError;
70
+ }
71
+ }
72
+ }
73
+ const response = await fetch(wasmUrl, { signal: controller.signal });
74
+ clearTimeout(timeout);
75
+ if (!response.ok) {
76
+ throw new Error(`Failed to fetch WASM: ${response.status}`);
77
+ }
78
+ const wasmArrayBuffer = await response.arrayBuffer();
79
+ const compiledModule = await WebAssembly.compile(wasmArrayBuffer);
80
+ const imports = {
81
+ wbg: {
82
+ __wbg_log_1d3ae13c3d5e6b8e: (ptr, len) => {
83
+ console.log("WASM:", ptr, len);
84
+ },
85
+ __wbindgen_throw: (ptr, len) => {
86
+ throw new Error(`WASM Error at ${ptr}, length ${len}`);
87
+ }
88
+ }
89
+ };
90
+ wasmInstance = await WebAssembly.instantiate(compiledModule, imports);
91
+ wasmExports = wasmInstance.exports;
92
+ console.log("[AgentShield] \u2705 WASM module initialized via fallback");
93
+ } catch (fetchError) {
94
+ if (fetchError.name === "AbortError") {
95
+ console.warn("[AgentShield] WASM fetch timed out after 3 seconds - using pattern detection");
96
+ } else {
97
+ console.warn("[AgentShield] Failed to fetch WASM file:", fetchError.message);
98
+ }
99
+ wasmExports = null;
100
+ }
101
+ } catch (error) {
102
+ console.error("[AgentShield] Failed to initialize WASM:", error);
103
+ wasmExports = null;
104
+ }
105
+ })();
106
+ await initPromise;
107
+ return !!wasmExports;
108
+ }
109
+ async function detectAgentWithWasm(userAgent, headers, ipAddress) {
110
+ const initialized = await initWasm();
111
+ if (!initialized || !wasmExports) {
112
+ return null;
113
+ }
114
+ try {
115
+ const headersJson = JSON.stringify(headers);
116
+ if (typeof wasmExports.detect_agent === "function") {
117
+ const result = wasmExports.detect_agent(
118
+ userAgent || "",
119
+ headersJson,
120
+ ipAddress || "",
121
+ (/* @__PURE__ */ new Date()).toISOString()
122
+ );
123
+ return {
124
+ isAgent: result.is_agent || false,
125
+ confidence: result.confidence || 0,
126
+ agent: result.agent,
127
+ verificationMethod: result.verification_method || "wasm",
128
+ riskLevel: result.risk_level || "low"
129
+ };
130
+ }
131
+ console.warn("[AgentShield] WASM exports do not include detect_agent function");
132
+ return null;
133
+ } catch (error) {
134
+ console.error("[AgentShield] WASM detection failed:", error);
135
+ return null;
136
+ }
137
+ }
138
+ async function getWasmVersion() {
139
+ const initialized = await initWasm();
140
+ if (!initialized || !wasmExports) {
141
+ return null;
142
+ }
143
+ if (typeof wasmExports.version === "function") {
144
+ return wasmExports.version();
145
+ }
146
+ return "unknown";
147
+ }
148
+ async function isWasmAvailable() {
149
+ try {
150
+ const initialized = await initWasm();
151
+ if (!initialized) return false;
152
+ const version = await getWasmVersion();
153
+ return version !== null;
154
+ } catch {
155
+ return false;
156
+ }
157
+ }
158
+ var wasmInstance, wasmExports, initPromise, WASM_PATH, baseUrl;
159
+ var init_wasm_loader = __esm({
160
+ "src/wasm-loader.ts"() {
161
+ wasmInstance = null;
162
+ wasmExports = null;
163
+ initPromise = null;
164
+ WASM_PATH = "/wasm/agentshield_wasm_bg.wasm";
165
+ baseUrl = null;
166
+ }
167
+ });
168
+
169
+ // src/edge-detector-with-wasm.ts
170
+ var edge_detector_with_wasm_exports = {};
171
+ __export(edge_detector_with_wasm_exports, {
172
+ EdgeAgentDetectorWithWasm: () => EdgeAgentDetectorWithWasm,
173
+ EdgeAgentDetectorWrapperWithWasm: () => EdgeAgentDetectorWrapperWithWasm
174
+ });
175
+ var AI_AGENT_PATTERNS2, CLOUD_PROVIDERS2, EdgeAgentDetectorWithWasm, EdgeAgentDetectorWrapperWithWasm;
176
+ var init_edge_detector_with_wasm = __esm({
177
+ "src/edge-detector-with-wasm.ts"() {
178
+ init_wasm_loader();
179
+ AI_AGENT_PATTERNS2 = [
180
+ { pattern: /chatgpt-user/i, type: "chatgpt", name: "ChatGPT" },
181
+ { pattern: /claude-web/i, type: "claude", name: "Claude" },
182
+ { pattern: /perplexitybot/i, type: "perplexity", name: "Perplexity" },
183
+ { pattern: /perplexity-user/i, type: "perplexity", name: "Perplexity" },
184
+ { pattern: /perplexity-ai/i, type: "perplexity", name: "Perplexity" },
185
+ { pattern: /perplexity/i, type: "perplexity", name: "Perplexity" },
186
+ { pattern: /bingbot/i, type: "bing", name: "Bing AI" },
187
+ { pattern: /anthropic-ai/i, type: "anthropic", name: "Anthropic" }
188
+ ];
189
+ CLOUD_PROVIDERS2 = {
190
+ aws: ["54.", "52.", "35.", "18.", "3."],
191
+ gcp: ["35.", "34.", "104.", "107.", "108."],
192
+ azure: ["13.", "20.", "40.", "52.", "104."]
193
+ };
194
+ EdgeAgentDetectorWithWasm = class {
195
+ constructor(enableWasm = true) {
196
+ this.enableWasm = enableWasm;
197
+ }
198
+ wasmEnabled = false;
199
+ initPromise = null;
200
+ baseUrl = null;
201
+ /**
202
+ * Set the base URL for WASM loading in Edge Runtime
203
+ */
204
+ setBaseUrl(url) {
205
+ this.baseUrl = url;
206
+ setWasmBaseUrl(url);
207
+ }
208
+ /**
209
+ * Initialize the detector (including WASM if enabled)
210
+ */
211
+ async init() {
212
+ if (!this.enableWasm) {
213
+ this.wasmEnabled = false;
214
+ return;
215
+ }
216
+ if (this.initPromise) {
217
+ await this.initPromise;
218
+ return;
219
+ }
220
+ this.initPromise = (async () => {
221
+ try {
222
+ const wasmAvailable = await isWasmAvailable();
223
+ this.wasmEnabled = wasmAvailable;
224
+ if (this.wasmEnabled) {
225
+ console.log("[AgentShield] WASM detection enabled");
226
+ } else {
227
+ console.log("[AgentShield] WASM not available, using pattern detection");
228
+ }
229
+ } catch (error) {
230
+ console.error("[AgentShield] Failed to initialize WASM:", error);
231
+ this.wasmEnabled = false;
232
+ }
233
+ })();
234
+ await this.initPromise;
235
+ }
236
+ /**
237
+ * Pattern-based detection (fallback)
238
+ */
239
+ async patternDetection(input) {
240
+ const reasons = [];
241
+ let detectedAgent;
242
+ let verificationMethod;
243
+ let confidence = 0;
244
+ const headers = input.headers || {};
245
+ const normalizedHeaders = {};
246
+ for (const [key, value] of Object.entries(headers)) {
247
+ normalizedHeaders[key.toLowerCase()] = value;
248
+ }
249
+ const signaturePresent = !!(normalizedHeaders["signature"] || normalizedHeaders["signature-input"]);
250
+ const signatureAgent = normalizedHeaders["signature-agent"];
251
+ if (signatureAgent?.includes("chatgpt.com")) {
252
+ confidence = 0.85;
253
+ reasons.push("signature_agent:chatgpt");
254
+ detectedAgent = { type: "chatgpt", name: "ChatGPT" };
255
+ verificationMethod = "signature";
256
+ } else if (signaturePresent) {
257
+ confidence = Math.max(confidence, 0.4);
258
+ reasons.push("signature_present");
259
+ }
260
+ const userAgent = input.userAgent || input.headers?.["user-agent"] || "";
261
+ if (userAgent) {
262
+ for (const { pattern, type, name } of AI_AGENT_PATTERNS2) {
263
+ if (pattern.test(userAgent)) {
264
+ const highConfidenceAgents = [
265
+ "chatgpt",
266
+ "claude",
267
+ "perplexity",
268
+ "anthropic"
269
+ ];
270
+ const patternConfidence = highConfidenceAgents.includes(type) ? 0.85 : 0.5;
271
+ confidence = Math.max(confidence, patternConfidence);
272
+ reasons.push(`known_pattern:${type}`);
273
+ if (!detectedAgent) {
274
+ detectedAgent = { type, name };
275
+ verificationMethod = "pattern";
276
+ }
277
+ break;
278
+ }
279
+ }
280
+ }
281
+ const aiHeaders = [
282
+ "openai-conversation-id",
283
+ "openai-ephemeral-user-id",
284
+ "anthropic-client-id",
285
+ "x-goog-api-client",
286
+ "x-ms-copilot-id"
287
+ ];
288
+ const foundAiHeaders = aiHeaders.filter(
289
+ (header) => normalizedHeaders[header]
290
+ );
291
+ if (foundAiHeaders.length > 0) {
292
+ confidence = Math.max(confidence, 0.6);
293
+ reasons.push(`ai_headers:${foundAiHeaders.length}`);
294
+ }
295
+ const ip = input.ip || input.ipAddress;
296
+ if (ip && !normalizedHeaders["x-forwarded-for"] && !normalizedHeaders["x-real-ip"]) {
297
+ for (const [provider, prefixes] of Object.entries(CLOUD_PROVIDERS2)) {
298
+ if (prefixes.some((prefix) => ip.startsWith(prefix))) {
299
+ confidence = Math.max(confidence, 0.4);
300
+ reasons.push(`cloud_provider:${provider}`);
301
+ break;
302
+ }
303
+ }
304
+ }
305
+ if (reasons.length > 2) {
306
+ confidence = Math.min(confidence * 1.2, 0.95);
307
+ }
308
+ return {
309
+ isAgent: confidence > 0.3,
310
+ confidence,
311
+ ...detectedAgent && { detectedAgent },
312
+ reasons,
313
+ ...verificationMethod && { verificationMethod },
314
+ forgeabilityRisk: confidence > 0.8 ? "medium" : "high",
315
+ timestamp: /* @__PURE__ */ new Date()
316
+ };
317
+ }
318
+ /**
319
+ * Analyze request with WASM enhancement when available
320
+ */
321
+ async analyze(input) {
322
+ await this.init();
323
+ if (this.wasmEnabled) {
324
+ try {
325
+ const wasmResult = await detectAgentWithWasm(
326
+ input.userAgent || input.headers?.["user-agent"],
327
+ input.headers || {},
328
+ input.ip || input.ipAddress
329
+ );
330
+ if (wasmResult) {
331
+ console.log("[AgentShield] Using WASM detection result");
332
+ const detectedAgent = wasmResult.agent ? this.mapAgentName(wasmResult.agent) : void 0;
333
+ return {
334
+ isAgent: wasmResult.isAgent,
335
+ confidence: wasmResult.confidence,
336
+ ...detectedAgent && { detectedAgent },
337
+ reasons: [`wasm:${wasmResult.verificationMethod}`],
338
+ verificationMethod: wasmResult.verificationMethod,
339
+ forgeabilityRisk: wasmResult.verificationMethod === "signature" ? "low" : wasmResult.confidence > 0.9 ? "medium" : "high",
340
+ timestamp: /* @__PURE__ */ new Date()
341
+ };
342
+ }
343
+ } catch (error) {
344
+ console.error("[AgentShield] WASM detection error:", error);
345
+ }
346
+ }
347
+ const patternResult = await this.patternDetection(input);
348
+ if (this.wasmEnabled && patternResult.confidence >= 0.85) {
349
+ patternResult.confidence = Math.min(0.95, patternResult.confidence + 0.1);
350
+ patternResult.reasons.push("wasm_enhanced");
351
+ if (!patternResult.verificationMethod) {
352
+ patternResult.verificationMethod = "wasm-enhanced";
353
+ }
354
+ }
355
+ return patternResult;
356
+ }
357
+ /**
358
+ * Map agent names from WASM to consistent format
359
+ */
360
+ mapAgentName(agent) {
361
+ const lowerAgent = agent.toLowerCase();
362
+ if (lowerAgent.includes("chatgpt")) {
363
+ return { type: "chatgpt", name: "ChatGPT" };
364
+ } else if (lowerAgent.includes("claude")) {
365
+ return { type: "claude", name: "Claude" };
366
+ } else if (lowerAgent.includes("perplexity")) {
367
+ return { type: "perplexity", name: "Perplexity" };
368
+ } else if (lowerAgent.includes("bing")) {
369
+ return { type: "bing", name: "Bing AI" };
370
+ } else if (lowerAgent.includes("anthropic")) {
371
+ return { type: "anthropic", name: "Anthropic" };
372
+ }
373
+ return { type: "unknown", name: agent };
374
+ }
375
+ };
376
+ EdgeAgentDetectorWrapperWithWasm = class {
377
+ detector;
378
+ events = /* @__PURE__ */ new Map();
379
+ constructor(config) {
380
+ this.detector = new EdgeAgentDetectorWithWasm(config?.enableWasm ?? true);
381
+ if (config?.baseUrl) {
382
+ this.detector.setBaseUrl(config.baseUrl);
383
+ }
384
+ }
385
+ setBaseUrl(url) {
386
+ this.detector.setBaseUrl(url);
387
+ }
388
+ async analyze(input) {
389
+ const result = await this.detector.analyze(input);
390
+ if (result.isAgent && this.events.has("agent.detected")) {
391
+ const handlers = this.events.get("agent.detected") || [];
392
+ handlers.forEach((handler) => handler(result, input));
393
+ }
394
+ return result;
395
+ }
396
+ on(event, handler) {
397
+ if (!this.events.has(event)) {
398
+ this.events.set(event, []);
399
+ }
400
+ this.events.get(event).push(handler);
401
+ }
402
+ emit(event, ...args) {
403
+ const handlers = this.events.get(event) || [];
404
+ handlers.forEach((handler) => handler(...args));
405
+ }
406
+ async init() {
407
+ await this.detector.init();
408
+ }
409
+ };
410
+ }
411
+ });
412
+
413
+ // src/wasm-confidence.ts
414
+ var wasm_confidence_exports = {};
415
+ __export(wasm_confidence_exports, {
416
+ checkWasmAvailability: () => checkWasmAvailability,
417
+ getVerificationMethod: () => getVerificationMethod,
418
+ getWasmConfidenceBoost: () => getWasmConfidenceBoost,
419
+ shouldIndicateWasmVerification: () => shouldIndicateWasmVerification
420
+ });
421
+ async function checkWasmAvailability() {
422
+ try {
423
+ if (typeof WebAssembly === "undefined") {
424
+ return false;
425
+ }
426
+ if (!WebAssembly.instantiate || !WebAssembly.Module) {
427
+ return false;
428
+ }
429
+ return true;
430
+ } catch {
431
+ return false;
432
+ }
433
+ }
434
+ function shouldIndicateWasmVerification(confidence) {
435
+ return confidence >= 0.85 && confidence < 1;
436
+ }
437
+ function getWasmConfidenceBoost(baseConfidence, reasons = []) {
438
+ if (reasons.some(
439
+ (r) => r.includes("signature_agent") && !r.includes("signature_headers_present")
440
+ )) {
441
+ return 1;
442
+ }
443
+ if (baseConfidence >= 0.85) {
444
+ return 0.95;
445
+ }
446
+ if (baseConfidence >= 0.7) {
447
+ return Math.min(baseConfidence * 1.1, 0.9);
448
+ }
449
+ return baseConfidence;
450
+ }
451
+ function getVerificationMethod(confidence, reasons = []) {
452
+ if (reasons.some(
453
+ (r) => r.includes("signature_agent") && !r.includes("signature_headers_present")
454
+ )) {
455
+ return "signature";
456
+ }
457
+ if (shouldIndicateWasmVerification(confidence)) {
458
+ return "wasm-enhanced";
459
+ }
460
+ return "pattern";
461
+ }
462
+ var init_wasm_confidence = __esm({
463
+ "src/wasm-confidence.ts"() {
464
+ }
465
+ });
4
466
 
5
467
  // src/signature-verifier.ts
6
468
  var KNOWN_KEYS = {
@@ -174,413 +636,66 @@ async function verifyAgentSignature(method, path, headers) {
174
636
  confidence: 0,
175
637
  reason: "Key is not valid at current time",
176
638
  verificationMethod: "none"
177
- };
178
- }
179
- const signatureBase = buildSignatureBase(method, path, headers, parsed.signedHeaders);
180
- let signatureValue = signature;
181
- if (signatureValue.startsWith("sig1=:")) {
182
- signatureValue = signatureValue.substring(6);
183
- }
184
- if (signatureValue.endsWith(":")) {
185
- signatureValue = signatureValue.slice(0, -1);
186
- }
187
- const isValid = await verifyEd25519Signature(
188
- key.publicKey,
189
- signatureValue,
190
- signatureBase
191
- );
192
- if (isValid) {
193
- return {
194
- isValid: true,
195
- agent,
196
- keyid: parsed.keyid,
197
- confidence: 1,
198
- // 100% confidence for valid signature
199
- verificationMethod: "signature"
200
- };
201
- } else {
202
- return {
203
- isValid: false,
204
- confidence: 0,
205
- reason: "Signature verification failed",
206
- verificationMethod: "none"
207
- };
208
- }
209
- }
210
- function hasSignatureHeaders(headers) {
211
- return !!((headers["signature"] || headers["Signature"]) && (headers["signature-input"] || headers["Signature-Input"]));
212
- }
213
- function isChatGPTSignature(headers) {
214
- const signatureAgent = headers["signature-agent"] || headers["Signature-Agent"];
215
- return signatureAgent === '"https://chatgpt.com"' || (signatureAgent?.includes("chatgpt.com") || false);
216
- }
217
-
218
- // src/edge-detector-wrapper.ts
219
- var AI_AGENT_PATTERNS = [
220
- { pattern: /chatgpt-user/i, type: "chatgpt", name: "ChatGPT" },
221
- { pattern: /claude-web/i, type: "claude", name: "Claude" },
222
- { pattern: /perplexitybot/i, type: "perplexity", name: "Perplexity" },
223
- { pattern: /perplexity-user/i, type: "perplexity", name: "Perplexity" },
224
- { pattern: /perplexity-ai/i, type: "perplexity", name: "Perplexity" },
225
- { pattern: /perplexity/i, type: "perplexity", name: "Perplexity" },
226
- // Fallback
227
- { pattern: /bingbot/i, type: "bing", name: "Bing AI" },
228
- { pattern: /anthropic-ai/i, type: "anthropic", name: "Anthropic" }
229
- ];
230
- var CLOUD_PROVIDERS = {
231
- aws: ["54.", "52.", "35.", "18.", "3."],
232
- gcp: ["35.", "34.", "104.", "107.", "108."],
233
- azure: ["13.", "20.", "40.", "52.", "104."]
234
- };
235
- var EdgeAgentDetector = class {
236
- async analyze(input) {
237
- const reasons = [];
238
- let detectedAgent;
239
- let verificationMethod;
240
- let confidence = 0;
241
- const headers = input.headers || {};
242
- const normalizedHeaders = {};
243
- for (const [key, value] of Object.entries(headers)) {
244
- normalizedHeaders[key.toLowerCase()] = value;
245
- }
246
- if (hasSignatureHeaders(headers)) {
247
- try {
248
- const signatureResult = await verifyAgentSignature(
249
- input.method || "GET",
250
- input.url || "/",
251
- headers
252
- );
253
- if (signatureResult.isValid) {
254
- confidence = signatureResult.confidence;
255
- reasons.push(`verified_signature:${signatureResult.agent?.toLowerCase() || "unknown"}`);
256
- if (signatureResult.agent) {
257
- detectedAgent = {
258
- type: signatureResult.agent.toLowerCase(),
259
- name: signatureResult.agent
260
- };
261
- }
262
- verificationMethod = signatureResult.verificationMethod;
263
- if (signatureResult.keyid) {
264
- reasons.push(`keyid:${signatureResult.keyid}`);
265
- }
266
- } else {
267
- confidence = Math.max(confidence, 0.3);
268
- reasons.push("invalid_signature");
269
- if (signatureResult.reason) {
270
- reasons.push(`signature_error:${signatureResult.reason}`);
271
- }
272
- if (isChatGPTSignature(headers)) {
273
- reasons.push("claims_chatgpt");
274
- detectedAgent = { type: "chatgpt", name: "ChatGPT (unverified)" };
275
- }
276
- }
277
- } catch (error) {
278
- console.error("[EdgeAgentDetector] Signature verification error:", error);
279
- confidence = Math.max(confidence, 0.2);
280
- reasons.push("signature_verification_error");
281
- }
282
- }
283
- const userAgent = input.userAgent || input.headers?.["user-agent"] || "";
284
- if (userAgent) {
285
- for (const { pattern, type, name } of AI_AGENT_PATTERNS) {
286
- if (pattern.test(userAgent)) {
287
- const highConfidenceAgents = [
288
- "chatgpt",
289
- "claude",
290
- "perplexity",
291
- "anthropic"
292
- ];
293
- const patternConfidence = highConfidenceAgents.includes(type) ? 0.85 : 0.5;
294
- confidence = Math.max(confidence, patternConfidence);
295
- reasons.push(`known_pattern:${type}`);
296
- if (!detectedAgent) {
297
- detectedAgent = { type, name };
298
- verificationMethod = "pattern";
299
- }
300
- break;
301
- }
302
- }
303
- }
304
- const aiHeaders = [
305
- "openai-conversation-id",
306
- "openai-ephemeral-user-id",
307
- "anthropic-client-id",
308
- "x-goog-api-client",
309
- "x-ms-copilot-id"
310
- ];
311
- const foundAiHeaders = aiHeaders.filter(
312
- (header) => normalizedHeaders[header]
313
- );
314
- if (foundAiHeaders.length > 0) {
315
- confidence = Math.max(confidence, 0.6);
316
- reasons.push(`ai_headers:${foundAiHeaders.length}`);
317
- }
318
- const ip = input.ip || input.ipAddress;
319
- if (ip && !normalizedHeaders["x-forwarded-for"] && !normalizedHeaders["x-real-ip"]) {
320
- for (const [provider, prefixes] of Object.entries(CLOUD_PROVIDERS)) {
321
- if (prefixes.some((prefix) => ip.startsWith(prefix))) {
322
- confidence = Math.max(confidence, 0.4);
323
- reasons.push(`cloud_provider:${provider}`);
324
- break;
325
- }
326
- }
327
- }
328
- if (reasons.length > 2 && confidence < 1) {
329
- confidence = Math.min(confidence * 1.2, 0.95);
330
- }
331
- return {
332
- isAgent: confidence > 0.3,
333
- confidence,
334
- ...detectedAgent && { detectedAgent },
335
- reasons,
336
- ...verificationMethod && { verificationMethod },
337
- forgeabilityRisk: verificationMethod === "signature" ? "low" : confidence > 0.8 ? "medium" : "high",
338
- timestamp: /* @__PURE__ */ new Date()
339
- };
340
- }
341
- };
342
- var EdgeAgentDetectorWrapper = class {
343
- detector;
344
- events = /* @__PURE__ */ new Map();
345
- constructor(_config) {
346
- this.detector = new EdgeAgentDetector();
347
- }
348
- async analyze(input) {
349
- const result = await this.detector.analyze(input);
350
- if (result.isAgent && this.events.has("agent.detected")) {
351
- const handlers = this.events.get("agent.detected") || [];
352
- handlers.forEach((handler) => handler(result, input));
353
- }
354
- return result;
355
- }
356
- on(event, handler) {
357
- if (!this.events.has(event)) {
358
- this.events.set(event, []);
359
- }
360
- this.events.get(event).push(handler);
361
- }
362
- emit(event, ...args) {
363
- const handlers = this.events.get(event) || [];
364
- handlers.forEach((handler) => handler(...args));
365
- }
366
- async init() {
367
- return;
368
- }
369
- };
370
-
371
- // src/wasm-loader.ts
372
- var wasmInstance = null;
373
- var wasmExports = null;
374
- var initPromise = null;
375
- var WASM_PATH = "/wasm/agentshield_wasm_bg.wasm";
376
- var baseUrl = null;
377
- function setWasmBaseUrl(url) {
378
- baseUrl = url;
379
- }
380
- function getWasmUrl() {
381
- if (baseUrl) {
382
- try {
383
- const url = new URL(baseUrl);
384
- return `${url.origin}${WASM_PATH}`;
385
- } catch {
386
- return WASM_PATH;
387
- }
388
- }
389
- return WASM_PATH;
390
- }
391
- async function initWasm() {
392
- if (wasmExports) return true;
393
- if (initPromise) {
394
- await initPromise;
395
- return !!wasmExports;
396
- }
397
- initPromise = (async () => {
398
- try {
399
- const controller = new AbortController();
400
- const timeout = setTimeout(() => controller.abort(), 3e3);
401
- try {
402
- const wasmUrl = getWasmUrl();
403
- if (typeof WebAssembly.instantiateStreaming === "function") {
404
- try {
405
- const response2 = await fetch(wasmUrl, { signal: controller.signal });
406
- clearTimeout(timeout);
407
- if (!response2.ok) {
408
- throw new Error(`Failed to fetch WASM: ${response2.status}`);
409
- }
410
- const streamResponse = response2.clone();
411
- const { instance } = await WebAssembly.instantiateStreaming(
412
- streamResponse,
413
- {
414
- wbg: {
415
- __wbg_log_1d3ae13c3d5e6b8e: (ptr, len) => {
416
- console.log("WASM:", ptr, len);
417
- },
418
- __wbindgen_throw: (ptr, len) => {
419
- throw new Error(`WASM Error at ${ptr}, length ${len}`);
420
- }
421
- }
422
- }
423
- );
424
- wasmInstance = instance;
425
- wasmExports = instance.exports;
426
- console.log("[AgentShield] \u2705 WASM module initialized with streaming");
427
- return;
428
- } catch (streamError) {
429
- if (!controller.signal.aborted) {
430
- console.log("[AgentShield] Streaming compilation failed, falling back to standard compilation");
431
- } else {
432
- throw streamError;
433
- }
434
- }
435
- }
436
- const response = await fetch(wasmUrl, { signal: controller.signal });
437
- clearTimeout(timeout);
438
- if (!response.ok) {
439
- throw new Error(`Failed to fetch WASM: ${response.status}`);
440
- }
441
- const wasmArrayBuffer = await response.arrayBuffer();
442
- const compiledModule = await WebAssembly.compile(wasmArrayBuffer);
443
- const imports = {
444
- wbg: {
445
- __wbg_log_1d3ae13c3d5e6b8e: (ptr, len) => {
446
- console.log("WASM:", ptr, len);
447
- },
448
- __wbindgen_throw: (ptr, len) => {
449
- throw new Error(`WASM Error at ${ptr}, length ${len}`);
450
- }
451
- }
452
- };
453
- wasmInstance = await WebAssembly.instantiate(compiledModule, imports);
454
- wasmExports = wasmInstance.exports;
455
- console.log("[AgentShield] \u2705 WASM module initialized via fallback");
456
- } catch (fetchError) {
457
- if (fetchError.name === "AbortError") {
458
- console.warn("[AgentShield] WASM fetch timed out after 3 seconds - using pattern detection");
459
- } else {
460
- console.warn("[AgentShield] Failed to fetch WASM file:", fetchError.message);
461
- }
462
- wasmExports = null;
463
- }
464
- } catch (error) {
465
- console.error("[AgentShield] Failed to initialize WASM:", error);
466
- wasmExports = null;
467
- }
468
- })();
469
- await initPromise;
470
- return !!wasmExports;
471
- }
472
- async function detectAgentWithWasm(userAgent, headers, ipAddress) {
473
- const initialized = await initWasm();
474
- if (!initialized || !wasmExports) {
475
- return null;
639
+ };
476
640
  }
477
- try {
478
- const headersJson = JSON.stringify(headers);
479
- if (typeof wasmExports.detect_agent === "function") {
480
- const result = wasmExports.detect_agent(
481
- userAgent || "",
482
- headersJson,
483
- ipAddress || "",
484
- (/* @__PURE__ */ new Date()).toISOString()
485
- );
486
- return {
487
- isAgent: result.is_agent || false,
488
- confidence: result.confidence || 0,
489
- agent: result.agent,
490
- verificationMethod: result.verification_method || "wasm",
491
- riskLevel: result.risk_level || "low"
492
- };
493
- }
494
- console.warn("[AgentShield] WASM exports do not include detect_agent function");
495
- return null;
496
- } catch (error) {
497
- console.error("[AgentShield] WASM detection failed:", error);
498
- return null;
641
+ const signatureBase = buildSignatureBase(method, path, headers, parsed.signedHeaders);
642
+ let signatureValue = signature;
643
+ if (signatureValue.startsWith("sig1=:")) {
644
+ signatureValue = signatureValue.substring(6);
499
645
  }
500
- }
501
- async function getWasmVersion() {
502
- const initialized = await initWasm();
503
- if (!initialized || !wasmExports) {
504
- return null;
646
+ if (signatureValue.endsWith(":")) {
647
+ signatureValue = signatureValue.slice(0, -1);
505
648
  }
506
- if (typeof wasmExports.version === "function") {
507
- return wasmExports.version();
649
+ const isValid = await verifyEd25519Signature(
650
+ key.publicKey,
651
+ signatureValue,
652
+ signatureBase
653
+ );
654
+ if (isValid) {
655
+ return {
656
+ isValid: true,
657
+ agent,
658
+ keyid: parsed.keyid,
659
+ confidence: 1,
660
+ // 100% confidence for valid signature
661
+ verificationMethod: "signature"
662
+ };
663
+ } else {
664
+ return {
665
+ isValid: false,
666
+ confidence: 0,
667
+ reason: "Signature verification failed",
668
+ verificationMethod: "none"
669
+ };
508
670
  }
509
- return "unknown";
510
671
  }
511
- async function isWasmAvailable() {
512
- try {
513
- const initialized = await initWasm();
514
- if (!initialized) return false;
515
- const version = await getWasmVersion();
516
- return version !== null;
517
- } catch {
518
- return false;
519
- }
672
+ function hasSignatureHeaders(headers) {
673
+ return !!((headers["signature"] || headers["Signature"]) && (headers["signature-input"] || headers["Signature-Input"]));
674
+ }
675
+ function isChatGPTSignature(headers) {
676
+ const signatureAgent = headers["signature-agent"] || headers["Signature-Agent"];
677
+ return signatureAgent === '"https://chatgpt.com"' || (signatureAgent?.includes("chatgpt.com") || false);
520
678
  }
521
679
 
522
- // src/edge-detector-with-wasm.ts
523
- var AI_AGENT_PATTERNS2 = [
680
+ // src/edge-detector-wrapper.ts
681
+ var AI_AGENT_PATTERNS = [
524
682
  { pattern: /chatgpt-user/i, type: "chatgpt", name: "ChatGPT" },
525
683
  { pattern: /claude-web/i, type: "claude", name: "Claude" },
526
684
  { pattern: /perplexitybot/i, type: "perplexity", name: "Perplexity" },
527
685
  { pattern: /perplexity-user/i, type: "perplexity", name: "Perplexity" },
528
686
  { pattern: /perplexity-ai/i, type: "perplexity", name: "Perplexity" },
529
687
  { pattern: /perplexity/i, type: "perplexity", name: "Perplexity" },
688
+ // Fallback
530
689
  { pattern: /bingbot/i, type: "bing", name: "Bing AI" },
531
690
  { pattern: /anthropic-ai/i, type: "anthropic", name: "Anthropic" }
532
691
  ];
533
- var CLOUD_PROVIDERS2 = {
692
+ var CLOUD_PROVIDERS = {
534
693
  aws: ["54.", "52.", "35.", "18.", "3."],
535
694
  gcp: ["35.", "34.", "104.", "107.", "108."],
536
695
  azure: ["13.", "20.", "40.", "52.", "104."]
537
696
  };
538
- var EdgeAgentDetectorWithWasm = class {
539
- constructor(enableWasm = true) {
540
- this.enableWasm = enableWasm;
541
- }
542
- wasmEnabled = false;
543
- initPromise = null;
544
- baseUrl = null;
545
- /**
546
- * Set the base URL for WASM loading in Edge Runtime
547
- */
548
- setBaseUrl(url) {
549
- this.baseUrl = url;
550
- setWasmBaseUrl(url);
551
- }
552
- /**
553
- * Initialize the detector (including WASM if enabled)
554
- */
555
- async init() {
556
- if (!this.enableWasm) {
557
- this.wasmEnabled = false;
558
- return;
559
- }
560
- if (this.initPromise) {
561
- await this.initPromise;
562
- return;
563
- }
564
- this.initPromise = (async () => {
565
- try {
566
- const wasmAvailable = await isWasmAvailable();
567
- this.wasmEnabled = wasmAvailable;
568
- if (this.wasmEnabled) {
569
- console.log("[AgentShield] WASM detection enabled");
570
- } else {
571
- console.log("[AgentShield] WASM not available, using pattern detection");
572
- }
573
- } catch (error) {
574
- console.error("[AgentShield] Failed to initialize WASM:", error);
575
- this.wasmEnabled = false;
576
- }
577
- })();
578
- await this.initPromise;
579
- }
580
- /**
581
- * Pattern-based detection (fallback)
582
- */
583
- async patternDetection(input) {
697
+ var EdgeAgentDetector = class {
698
+ async analyze(input) {
584
699
  const reasons = [];
585
700
  let detectedAgent;
586
701
  let verificationMethod;
@@ -590,20 +705,46 @@ var EdgeAgentDetectorWithWasm = class {
590
705
  for (const [key, value] of Object.entries(headers)) {
591
706
  normalizedHeaders[key.toLowerCase()] = value;
592
707
  }
593
- const signaturePresent = !!(normalizedHeaders["signature"] || normalizedHeaders["signature-input"]);
594
- const signatureAgent = normalizedHeaders["signature-agent"];
595
- if (signatureAgent?.includes("chatgpt.com")) {
596
- confidence = 0.85;
597
- reasons.push("signature_agent:chatgpt");
598
- detectedAgent = { type: "chatgpt", name: "ChatGPT" };
599
- verificationMethod = "signature";
600
- } else if (signaturePresent) {
601
- confidence = Math.max(confidence, 0.4);
602
- reasons.push("signature_present");
708
+ if (hasSignatureHeaders(headers)) {
709
+ try {
710
+ const signatureResult = await verifyAgentSignature(
711
+ input.method || "GET",
712
+ input.url || "/",
713
+ headers
714
+ );
715
+ if (signatureResult.isValid) {
716
+ confidence = signatureResult.confidence;
717
+ reasons.push(`verified_signature:${signatureResult.agent?.toLowerCase() || "unknown"}`);
718
+ if (signatureResult.agent) {
719
+ detectedAgent = {
720
+ type: signatureResult.agent.toLowerCase(),
721
+ name: signatureResult.agent
722
+ };
723
+ }
724
+ verificationMethod = signatureResult.verificationMethod;
725
+ if (signatureResult.keyid) {
726
+ reasons.push(`keyid:${signatureResult.keyid}`);
727
+ }
728
+ } else {
729
+ confidence = Math.max(confidence, 0.3);
730
+ reasons.push("invalid_signature");
731
+ if (signatureResult.reason) {
732
+ reasons.push(`signature_error:${signatureResult.reason}`);
733
+ }
734
+ if (isChatGPTSignature(headers)) {
735
+ reasons.push("claims_chatgpt");
736
+ detectedAgent = { type: "chatgpt", name: "ChatGPT (unverified)" };
737
+ }
738
+ }
739
+ } catch (error) {
740
+ console.error("[EdgeAgentDetector] Signature verification error:", error);
741
+ confidence = Math.max(confidence, 0.2);
742
+ reasons.push("signature_verification_error");
743
+ }
603
744
  }
604
745
  const userAgent = input.userAgent || input.headers?.["user-agent"] || "";
605
746
  if (userAgent) {
606
- for (const { pattern, type, name } of AI_AGENT_PATTERNS2) {
747
+ for (const { pattern, type, name } of AI_AGENT_PATTERNS) {
607
748
  if (pattern.test(userAgent)) {
608
749
  const highConfidenceAgents = [
609
750
  "chatgpt",
@@ -638,7 +779,7 @@ var EdgeAgentDetectorWithWasm = class {
638
779
  }
639
780
  const ip = input.ip || input.ipAddress;
640
781
  if (ip && !normalizedHeaders["x-forwarded-for"] && !normalizedHeaders["x-real-ip"]) {
641
- for (const [provider, prefixes] of Object.entries(CLOUD_PROVIDERS2)) {
782
+ for (const [provider, prefixes] of Object.entries(CLOUD_PROVIDERS)) {
642
783
  if (prefixes.some((prefix) => ip.startsWith(prefix))) {
643
784
  confidence = Math.max(confidence, 0.4);
644
785
  reasons.push(`cloud_provider:${provider}`);
@@ -646,7 +787,7 @@ var EdgeAgentDetectorWithWasm = class {
646
787
  }
647
788
  }
648
789
  }
649
- if (reasons.length > 2) {
790
+ if (reasons.length > 2 && confidence < 1) {
650
791
  confidence = Math.min(confidence * 1.2, 0.95);
651
792
  }
652
793
  return {
@@ -655,79 +796,16 @@ var EdgeAgentDetectorWithWasm = class {
655
796
  ...detectedAgent && { detectedAgent },
656
797
  reasons,
657
798
  ...verificationMethod && { verificationMethod },
658
- forgeabilityRisk: confidence > 0.8 ? "medium" : "high",
799
+ forgeabilityRisk: verificationMethod === "signature" ? "low" : confidence > 0.8 ? "medium" : "high",
659
800
  timestamp: /* @__PURE__ */ new Date()
660
801
  };
661
802
  }
662
- /**
663
- * Analyze request with WASM enhancement when available
664
- */
665
- async analyze(input) {
666
- await this.init();
667
- if (this.wasmEnabled) {
668
- try {
669
- const wasmResult = await detectAgentWithWasm(
670
- input.userAgent || input.headers?.["user-agent"],
671
- input.headers || {},
672
- input.ip || input.ipAddress
673
- );
674
- if (wasmResult) {
675
- console.log("[AgentShield] Using WASM detection result");
676
- const detectedAgent = wasmResult.agent ? this.mapAgentName(wasmResult.agent) : void 0;
677
- return {
678
- isAgent: wasmResult.isAgent,
679
- confidence: wasmResult.confidence,
680
- ...detectedAgent && { detectedAgent },
681
- reasons: [`wasm:${wasmResult.verificationMethod}`],
682
- verificationMethod: wasmResult.verificationMethod,
683
- forgeabilityRisk: wasmResult.verificationMethod === "signature" ? "low" : wasmResult.confidence > 0.9 ? "medium" : "high",
684
- timestamp: /* @__PURE__ */ new Date()
685
- };
686
- }
687
- } catch (error) {
688
- console.error("[AgentShield] WASM detection error:", error);
689
- }
690
- }
691
- const patternResult = await this.patternDetection(input);
692
- if (this.wasmEnabled && patternResult.confidence >= 0.85) {
693
- patternResult.confidence = Math.min(0.95, patternResult.confidence + 0.1);
694
- patternResult.reasons.push("wasm_enhanced");
695
- if (!patternResult.verificationMethod) {
696
- patternResult.verificationMethod = "wasm-enhanced";
697
- }
698
- }
699
- return patternResult;
700
- }
701
- /**
702
- * Map agent names from WASM to consistent format
703
- */
704
- mapAgentName(agent) {
705
- const lowerAgent = agent.toLowerCase();
706
- if (lowerAgent.includes("chatgpt")) {
707
- return { type: "chatgpt", name: "ChatGPT" };
708
- } else if (lowerAgent.includes("claude")) {
709
- return { type: "claude", name: "Claude" };
710
- } else if (lowerAgent.includes("perplexity")) {
711
- return { type: "perplexity", name: "Perplexity" };
712
- } else if (lowerAgent.includes("bing")) {
713
- return { type: "bing", name: "Bing AI" };
714
- } else if (lowerAgent.includes("anthropic")) {
715
- return { type: "anthropic", name: "Anthropic" };
716
- }
717
- return { type: "unknown", name: agent };
718
- }
719
803
  };
720
- var EdgeAgentDetectorWrapperWithWasm = class {
804
+ var EdgeAgentDetectorWrapper = class {
721
805
  detector;
722
806
  events = /* @__PURE__ */ new Map();
723
- constructor(config) {
724
- this.detector = new EdgeAgentDetectorWithWasm(config?.enableWasm ?? true);
725
- if (config?.baseUrl) {
726
- this.detector.setBaseUrl(config.baseUrl);
727
- }
728
- }
729
- setBaseUrl(url) {
730
- this.detector.setBaseUrl(url);
807
+ constructor(_config) {
808
+ this.detector = new EdgeAgentDetector();
731
809
  }
732
810
  async analyze(input) {
733
811
  const result = await this.detector.analyze(input);
@@ -748,10 +826,13 @@ var EdgeAgentDetectorWrapperWithWasm = class {
748
826
  handlers.forEach((handler) => handler(...args));
749
827
  }
750
828
  async init() {
751
- await this.detector.init();
829
+ return;
752
830
  }
753
831
  };
754
832
 
833
+ // src/middleware.ts
834
+ init_edge_detector_with_wasm();
835
+
755
836
  // src/session-tracker.ts
756
837
  var EdgeSessionTracker = class {
757
838
  config;
@@ -1102,48 +1183,80 @@ function createAgentShieldMiddleware2(config) {
1102
1183
  };
1103
1184
  }
1104
1185
 
1105
- // src/wasm-confidence.ts
1106
- async function checkWasmAvailability() {
1107
- try {
1108
- if (typeof WebAssembly === "undefined") {
1109
- return false;
1186
+ // src/edge-safe-detector.ts
1187
+ var AI_AGENT_PATTERNS3 = [
1188
+ { pattern: /chatgpt-user/i, type: "chatgpt", name: "ChatGPT" },
1189
+ { pattern: /claude-web/i, type: "claude", name: "Claude" },
1190
+ { pattern: /perplexitybot/i, type: "perplexity", name: "Perplexity" },
1191
+ { pattern: /perplexity-user/i, type: "perplexity", name: "Perplexity" },
1192
+ { pattern: /perplexity/i, type: "perplexity", name: "Perplexity" },
1193
+ { pattern: /bingbot/i, type: "bing", name: "Bing AI" },
1194
+ { pattern: /anthropic-ai/i, type: "anthropic", name: "Anthropic" }
1195
+ ];
1196
+ var EdgeSafeDetector = class {
1197
+ async analyze(input) {
1198
+ const reasons = [];
1199
+ let detectedAgent;
1200
+ let confidence = 0;
1201
+ const headers = input.headers || {};
1202
+ const normalizedHeaders = {};
1203
+ for (const [key, value] of Object.entries(headers)) {
1204
+ normalizedHeaders[key.toLowerCase()] = value;
1110
1205
  }
1111
- if (!WebAssembly.instantiate || !WebAssembly.Module) {
1112
- return false;
1206
+ const userAgent = input.userAgent || normalizedHeaders["user-agent"] || "";
1207
+ if (userAgent) {
1208
+ for (const { pattern, type, name } of AI_AGENT_PATTERNS3) {
1209
+ if (pattern.test(userAgent)) {
1210
+ confidence = 0.85;
1211
+ reasons.push(`known_pattern:${type}`);
1212
+ detectedAgent = { type, name };
1213
+ break;
1214
+ }
1215
+ }
1113
1216
  }
1114
- return true;
1115
- } catch {
1116
- return false;
1117
- }
1118
- }
1119
- function shouldIndicateWasmVerification(confidence) {
1120
- return confidence >= 0.85 && confidence < 1;
1121
- }
1122
- function getWasmConfidenceBoost(baseConfidence, reasons = []) {
1123
- if (reasons.some(
1124
- (r) => r.includes("signature_agent") && !r.includes("signature_headers_present")
1125
- )) {
1126
- return 1;
1127
- }
1128
- if (baseConfidence >= 0.85) {
1129
- return 0.95;
1130
- }
1131
- if (baseConfidence >= 0.7) {
1132
- return Math.min(baseConfidence * 1.1, 0.9);
1133
- }
1134
- return baseConfidence;
1135
- }
1136
- function getVerificationMethod(confidence, reasons = []) {
1137
- if (reasons.some(
1138
- (r) => r.includes("signature_agent") && !r.includes("signature_headers_present")
1139
- )) {
1140
- return "signature";
1141
- }
1142
- if (shouldIndicateWasmVerification(confidence)) {
1143
- return "wasm-enhanced";
1217
+ const hasChrome = userAgent.toLowerCase().includes("chrome");
1218
+ const hasFirefox = userAgent.toLowerCase().includes("firefox");
1219
+ const hasSafari = userAgent.toLowerCase().includes("safari");
1220
+ const hasBrowserUA = hasChrome || hasFirefox || hasSafari;
1221
+ if (hasBrowserUA) {
1222
+ const hasSecChUa = !!normalizedHeaders["sec-ch-ua"];
1223
+ const hasSecFetch = !!normalizedHeaders["sec-fetch-site"];
1224
+ const hasAcceptLanguage = !!normalizedHeaders["accept-language"];
1225
+ const hasCookies = !!normalizedHeaders["cookie"];
1226
+ const missingHeaders = [];
1227
+ if (!hasSecChUa && hasChrome) missingHeaders.push("sec-ch-ua");
1228
+ if (!hasSecFetch) missingHeaders.push("sec-fetch");
1229
+ if (!hasAcceptLanguage) missingHeaders.push("accept-language");
1230
+ if (!hasCookies) missingHeaders.push("cookies");
1231
+ if (missingHeaders.length >= 2) {
1232
+ confidence = Math.max(confidence, 0.85);
1233
+ reasons.push("browser_ua_missing_headers");
1234
+ if (!detectedAgent && hasChrome && !hasSecChUa) {
1235
+ detectedAgent = { type: "perplexity", name: "Perplexity" };
1236
+ }
1237
+ }
1238
+ }
1239
+ const aiHeaders = [
1240
+ "openai-conversation-id",
1241
+ "anthropic-client-id",
1242
+ "x-goog-api-client"
1243
+ ];
1244
+ const foundAiHeaders = aiHeaders.filter((h) => normalizedHeaders[h]);
1245
+ if (foundAiHeaders.length > 0) {
1246
+ confidence = Math.max(confidence, 0.6);
1247
+ reasons.push(`ai_headers:${foundAiHeaders.length}`);
1248
+ }
1249
+ return {
1250
+ isAgent: confidence > 0.3,
1251
+ confidence,
1252
+ detectedAgent,
1253
+ reasons,
1254
+ verificationMethod: "pattern",
1255
+ timestamp: /* @__PURE__ */ new Date(),
1256
+ confidenceLevel: confidence >= 0.8 ? "high" : confidence >= 0.5 ? "medium" : "low"
1257
+ };
1144
1258
  }
1145
- return "pattern";
1146
- }
1259
+ };
1147
1260
 
1148
1261
  // src/storage/memory-adapter.ts
1149
1262
  var MemoryStorageAdapter = class {
@@ -1418,39 +1531,48 @@ function createEnhancedAgentShieldMiddleware(config = {}) {
1418
1531
  };
1419
1532
  let detector = null;
1420
1533
  let detectorInitPromise = null;
1534
+ let wasmConfidenceUtils = null;
1421
1535
  const getDetector = async (requestUrl) => {
1422
1536
  if (detector) {
1423
- if (requestUrl && "setBaseUrl" in detector) {
1424
- detector.setBaseUrl(requestUrl);
1425
- }
1426
1537
  return detector;
1427
1538
  }
1428
1539
  if (detectorInitPromise) {
1429
1540
  await detectorInitPromise;
1430
- if (requestUrl && detector && "setBaseUrl" in detector) {
1431
- detector.setBaseUrl(requestUrl);
1432
- }
1433
1541
  return detector;
1434
1542
  }
1435
1543
  detectorInitPromise = (async () => {
1436
- try {
1437
- const wasmAvailable = await checkWasmAvailability();
1438
- if (wasmAvailable) {
1439
- console.log("[AgentShield] \u2705 WASM support detected - enhanced detection enabled");
1440
- detector = new EdgeAgentDetectorWrapperWithWasm({ enableWasm: true });
1441
- } else {
1442
- console.log("[AgentShield] \u2139\uFE0F Using pattern-based detection (WASM not available)");
1443
- detector = new EdgeAgentDetectorWrapper({});
1544
+ const isEdgeRuntime = typeof globalThis.EdgeRuntime !== "undefined" || process.env.NEXT_RUNTIME === "edge";
1545
+ if (isEdgeRuntime) {
1546
+ console.log("[AgentShield] Edge Runtime detected - using pattern detection");
1547
+ detector = new EdgeSafeDetector();
1548
+ } else {
1549
+ try {
1550
+ try {
1551
+ const wasmUtils = await Promise.resolve().then(() => (init_wasm_confidence(), wasm_confidence_exports));
1552
+ wasmConfidenceUtils = wasmUtils;
1553
+ const wasmAvailable = await wasmUtils.checkWasmAvailability();
1554
+ if (wasmAvailable) {
1555
+ const { EdgeAgentDetectorWrapperWithWasm: EdgeAgentDetectorWrapperWithWasm2 } = await Promise.resolve().then(() => (init_edge_detector_with_wasm(), edge_detector_with_wasm_exports));
1556
+ console.log("[AgentShield] \u2705 WASM support detected - enhanced detection enabled");
1557
+ detector = new EdgeAgentDetectorWrapperWithWasm2({ enableWasm: true });
1558
+ if (requestUrl && "setBaseUrl" in detector) {
1559
+ detector.setBaseUrl(requestUrl);
1560
+ }
1561
+ } else {
1562
+ console.log("[AgentShield] \u2139\uFE0F Using pattern-based detection (WASM not available)");
1563
+ detector = new EdgeSafeDetector();
1564
+ }
1565
+ } catch (wasmError) {
1566
+ console.log("[AgentShield] WASM utilities not available, using pattern detection");
1567
+ detector = new EdgeSafeDetector();
1568
+ }
1569
+ } catch (error) {
1570
+ console.warn("[AgentShield] Failed to initialize enhanced detector, using fallback");
1571
+ detector = new EdgeSafeDetector();
1444
1572
  }
1445
- } catch (error) {
1446
- console.warn("[AgentShield] Failed to initialize WASM, using fallback:", error);
1447
- detector = new EdgeAgentDetectorWrapper({});
1448
1573
  }
1449
1574
  })();
1450
1575
  await detectorInitPromise;
1451
- if (requestUrl && detector && "setBaseUrl" in detector) {
1452
- detector.setBaseUrl(requestUrl);
1453
- }
1454
1576
  return detector;
1455
1577
  };
1456
1578
  const sessionManager = new SessionManager();
@@ -1476,11 +1598,11 @@ function createEnhancedAgentShieldMiddleware(config = {}) {
1476
1598
  const result = await activeDetector.analyze(context);
1477
1599
  let finalConfidence = result.confidence;
1478
1600
  let verificationMethod = result.verificationMethod || "pattern";
1479
- if (result.isAgent) {
1601
+ if (result.isAgent && wasmConfidenceUtils) {
1480
1602
  const reasons = result.reasons || [];
1481
- if (shouldIndicateWasmVerification(result.confidence)) {
1482
- finalConfidence = getWasmConfidenceBoost(result.confidence, reasons);
1483
- verificationMethod = getVerificationMethod(finalConfidence, reasons);
1603
+ if (wasmConfidenceUtils.shouldIndicateWasmVerification(result.confidence)) {
1604
+ finalConfidence = wasmConfidenceUtils.getWasmConfidenceBoost(result.confidence, reasons);
1605
+ verificationMethod = wasmConfidenceUtils.getVerificationMethod(finalConfidence, reasons);
1484
1606
  }
1485
1607
  }
1486
1608
  if (result.isAgent && finalConfidence >= (config.confidenceThreshold ?? 0.7)) {