@devtune/ai-traffic 0.12.1 → 0.13.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/README.md +75 -12
- package/dist/cjs/client.js +326 -73
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/detection.js +14 -3
- package/dist/cjs/detection.js.map +1 -1
- package/dist/cjs/express.js +4 -0
- package/dist/cjs/express.js.map +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/node.js +4 -0
- package/dist/cjs/node.js.map +1 -1
- package/dist/cjs/referral.js +130 -0
- package/dist/cjs/referral.js.map +1 -0
- package/dist/cjs/registry.js +2 -0
- package/dist/cjs/registry.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/client.d.ts +139 -19
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +325 -72
- package/dist/client.js.map +1 -1
- package/dist/detection.d.ts +4 -0
- package/dist/detection.d.ts.map +1 -1
- package/dist/detection.js +12 -3
- package/dist/detection.js.map +1 -1
- package/dist/express.js +4 -0
- package/dist/express.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/node.js +4 -0
- package/dist/node.js.map +1 -1
- package/dist/referral.d.ts +39 -0
- package/dist/referral.d.ts.map +1 -0
- package/dist/referral.js +124 -0
- package/dist/referral.js.map +1 -0
- package/dist/registry.d.ts +2 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +2 -2
- package/dist/registry.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ABOUTME: Implements the DevTune AI Traffic edge-push client.
|
|
3
|
-
* Handles registry refresh, AI bot matching, batched ingest beacons, and route wrappers.
|
|
3
|
+
* Handles registry refresh, AI bot and AI referral matching, batched ingest beacons, and route wrappers.
|
|
4
4
|
*/
|
|
5
|
-
import { type AiBotRegistryEntry } from "./registry.js";
|
|
5
|
+
import { type AiBotRegistryEntry, type LlmPlatform } from "./registry.js";
|
|
6
6
|
import { type DevTuneAiTrafficTrustedProxy } from "./client-ip.js";
|
|
7
7
|
import { type DevTuneAiTrafficWebBotAuth } from "./web-bot-auth.js";
|
|
8
8
|
export interface HeadersLike {
|
|
@@ -15,6 +15,12 @@ export interface HeadersLike {
|
|
|
15
15
|
* first value.
|
|
16
16
|
*/
|
|
17
17
|
getCombined?(name: string): string | null;
|
|
18
|
+
/**
|
|
19
|
+
* Every header name on the request. Only read to look for a `fastly-*`
|
|
20
|
+
* header, which marks a request Fastly forwarded. Fetch `Headers` have it;
|
|
21
|
+
* without it only `fastly-client-ip`, `fastly-ff` and `fastly-ssl` are checked.
|
|
22
|
+
*/
|
|
23
|
+
keys?(): Iterable<string>;
|
|
18
24
|
}
|
|
19
25
|
export interface RequestLike {
|
|
20
26
|
headers: HeadersLike;
|
|
@@ -24,7 +30,10 @@ export interface RequestLike {
|
|
|
24
30
|
* edge runtimes have no socket and leave it undefined.
|
|
25
31
|
*/
|
|
26
32
|
ip?: string | null;
|
|
27
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Request method, needed to forward a Web Bot Auth signature and to record
|
|
35
|
+
* a referral visit: only a `GET` can be one.
|
|
36
|
+
*/
|
|
28
37
|
method?: string;
|
|
29
38
|
/**
|
|
30
39
|
* The absolute request URL exactly as the client sent it, for a runtime
|
|
@@ -36,6 +45,10 @@ export interface RequestLike {
|
|
|
36
45
|
*/
|
|
37
46
|
targetUri?: string | null;
|
|
38
47
|
}
|
|
48
|
+
/** What the prefilter reads. Without a `url` only the bot check runs. */
|
|
49
|
+
type ReferralCandidateRequest = Pick<RequestLike, "headers" | "method"> & {
|
|
50
|
+
url?: string;
|
|
51
|
+
};
|
|
39
52
|
export interface WaitUntilLike {
|
|
40
53
|
waitUntil(promise: Promise<unknown>): void;
|
|
41
54
|
}
|
|
@@ -58,11 +71,43 @@ export interface DevTuneAiTrafficEvent {
|
|
|
58
71
|
* signature headers. DevTune verifies and discards it; it is never stored.
|
|
59
72
|
*/
|
|
60
73
|
webBotAuth?: DevTuneAiTrafficWebBotAuth;
|
|
74
|
+
/** A referral visit's `Referer`, cut to its origin. Referral events only. */
|
|
75
|
+
referrer?: string;
|
|
76
|
+
/** A referral visit's campaign parameters from the query the `url` leaves out. Referral events only. */
|
|
77
|
+
campaign?: DevTuneAiTrafficCampaign;
|
|
78
|
+
/**
|
|
79
|
+
* True when the request came through a CDN (`cf-ray`, `x-amz-cf-id` or a
|
|
80
|
+
* `fastly-*` header), so a cache may have answered page loads the sensor
|
|
81
|
+
* never saw. Omitted otherwise.
|
|
82
|
+
*/
|
|
83
|
+
cdn?: boolean;
|
|
61
84
|
}
|
|
62
|
-
|
|
85
|
+
/**
|
|
86
|
+
* The landing URL's campaign parameters DevTune reads to classify a referral
|
|
87
|
+
* visit and to recognise a paid click. Each is present only when the URL had
|
|
88
|
+
* it; `oppref` is the presence of OpenAI's ad click ID, never its value.
|
|
89
|
+
*/
|
|
90
|
+
export interface DevTuneAiTrafficCampaign {
|
|
91
|
+
utm_source?: string;
|
|
92
|
+
utm_medium?: string;
|
|
93
|
+
oppref?: boolean;
|
|
94
|
+
}
|
|
95
|
+
export interface DevTuneAiTrafficBotMatch {
|
|
96
|
+
kind: "bot";
|
|
63
97
|
entry: AiBotRegistryEntry;
|
|
64
98
|
event: DevTuneAiTrafficEvent;
|
|
65
99
|
}
|
|
100
|
+
export interface DevTuneAiTrafficReferralMatch {
|
|
101
|
+
kind: "referral";
|
|
102
|
+
/**
|
|
103
|
+
* The AI platform the visit came from, by its `Referer` host or else its
|
|
104
|
+
* `utm_source`. DevTune classifies the event again on receipt and drops a
|
|
105
|
+
* paid click.
|
|
106
|
+
*/
|
|
107
|
+
platform: LlmPlatform;
|
|
108
|
+
event: DevTuneAiTrafficEvent;
|
|
109
|
+
}
|
|
110
|
+
export type DevTuneAiTrafficMatch = DevTuneAiTrafficBotMatch | DevTuneAiTrafficReferralMatch;
|
|
66
111
|
export interface DevTuneAiTrafficLogger {
|
|
67
112
|
warn(message: string, context?: Record<string, unknown>): void;
|
|
68
113
|
debug?(message: string, context?: Record<string, unknown>): void;
|
|
@@ -96,6 +141,16 @@ export interface DevTuneAiTrafficOptions {
|
|
|
96
141
|
maxRetryAttempts?: number;
|
|
97
142
|
maxRetryDelayMs?: number;
|
|
98
143
|
maxQueuedEvents?: number;
|
|
144
|
+
/**
|
|
145
|
+
* Bound on queued AI referral visits, kept apart from the bot queue so
|
|
146
|
+
* referrals never push out bot events. Defaults to 200.
|
|
147
|
+
*/
|
|
148
|
+
maxQueuedReferralEvents?: number;
|
|
149
|
+
/**
|
|
150
|
+
* Record AI referral visits. Defaults to true; `false` records AI bot
|
|
151
|
+
* requests only, as the sensor did before 0.13.0.
|
|
152
|
+
*/
|
|
153
|
+
captureReferrals?: boolean;
|
|
99
154
|
/**
|
|
100
155
|
* Which address source to trust for bot verification. Defaults to the
|
|
101
156
|
* platform's own forwarded header on Vercel and to the socket peer
|
|
@@ -124,6 +179,8 @@ export declare class DevTuneAiTrafficClient {
|
|
|
124
179
|
private readonly maxRetryAttempts;
|
|
125
180
|
private readonly maxRetryDelayMs;
|
|
126
181
|
private readonly maxQueuedEvents;
|
|
182
|
+
private readonly maxQueuedReferralEvents;
|
|
183
|
+
private readonly captureReferrals;
|
|
127
184
|
private readonly trustedProxy;
|
|
128
185
|
private readonly projectId;
|
|
129
186
|
private readonly keyCredential;
|
|
@@ -135,13 +192,23 @@ export declare class DevTuneAiTrafficClient {
|
|
|
135
192
|
private flushPromise;
|
|
136
193
|
private delayedFlushPromise;
|
|
137
194
|
private readonly queue;
|
|
195
|
+
private readonly referralQueue;
|
|
138
196
|
constructor(options: DevTuneAiTrafficOptions);
|
|
139
|
-
mightTrackRequest(request: Pick<RequestLike, "headers">): boolean;
|
|
140
197
|
/**
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
198
|
+
* A cheap check that `trackRequest()` could record this request: true for
|
|
199
|
+
* an AI bot candidate, by user agent alone, or for an AI referral candidate
|
|
200
|
+
* (see `matchReferralPlatform`). Adapters that record after the response
|
|
201
|
+
* call it first, so other requests cost no response work. A request without
|
|
202
|
+
* a `url` is checked as a bot candidate only.
|
|
203
|
+
*/
|
|
204
|
+
mightTrackRequest(request: ReferralCandidateRequest): boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Records a matched AI bot request or AI referral visit. A user agent in
|
|
207
|
+
* the bot registry makes it a bot request whatever its `Referer`. Pass
|
|
208
|
+
* `receivedAt` when the request is recorded after its response, taken from
|
|
209
|
+
* `signedArrivalTime()` as the request arrived: a signed bot event is
|
|
210
|
+
* checked against the time it was signed for. Other events keep the time
|
|
211
|
+
* they are recorded.
|
|
145
212
|
*/
|
|
146
213
|
trackRequest(request: RequestLike, waitUntilContext?: WaitUntilLike, responseStatus?: number | null, receivedAt?: Date): DevTuneAiTrafficMatch | null;
|
|
147
214
|
/**
|
|
@@ -153,23 +220,74 @@ export declare class DevTuneAiTrafficClient {
|
|
|
153
220
|
signedArrivalTime(request: Pick<RequestLike, "headers">): Date | undefined;
|
|
154
221
|
refreshRegistry(): Promise<void>;
|
|
155
222
|
flush(): Promise<void>;
|
|
223
|
+
/**
|
|
224
|
+
* Starts a drain, or joins the one in flight. A drain that spends a retry
|
|
225
|
+
* budget leaves events queued that would otherwise wait for the next tracked
|
|
226
|
+
* request, so it schedules one follow-up drain, no sooner than a capped
|
|
227
|
+
* retry's wait. The follow-up schedules none: if it is throttled too, the
|
|
228
|
+
* rest waits for the next tracked request, as before 0.13.0. The timer is
|
|
229
|
+
* unref'd and not tied to `waitUntil`, so only a long-lived process runs it.
|
|
230
|
+
*/
|
|
231
|
+
private startDrain;
|
|
156
232
|
/** Starts at most one background refresh per cache interval, including browser traffic. */
|
|
157
233
|
refreshRegistryIfStale(waitUntilContext?: WaitUntilLike): void;
|
|
158
|
-
private
|
|
234
|
+
private mightBeAiBot;
|
|
235
|
+
/**
|
|
236
|
+
* A bot registry match that is not a page's own request, or failing that the
|
|
237
|
+
* AI platform a referral visit came from. A bot user agent wins: it is never
|
|
238
|
+
* recorded as a referral.
|
|
239
|
+
*/
|
|
240
|
+
private matchSource;
|
|
241
|
+
/**
|
|
242
|
+
* The AI platform a referral candidate came from, or null. A candidate is a
|
|
243
|
+
* `GET` from another site (`Sec-Fetch-Site` not `same-origin` or
|
|
244
|
+
* `same-site`) whose `Referer` host, or failing that `utm_source`, is in the
|
|
245
|
+
* registry, and that loads a top-level page: `Sec-Fetch-Dest` is `document`
|
|
246
|
+
* or absent, it is not a prefetch, and it is not a framework data request.
|
|
247
|
+
* Frames stay bot-only. Every request reaches this, so the method and
|
|
248
|
+
* fetch-site checks and substring tests run before any URL is parsed.
|
|
249
|
+
* Browsers send the `Referer` host lower-cased, as the registry lists it.
|
|
250
|
+
* Always null when `captureReferrals` is off.
|
|
251
|
+
*/
|
|
252
|
+
private matchReferralPlatform;
|
|
253
|
+
/** The `Referer` host's platform, or else the `utm_source`'s, as DevTune's classifier orders them. */
|
|
254
|
+
private matchReferrerOrUtmSource;
|
|
255
|
+
private createBotEvent;
|
|
256
|
+
/**
|
|
257
|
+
* A referral visit carries its `Referer` origin and campaign parameters,
|
|
258
|
+
* and never an address or signature material: there is no claimed crawler
|
|
259
|
+
* identity to verify. A visit answered with a redirect is not recorded:
|
|
260
|
+
* the browser takes the same `Referer` to the redirect's target, which is
|
|
261
|
+
* where DevTune counts it, so ingest drops the redirect's event.
|
|
262
|
+
*/
|
|
263
|
+
private createReferralEvent;
|
|
264
|
+
/** The fields every event carries. The `url` is the origin and path, without the query. */
|
|
265
|
+
private createBaseFields;
|
|
159
266
|
private resolveStatus;
|
|
160
267
|
private matchesNotFoundPath;
|
|
161
268
|
/**
|
|
162
|
-
* Adds an event to
|
|
269
|
+
* Adds an event to its queue and decides when to send.
|
|
163
270
|
*
|
|
164
271
|
* Backing off on a 429 means the queue can now drain slower than traffic
|
|
165
272
|
* arrives, which it never could when every batch cost exactly one request.
|
|
166
273
|
* The bound is what keeps that from growing without limit in a customer's
|
|
167
274
|
* process: past `maxQueuedEvents` the oldest events are shed, because the
|
|
168
|
-
* newest ones are the ones still worth measuring.
|
|
275
|
+
* newest ones are the ones still worth measuring. Referral visits have
|
|
276
|
+
* their own queue and bound, `maxQueuedReferralEvents`, so a burst of them
|
|
277
|
+
* never sheds a bot event.
|
|
169
278
|
*/
|
|
170
279
|
private enqueue;
|
|
280
|
+
/** Sheds the oldest events past a queue's bound, with a sampled warning. */
|
|
281
|
+
private shedOverflow;
|
|
171
282
|
/**
|
|
172
|
-
* Drains the
|
|
283
|
+
* Drains the queues one wire batch at a time, bots before referrals. A
|
|
284
|
+
* batch never mixes the two, and referrals never cost bots: each has its own
|
|
285
|
+
* retry budget per flush, a referral batch that spends its budget is dropped
|
|
286
|
+
* while bots keep draining, and a referral batch that gets a 429 while bots
|
|
287
|
+
* are waiting goes back to the front of its queue after the backoff, with
|
|
288
|
+
* its attempt count, so the bots are sent first. When the bots' budget is
|
|
289
|
+
* spent the drain ends there: the rate limit covers both kinds, so referrals
|
|
290
|
+
* would only meet the same 429, and the next drain starts with bots.
|
|
173
291
|
*
|
|
174
292
|
* A 429 is the one failure the ingest endpoint tells us is temporary, so the
|
|
175
293
|
* batch is held out of the queue and redelivered after the server's
|
|
@@ -179,14 +297,14 @@ export declare class DevTuneAiTrafficClient {
|
|
|
179
297
|
* are not folded into the batch being retried, so they cannot be dropped on a
|
|
180
298
|
* bound they never had a chance to spend.
|
|
181
299
|
*
|
|
182
|
-
*
|
|
300
|
+
* Each budget belongs to the whole drain, not to each batch. A per-batch
|
|
183
301
|
* bound says nothing about how long a drain can run, because a throttled
|
|
184
302
|
* endpoint rejects every batch in turn and traffic keeps arriving behind it.
|
|
185
|
-
* One budget per pass caps the added latency of a flush at
|
|
186
|
-
* `maxRetryAttempts * maxRetryDelayMs` no matter how deep the
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* fresh budget.
|
|
303
|
+
* One budget per kind per pass caps the added latency of a flush at
|
|
304
|
+
* `2 * maxRetryAttempts * maxRetryDelayMs` no matter how deep the queues
|
|
305
|
+
* are. When a budget is spent the current batch is dropped with the usual
|
|
306
|
+
* sampled warning, leaving the rest queued for the next flush, which gets
|
|
307
|
+
* fresh budgets. Resolves true when a budget was spent.
|
|
190
308
|
*
|
|
191
309
|
* Every other failure keeps its previous behavior: one attempt, dropped, and
|
|
192
310
|
* a sampled warning.
|
|
@@ -233,6 +351,7 @@ export declare class DevTuneAiTrafficClient {
|
|
|
233
351
|
* transient failure, so it is reported once per client instead of sampled.
|
|
234
352
|
*/
|
|
235
353
|
private warnMissingVercelOidcTokenOnce;
|
|
354
|
+
private queuedEventCount;
|
|
236
355
|
private resolveRetryDelayMs;
|
|
237
356
|
private sampleWarn;
|
|
238
357
|
}
|
|
@@ -240,4 +359,5 @@ export declare function createDevTuneAiTraffic(options: DevTuneAiTrafficOptions)
|
|
|
240
359
|
export declare function createDevTuneAiTrafficMiddleware(options: DevTuneAiTrafficOptions): (request: RequestLike, event?: WaitUntilLike) => void;
|
|
241
360
|
export declare function mightBeAiBotUserAgent(userAgent: string | null | undefined): boolean;
|
|
242
361
|
export declare function withDevTuneAiTrafficRoute<Context, ResponseType extends Response>(handler: DevTuneAiTrafficRouteHandler<Context, ResponseType>, options: DevTuneAiTrafficOptions): (request: RequestLike, context: Context) => Promise<ResponseType>;
|
|
362
|
+
export {};
|
|
243
363
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|