@ainyc/canonry 4.71.0 → 4.71.1
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.
|
@@ -95,7 +95,7 @@ import {
|
|
|
95
95
|
runs,
|
|
96
96
|
schedules,
|
|
97
97
|
usageCounters
|
|
98
|
-
} from "./chunk-
|
|
98
|
+
} from "./chunk-ETJDAMGA.js";
|
|
99
99
|
import {
|
|
100
100
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
101
101
|
AGENT_PROVIDER_IDS,
|
|
@@ -5618,7 +5618,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
5618
5618
|
return result;
|
|
5619
5619
|
}
|
|
5620
5620
|
async function backfillInsightsCommand(project, opts) {
|
|
5621
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
5621
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-ISO4VGEC.js");
|
|
5622
5622
|
const config = loadConfig();
|
|
5623
5623
|
const db = createClient(config.database);
|
|
5624
5624
|
migrate(db);
|
|
@@ -27326,10 +27326,11 @@ async function resolveRetainedStart(options, unservableStartMs, endMs) {
|
|
|
27326
27326
|
async function drainVercelTrafficEvents(options) {
|
|
27327
27327
|
const startMs = toMs(options.startDate);
|
|
27328
27328
|
const endMs = toMs(options.endDate);
|
|
27329
|
+
const now = options.now ?? (() => Date.now());
|
|
27329
27330
|
const events = [];
|
|
27330
27331
|
const seenEventIds = /* @__PURE__ */ new Set();
|
|
27331
27332
|
if (endMs <= startMs) {
|
|
27332
|
-
return { events, subWindowCount: 0, effectiveStartMs: startMs, retentionClamped: false, truncatedSliceCount: 0, truncatedSliceStartsMs: [] };
|
|
27333
|
+
return { events, subWindowCount: 0, effectiveStartMs: startMs, retentionClamped: false, truncatedSliceCount: 0, truncatedSliceStartsMs: [], drainedThroughMs: startMs, deadlineReached: false };
|
|
27333
27334
|
}
|
|
27334
27335
|
let cursorMs = startMs;
|
|
27335
27336
|
let spanMs = endMs - startMs;
|
|
@@ -27340,8 +27341,13 @@ async function drainVercelTrafficEvents(options) {
|
|
|
27340
27341
|
let floorSpanProbeCountdown = 0;
|
|
27341
27342
|
let floorPageBudgetCountdown = 0;
|
|
27342
27343
|
let truncatedSliceCount = 0;
|
|
27344
|
+
let deadlineReached = false;
|
|
27343
27345
|
const truncatedSliceStartsMs = [];
|
|
27344
27346
|
while (cursorMs < endMs) {
|
|
27347
|
+
if (options.deadlineMs !== void 0 && now() >= options.deadlineMs) {
|
|
27348
|
+
deadlineReached = true;
|
|
27349
|
+
break;
|
|
27350
|
+
}
|
|
27345
27351
|
if (subWindowCount >= options.maxSubWindows) {
|
|
27346
27352
|
throw new Error(
|
|
27347
27353
|
`Vercel window not drained within ${options.maxSubWindows} sub-windows \u2014 narrow the time range`
|
|
@@ -27428,7 +27434,7 @@ async function drainVercelTrafficEvents(options) {
|
|
|
27428
27434
|
}
|
|
27429
27435
|
}
|
|
27430
27436
|
}
|
|
27431
|
-
return { events, subWindowCount, effectiveStartMs, retentionClamped, truncatedSliceCount, truncatedSliceStartsMs };
|
|
27437
|
+
return { events, subWindowCount, effectiveStartMs, retentionClamped, truncatedSliceCount, truncatedSliceStartsMs, drainedThroughMs: cursorMs, deadlineReached };
|
|
27432
27438
|
}
|
|
27433
27439
|
|
|
27434
27440
|
// ../api-routes/src/traffic.ts
|
|
@@ -27440,6 +27446,8 @@ var DEFAULT_WP_PAGE_SIZE = 500;
|
|
|
27440
27446
|
var DEFAULT_WP_MAX_PAGES = 20;
|
|
27441
27447
|
var DEFAULT_VERCEL_MAX_PAGES = 50;
|
|
27442
27448
|
var VERCEL_MAX_SUB_WINDOWS = 5e3;
|
|
27449
|
+
var VERCEL_MAX_SYNC_WINDOW_MS = 24 * 60 * 6e4;
|
|
27450
|
+
var DEFAULT_VERCEL_SYNC_DEADLINE_MS = 4 * 6e4;
|
|
27443
27451
|
var VERCEL_BACKFILL_CHUNK_MS = 60 * 6e4;
|
|
27444
27452
|
var MAX_TRACKED_EVENT_IDS = 1e3;
|
|
27445
27453
|
var DEFAULT_BACKFILL_DAYS = 30;
|
|
@@ -27687,6 +27695,7 @@ async function trafficRoutes(app, opts) {
|
|
|
27687
27695
|
}
|
|
27688
27696
|
}
|
|
27689
27697
|
const vercelMaxPages = opts.defaultVercelMaxPages ?? DEFAULT_VERCEL_MAX_PAGES;
|
|
27698
|
+
const vercelSyncDeadlineMs = opts.vercelSyncDeadlineMs ?? DEFAULT_VERCEL_SYNC_DEADLINE_MS;
|
|
27690
27699
|
const syncWindowMinutes = opts.defaultSyncWindowMinutes ?? DEFAULT_SYNC_WINDOW_MINUTES;
|
|
27691
27700
|
const pageSize = opts.defaultPageSize ?? DEFAULT_PAGE_SIZE3;
|
|
27692
27701
|
const maxPages = opts.defaultMaxPages ?? DEFAULT_MAX_PAGES4;
|
|
@@ -28038,6 +28047,7 @@ async function trafficRoutes(app, opts) {
|
|
|
28038
28047
|
let allEvents;
|
|
28039
28048
|
let nextCursor;
|
|
28040
28049
|
let auditAction;
|
|
28050
|
+
let effectiveWindowEnd = windowEnd;
|
|
28041
28051
|
if (sourceRow.sourceType === TrafficSourceTypes["cloud-run"]) {
|
|
28042
28052
|
auditAction = "traffic.cloud-run.synced";
|
|
28043
28053
|
const credentialStore = opts.cloudRunCredentialStore;
|
|
@@ -28163,9 +28173,19 @@ async function trafficRoutes(app, opts) {
|
|
|
28163
28173
|
const windowMinutes = Number.isFinite(requestedMinutes) && requestedMinutes && requestedMinutes > 0 ? Math.floor(requestedMinutes) : syncWindowMinutes;
|
|
28164
28174
|
const requestedStartMs = windowEnd.getTime() - windowMinutes * 6e4;
|
|
28165
28175
|
const lastSyncedMs = sourceRow.lastSyncedAt ? new Date(sourceRow.lastSyncedAt).getTime() : Number.NEGATIVE_INFINITY;
|
|
28166
|
-
|
|
28167
|
-
|
|
28168
|
-
)
|
|
28176
|
+
const clampedStartMs = Math.min(windowEnd.getTime(), Math.max(requestedStartMs, lastSyncedMs));
|
|
28177
|
+
const cappedStartMs = Math.max(clampedStartMs, windowEnd.getTime() - VERCEL_MAX_SYNC_WINDOW_MS);
|
|
28178
|
+
if (cappedStartMs > clampedStartMs) {
|
|
28179
|
+
request.log.warn(
|
|
28180
|
+
{
|
|
28181
|
+
sourceId: sourceRow.id,
|
|
28182
|
+
requestedStart: new Date(clampedStartMs).toISOString(),
|
|
28183
|
+
cappedStart: new Date(cappedStartMs).toISOString()
|
|
28184
|
+
},
|
|
28185
|
+
"Vercel sync window exceeded the max single-sync span; clamped the start forward (older traffic skipped \u2014 run a backfill to recover it)"
|
|
28186
|
+
);
|
|
28187
|
+
}
|
|
28188
|
+
windowStart = new Date(cappedStartMs);
|
|
28169
28189
|
try {
|
|
28170
28190
|
const drained = await drainVercelTrafficEvents({
|
|
28171
28191
|
pull: pullVercelEvents,
|
|
@@ -28176,11 +28196,31 @@ async function trafficRoutes(app, opts) {
|
|
|
28176
28196
|
startDate: windowStart.getTime(),
|
|
28177
28197
|
endDate: windowEnd.getTime(),
|
|
28178
28198
|
pagesPerSubWindow: vercelMaxPages,
|
|
28179
|
-
maxSubWindows: VERCEL_MAX_SUB_WINDOWS
|
|
28199
|
+
maxSubWindows: VERCEL_MAX_SUB_WINDOWS,
|
|
28200
|
+
// Bound the drain's wall-clock so a dense/slow window can't run for
|
|
28201
|
+
// many minutes. On hit the drain stops and reports how far it got.
|
|
28202
|
+
deadlineMs: syncStartedAtMs + vercelSyncDeadlineMs
|
|
28180
28203
|
});
|
|
28181
28204
|
if (drained.retentionClamped) {
|
|
28182
28205
|
throw vercelRetentionClampError(windowStart.getTime(), drained.effectiveStartMs);
|
|
28183
28206
|
}
|
|
28207
|
+
if (drained.deadlineReached) {
|
|
28208
|
+
if (drained.drainedThroughMs <= windowStart.getTime()) {
|
|
28209
|
+
throw new Error(
|
|
28210
|
+
`sync exceeded its ${vercelSyncDeadlineMs}ms drain budget without completing any sub-window (request-logs slow or unavailable)`
|
|
28211
|
+
);
|
|
28212
|
+
}
|
|
28213
|
+
effectiveWindowEnd = new Date(drained.drainedThroughMs);
|
|
28214
|
+
request.log.warn(
|
|
28215
|
+
{
|
|
28216
|
+
sourceId: sourceRow.id,
|
|
28217
|
+
drainedThrough: effectiveWindowEnd.toISOString(),
|
|
28218
|
+
requestedEnd: windowEnd.toISOString(),
|
|
28219
|
+
subWindows: drained.subWindowCount
|
|
28220
|
+
},
|
|
28221
|
+
"Vercel drain hit its time budget; committing the partial window and advancing to it \u2014 next sync resumes from here"
|
|
28222
|
+
);
|
|
28223
|
+
}
|
|
28184
28224
|
if (drained.truncatedSliceCount > 0) {
|
|
28185
28225
|
request.log.warn(
|
|
28186
28226
|
{
|
|
@@ -28364,11 +28404,13 @@ async function trafficRoutes(app, opts) {
|
|
|
28364
28404
|
}
|
|
28365
28405
|
const sourceUpdate = {
|
|
28366
28406
|
status: TrafficSourceStatuses.connected,
|
|
28367
|
-
// Advance to
|
|
28368
|
-
// source between
|
|
28369
|
-
// range. If we stored finishedAt, the next sync's clamp would skip
|
|
28370
|
-
//
|
|
28371
|
-
|
|
28407
|
+
// Advance to effectiveWindowEnd, not finishedAt — events arriving at the
|
|
28408
|
+
// source between the window end and finishedAt aren't in this pull's
|
|
28409
|
+
// range. If we stored finishedAt, the next sync's clamp would skip past
|
|
28410
|
+
// them and they'd be lost. effectiveWindowEnd equals windowEnd on a full
|
|
28411
|
+
// sync; for a Vercel drain that stopped at its deadline it is the partial
|
|
28412
|
+
// boundary, so the next sync resumes exactly where this one left off.
|
|
28413
|
+
lastSyncedAt: effectiveWindowEnd.toISOString(),
|
|
28372
28414
|
lastError: null,
|
|
28373
28415
|
lastEventIds: nextEventIds,
|
|
28374
28416
|
updatedAt: finishedAt
|
|
@@ -28421,7 +28463,9 @@ async function trafficRoutes(app, opts) {
|
|
|
28421
28463
|
aiReferralBucketRows,
|
|
28422
28464
|
sampleRows,
|
|
28423
28465
|
windowStart: windowStart.toISOString(),
|
|
28424
|
-
|
|
28466
|
+
// The window actually synced: equals windowEnd on a full sync, or the
|
|
28467
|
+
// partial boundary when a Vercel drain stopped at its deadline.
|
|
28468
|
+
windowEnd: effectiveWindowEnd.toISOString()
|
|
28425
28469
|
};
|
|
28426
28470
|
return response;
|
|
28427
28471
|
});
|
|
@@ -31208,6 +31252,7 @@ async function apiRoutes(app, opts) {
|
|
|
31208
31252
|
pullWordpressTrafficEvents: opts.pullWordpressTrafficEvents,
|
|
31209
31253
|
vercelTrafficCredentialStore: opts.vercelTrafficCredentialStore,
|
|
31210
31254
|
pullVercelTrafficEvents: opts.pullVercelTrafficEvents,
|
|
31255
|
+
vercelSyncDeadlineMs: opts.vercelSyncDeadlineMs,
|
|
31211
31256
|
onTrafficSynced: opts.onTrafficSynced,
|
|
31212
31257
|
onScheduleUpdated: opts.onScheduleUpdated,
|
|
31213
31258
|
allowLoopbackWebhooks: opts.allowLoopbackWebhooks
|
package/dist/cli.js
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
setTelemetrySource,
|
|
28
28
|
showFirstRunNotice,
|
|
29
29
|
trackEvent
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-CWEV3YMZ.js";
|
|
31
31
|
import {
|
|
32
32
|
CliError,
|
|
33
33
|
EXIT_SYSTEM_ERROR,
|
|
@@ -52,7 +52,7 @@ import {
|
|
|
52
52
|
projects,
|
|
53
53
|
queries,
|
|
54
54
|
renderReportHtml
|
|
55
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-ETJDAMGA.js";
|
|
56
56
|
import {
|
|
57
57
|
CcReleaseSyncStatuses,
|
|
58
58
|
CheckScopes,
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CWEV3YMZ.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
6
|
} from "./chunk-ZNWMVYYU.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-ETJDAMGA.js";
|
|
8
8
|
import "./chunk-5FM7QRYD.js";
|
|
9
9
|
export {
|
|
10
10
|
createServer,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainyc/canonry",
|
|
3
|
-
"version": "4.71.
|
|
3
|
+
"version": "4.71.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
|
|
6
6
|
"license": "FSL-1.1-ALv2",
|
|
@@ -66,22 +66,22 @@
|
|
|
66
66
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
67
67
|
"@ainyc/canonry-config": "0.0.0",
|
|
68
68
|
"@ainyc/canonry-contracts": "0.0.0",
|
|
69
|
-
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
70
69
|
"@ainyc/canonry-db": "0.0.0",
|
|
71
70
|
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
71
|
+
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
72
|
+
"@ainyc/canonry-integration-google": "0.0.0",
|
|
73
|
+
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
72
74
|
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
73
75
|
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
74
76
|
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
75
|
-
"@ainyc/canonry-integration-google": "0.0.0",
|
|
76
|
-
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
77
77
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
78
78
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
79
79
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
80
|
-
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
81
80
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
82
81
|
"@ainyc/canonry-provider-local": "0.0.0",
|
|
82
|
+
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
83
83
|
"@ainyc/canonry-provider-perplexity": "0.0.0",
|
|
84
|
-
"@ainyc/canonry-provider-
|
|
84
|
+
"@ainyc/canonry-provider-claude": "0.0.0"
|
|
85
85
|
},
|
|
86
86
|
"scripts": {
|
|
87
87
|
"build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",
|