@detiq/crawler 1.1.21 → 1.1.22
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/Dockerfile +5 -0
- package/dist/crawler.js +20 -7
- package/dist/crawler.js.map +2 -2
- package/dist/job-queue.js +7 -1
- package/dist/job-queue.js.map +2 -2
- package/package.json +1 -1
- package/src/crawler.ts +27 -6
- package/src/job-queue.ts +98 -86
- package/types/job-queue.d.ts +3 -1
package/Dockerfile
CHANGED
|
@@ -36,6 +36,11 @@ COPY packages/vscode-extension/package.json packages/vscode-extension/
|
|
|
36
36
|
COPY packages/web/package.json packages/web/
|
|
37
37
|
RUN npm ci --include=dev
|
|
38
38
|
|
|
39
|
+
# Patch Stagehand's act() schema to add `additionalProperties: false` on the
|
|
40
|
+
# inner anyOf[0] object. OpenAI strict mode (v1/responses) requires it on every
|
|
41
|
+
# nested object; Stagehand ≤3.6 omits it, causing a 400 "invalid_json_schema".
|
|
42
|
+
RUN node -e "const fs=require('fs');['packages/crawler/node_modules/@browserbasehq/stagehand/dist/cjs/lib/inference.js','packages/crawler/node_modules/@browserbasehq/stagehand/dist/esm/lib/inference.js'].forEach(f=>{if(!fs.existsSync(f)){console.log('skip',f);return;}let c=fs.readFileSync(f,'utf8');if(c.includes('.strict()')){console.log('already patched',f);return;}c=c.replace(/\\.nullable\\(\\)\\n(\\s+)\\.describe\\(\"The element to act on/g,'\.strict()\n\$1.nullable()\n\$1.describe(\"The element to act on');fs.writeFileSync(f,c);console.log('patched',f);});"
|
|
43
|
+
|
|
39
44
|
# Re-install chromium after npm ci so the browser revision matches the
|
|
40
45
|
# exact playwright version resolved by the lockfile (not the base image's
|
|
41
46
|
# bundled version, which may differ if the lockfile was updated).
|
package/dist/crawler.js
CHANGED
|
@@ -73,7 +73,7 @@ const _crawlLLMCache = /* @__PURE__ */ new Map();
|
|
|
73
73
|
async function getCachedCrawlLLM(tenantId) {
|
|
74
74
|
if (_crawlLLMCache.has(tenantId)) return _crawlLLMCache.get(tenantId);
|
|
75
75
|
const cfg = await getTaskAgentLLMConfig(tenantId, "crawl").catch(() => null);
|
|
76
|
-
_crawlLLMCache.set(tenantId, cfg);
|
|
76
|
+
if (cfg) _crawlLLMCache.set(tenantId, cfg);
|
|
77
77
|
return cfg;
|
|
78
78
|
}
|
|
79
79
|
function getGitInfo() {
|
|
@@ -88,7 +88,7 @@ function getGitInfo() {
|
|
|
88
88
|
const ALLOWED_NUMERIC_PATHS = /* @__PURE__ */ new Set(["/2fa", "/404", "/500", "/403", "/401"]);
|
|
89
89
|
const UUID_PATH_SEGMENT_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
90
90
|
const CUID_PATH_SEGMENT_RE = /^c[a-z0-9]{20,}$/i;
|
|
91
|
-
const NUMERIC_ID_PATH_SEGMENT_RE = /^\d
|
|
91
|
+
const NUMERIC_ID_PATH_SEGMENT_RE = /^\d{4,}$/;
|
|
92
92
|
const COMPOUND_NUMERIC_ID_PATH_SEGMENT_RE = /^\d+-\d+$/;
|
|
93
93
|
function normalizePathForNumericGuard(pathname) {
|
|
94
94
|
const normalized = pathname.replace(/\/+$/, "") || "/";
|
|
@@ -1598,6 +1598,7 @@ async function crawlProject(opts, onProgress) {
|
|
|
1598
1598
|
};
|
|
1599
1599
|
const edges = [];
|
|
1600
1600
|
const pendingTransitions = [];
|
|
1601
|
+
const pendingSummaryWrites = [];
|
|
1601
1602
|
const discovered = [];
|
|
1602
1603
|
const performanceMetrics = [];
|
|
1603
1604
|
const seenDomHashes = new Set(opts.knownDomHashes ?? []);
|
|
@@ -2932,6 +2933,7 @@ async function crawlProject(opts, onProgress) {
|
|
|
2932
2933
|
const summaryPromise = (async () => {
|
|
2933
2934
|
try {
|
|
2934
2935
|
const llmCfg = await getCachedCrawlLLM(opts.tenantId);
|
|
2936
|
+
if (!llmCfg) return void 0;
|
|
2935
2937
|
const snippet = extracted.markdown.slice(0, 1200);
|
|
2936
2938
|
if (snippet.trim().length < 80) return void 0;
|
|
2937
2939
|
const summarySeed = deterministicSeed(`${opts.tenantId}:${opts.projectId ?? ""}:page-summary:${url}`);
|
|
@@ -2972,10 +2974,15 @@ ${snippet}`,
|
|
|
2972
2974
|
markdown: fitMarkdown ?? extracted.markdown,
|
|
2973
2975
|
heading: extracted.title || name
|
|
2974
2976
|
}).catch((err) => console.warn("[crawler] markdown extraction save failed:", err));
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2977
|
+
pendingSummaryWrites.push(
|
|
2978
|
+
summaryPromise.then((aiSummary) => {
|
|
2979
|
+
if (aiSummary) AppBrain.updateScreenAiSummary(opts.tenantId, screen.id, aiSummary).catch((e) => {
|
|
2980
|
+
logger.warn({ screenId: screen.id, err: String(e?.message ?? e) }, "[crawler] aiSummary DB save failed");
|
|
2981
|
+
});
|
|
2982
|
+
}).catch((e) => {
|
|
2983
|
+
logger.warn({ screenId: screen.id, err: String(e?.message ?? e) }, "[crawler] aiSummary generation failed");
|
|
2984
|
+
})
|
|
2985
|
+
);
|
|
2979
2986
|
}
|
|
2980
2987
|
const structuredJson = summarizeStructuredElements(atElements);
|
|
2981
2988
|
const artifact = buildCrawlArtifactEnvelope({
|
|
@@ -3413,7 +3420,7 @@ ${snippet}`,
|
|
|
3413
3420
|
if (liteWorkerPromises.length > 0) await Promise.all(liteWorkerPromises);
|
|
3414
3421
|
if (opts.discoveryMode) {
|
|
3415
3422
|
return {
|
|
3416
|
-
discoveredUrls: Array.from(visited.values()),
|
|
3423
|
+
discoveredUrls: Array.from(visited.values()).filter((v) => v.startsWith("http")),
|
|
3417
3424
|
screensFound: 0,
|
|
3418
3425
|
screensErrored: 0,
|
|
3419
3426
|
screensSkippedToNextSegment: 0,
|
|
@@ -4149,6 +4156,12 @@ ${snippet}`,
|
|
|
4149
4156
|
}
|
|
4150
4157
|
const screensSucceeded = discovered.filter((d) => !!d.screenId).length;
|
|
4151
4158
|
const screensErrored = discovered.filter((d) => !!d.error && !d.screenId).length;
|
|
4159
|
+
if (pendingSummaryWrites.length > 0) {
|
|
4160
|
+
await Promise.race([
|
|
4161
|
+
Promise.allSettled(pendingSummaryWrites),
|
|
4162
|
+
new Promise((resolve) => setTimeout(resolve, Math.min(6e4, pendingSummaryWrites.length * 3e3)))
|
|
4163
|
+
]);
|
|
4164
|
+
}
|
|
4152
4165
|
if (screensSucceeded >= 3) {
|
|
4153
4166
|
const screensWithElements = discovered.filter((d) => (d.elements ?? 0) > 0 && d.screenId).length;
|
|
4154
4167
|
if (screensWithElements === 0) {
|