@humain/terminal 0.1.0 → 0.2.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.
- package/CHANGELOG.md +33 -0
- package/dist/bundle/chunks/{anthropic-messages-XULXUBIG.js → anthropic-messages-QFCEKGI3.js} +1 -1
- package/dist/bundle/chunks/{azure-openai-responses-JEG2XOYC.js → azure-openai-responses-G4ZMHV37.js} +1 -1
- package/dist/bundle/chunks/chunk-7T6XCLJF.js +22 -0
- package/dist/bundle/chunks/chunk-D6HHRSB5.js +103 -0
- package/dist/bundle/chunks/chunk-EY4DWHQU.js +2 -0
- package/dist/bundle/chunks/{chunk-RM336IEI.js → chunk-I47ZWR55.js} +486 -509
- package/dist/bundle/chunks/{chunk-JUPSJTFQ.js → chunk-K4JAZYQH.js} +1 -1
- package/dist/bundle/chunks/{chunk-HPPQHK3J.js → chunk-KKIB2TVR.js} +1 -1
- package/dist/bundle/chunks/chunk-LI2YVPWP.js +2 -0
- package/dist/bundle/chunks/{chunk-BZQ53VGE.js → chunk-XSR434CO.js} +1 -1
- package/dist/bundle/chunks/compat-QCV26HNS.js +2 -0
- package/dist/bundle/chunks/dist-PRPIUY3U.js +2 -0
- package/dist/bundle/chunks/esm-E7UVEYTO.js +4 -0
- package/dist/bundle/chunks/{extract-TRW5FBY6.js → extract-CTIFQZDJ.js} +15 -14
- package/dist/bundle/chunks/{google-generative-ai-OX6VSCA6.js → google-generative-ai-RSUU4MWO.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-GW76GSS2.js → google-vertex-CKQPOITO.js} +1 -1
- package/dist/bundle/chunks/host-WP3MVKS2.js +2 -0
- package/dist/bundle/chunks/{node-KOIP55YZ.js → node-NF43OPII.js} +1 -1
- package/dist/bundle/chunks/{node-XY3CBY3C.js → node-UMFM7CDZ.js} +1 -1
- package/dist/bundle/chunks/{openai-codex-responses-NPLWP6ZC.js → openai-codex-responses-S34V5ZSD.js} +1 -1
- package/dist/bundle/chunks/{openai-completions-OT2GTJKC.js → openai-completions-T2IGVUEI.js} +1 -1
- package/dist/bundle/chunks/{openai-responses-5A6CR7GI.js → openai-responses-GYZODCT3.js} +1 -1
- package/dist/bundle/chunks/readability-LAGF34IB.js +3 -0
- package/dist/bundle/chunks/turndown.cjs-HRMZVRUL.js +2 -0
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli.js +1 -5
- package/dist/core/agent-session.js +2 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +21 -8
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/subagent-env.d.ts +18 -0
- package/dist/core/tools/subagent-env.d.ts.map +1 -0
- package/dist/core/tools/subagent-env.js +43 -0
- package/dist/core/tools/subagent-env.js.map +1 -0
- package/dist/core/tools/subagent-scheduler.d.ts +31 -0
- package/dist/core/tools/subagent-scheduler.d.ts.map +1 -0
- package/dist/core/tools/subagent-scheduler.js +203 -0
- package/dist/core/tools/subagent-scheduler.js.map +1 -0
- package/dist/core/tools/subagent.d.ts +83 -3
- package/dist/core/tools/subagent.d.ts.map +1 -1
- package/dist/core/tools/subagent.js +214 -76
- package/dist/core/tools/subagent.js.map +1 -1
- package/dist/humain/index.d.ts.map +1 -1
- package/dist/humain/index.js +2 -0
- package/dist/humain/index.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/CHANGELOG.md +78 -0
- package/dist/humain/mcp-adapter/vendor/README.md +125 -19
- package/dist/humain/mcp-adapter/vendor/agent-plugin-loader.ts +69 -30
- package/dist/humain/mcp-adapter/vendor/agent-plugin-provenance.ts +36 -0
- package/dist/humain/mcp-adapter/vendor/claude-plugin-loader.ts +365 -0
- package/dist/humain/mcp-adapter/vendor/commands.ts +13 -15
- package/dist/humain/mcp-adapter/vendor/config.ts +198 -30
- package/dist/humain/mcp-adapter/vendor/consent-manager.ts +40 -9
- package/dist/humain/mcp-adapter/vendor/direct-tool-surface.ts +250 -0
- package/dist/humain/mcp-adapter/vendor/direct-tools.ts +9 -228
- package/dist/humain/mcp-adapter/vendor/dist/agent-plugin-loader.js +74 -32
- package/dist/humain/mcp-adapter/vendor/dist/agent-plugin-loader.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/dist/agent-plugin-provenance.d.ts +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/agent-plugin-provenance.js +31 -0
- package/dist/humain/mcp-adapter/vendor/dist/agent-plugin-provenance.js.map +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/claude-plugin-loader.d.ts +9 -0
- package/dist/humain/mcp-adapter/vendor/dist/claude-plugin-loader.js +362 -0
- package/dist/humain/mcp-adapter/vendor/dist/claude-plugin-loader.js.map +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/config.d.ts +3 -1
- package/dist/humain/mcp-adapter/vendor/dist/config.js +189 -27
- package/dist/humain/mcp-adapter/vendor/dist/config.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/dist/metadata-cache.js +7 -16
- package/dist/humain/mcp-adapter/vendor/dist/metadata-cache.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/dist/package-mcp-loader.js +5 -17
- package/dist/humain/mcp-adapter/vendor/dist/package-mcp-loader.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/dist/types.d.ts +30 -4
- package/dist/humain/mcp-adapter/vendor/dist/types.js +26 -0
- package/dist/humain/mcp-adapter/vendor/dist/types.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/dist/utils.d.ts +6 -0
- package/dist/humain/mcp-adapter/vendor/dist/utils.js +65 -6
- package/dist/humain/mcp-adapter/vendor/dist/utils.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/host-html-template.ts +20 -19
- package/dist/humain/mcp-adapter/vendor/http-ca.ts +84 -0
- package/dist/humain/mcp-adapter/vendor/index.bundle.mjs +37102 -15103
- package/dist/humain/mcp-adapter/vendor/index.ts +828 -164
- package/dist/humain/mcp-adapter/vendor/init.ts +48 -10
- package/dist/humain/mcp-adapter/vendor/lazy-loader.ts +7 -0
- package/dist/humain/mcp-adapter/vendor/mcp-auth-fetch.ts +113 -0
- package/dist/humain/mcp-adapter/vendor/mcp-auth-flow.ts +256 -77
- package/dist/humain/mcp-adapter/vendor/mcp-auth.ts +316 -54
- package/dist/humain/mcp-adapter/vendor/mcp-code.ts +45 -18
- package/dist/humain/mcp-adapter/vendor/mcp-install.ts +60 -0
- package/dist/humain/mcp-adapter/vendor/mcp-oauth-provider.ts +70 -6
- package/dist/humain/mcp-adapter/vendor/mcp-output-guard.ts +53 -42
- package/dist/humain/mcp-adapter/vendor/mcp-panel-theme.ts +105 -0
- package/dist/humain/mcp-adapter/vendor/mcp-panel.ts +366 -331
- package/dist/humain/mcp-adapter/vendor/mcp-references.ts +9 -14
- package/dist/humain/mcp-adapter/vendor/mcp-script-worker.mjs +3 -1
- package/dist/humain/mcp-adapter/vendor/mcp-setup-panel.ts +383 -341
- package/dist/humain/mcp-adapter/vendor/mcp-status.ts +5 -0
- package/dist/humain/mcp-adapter/vendor/metadata-cache.ts +7 -16
- package/dist/humain/mcp-adapter/vendor/namespace-tools.ts +61 -3
- package/dist/humain/mcp-adapter/vendor/oauth.ts +6 -2
- package/dist/humain/mcp-adapter/vendor/package-mcp-loader.ts +5 -17
- package/dist/humain/mcp-adapter/vendor/package.json +13 -3
- package/dist/humain/mcp-adapter/vendor/prompts.ts +35 -3
- package/dist/humain/mcp-adapter/vendor/proxy-modes.ts +108 -7
- package/dist/humain/mcp-adapter/vendor/runtime-owner.ts +16 -1
- package/dist/humain/mcp-adapter/vendor/sampling-handler.ts +9 -32
- package/dist/humain/mcp-adapter/vendor/sandbox-proxy-template.ts +20 -93
- package/dist/humain/mcp-adapter/vendor/server-manager.ts +227 -40
- package/dist/humain/mcp-adapter/vendor/session-approvals.ts +187 -0
- package/dist/humain/mcp-adapter/vendor/skills/mcp-scripting/SKILL.md +9 -1
- package/dist/humain/mcp-adapter/vendor/state.ts +10 -1
- package/dist/humain/mcp-adapter/vendor/tool-approval.ts +10 -22
- package/dist/humain/mcp-adapter/vendor/tool-metadata.ts +14 -0
- package/dist/humain/mcp-adapter/vendor/types.ts +57 -4
- package/dist/humain/mcp-adapter/vendor/ui-server.ts +36 -28
- package/dist/humain/mcp-adapter/vendor/utils.ts +64 -6
- package/dist/humain/node-http.d.ts +3 -0
- package/dist/humain/node-http.d.ts.map +1 -0
- package/dist/humain/node-http.js +119 -0
- package/dist/humain/node-http.js.map +1 -0
- package/dist/humain/node-provider.d.ts +4 -0
- package/dist/humain/node-provider.d.ts.map +1 -0
- package/dist/humain/node-provider.js +359 -0
- package/dist/humain/node-provider.js.map +1 -0
- package/dist/humain/web-access/vendor/abortable.d.ts +3 -0
- package/dist/humain/web-access/vendor/abortable.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/abortable.js +22 -0
- package/dist/humain/web-access/vendor/abortable.js.map +1 -0
- package/dist/humain/web-access/vendor/crawl4ai.d.ts +9 -0
- package/dist/humain/web-access/vendor/crawl4ai.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/crawl4ai.js +187 -0
- package/dist/humain/web-access/vendor/crawl4ai.js.map +1 -0
- package/dist/humain/web-access/vendor/credential-source.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/credential-source.js +1 -0
- package/dist/humain/web-access/vendor/credential-source.js.map +1 -1
- package/dist/humain/web-access/vendor/curator-page.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/curator-page.js +20 -2
- package/dist/humain/web-access/vendor/curator-page.js.map +1 -1
- package/dist/humain/web-access/vendor/curator-run.d.ts +11 -0
- package/dist/humain/web-access/vendor/curator-run.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/curator-run.js +38 -0
- package/dist/humain/web-access/vendor/curator-run.js.map +1 -0
- package/dist/humain/web-access/vendor/curator-server.d.ts +1 -0
- package/dist/humain/web-access/vendor/curator-server.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/curator-server.js +2 -0
- package/dist/humain/web-access/vendor/curator-server.js.map +1 -1
- package/dist/humain/web-access/vendor/duckduckgo.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/duckduckgo.js +1 -1
- package/dist/humain/web-access/vendor/duckduckgo.js.map +1 -1
- package/dist/humain/web-access/vendor/extract.d.ts +1 -1
- package/dist/humain/web-access/vendor/extract.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/extract.js +58 -11
- package/dist/humain/web-access/vendor/extract.js.map +1 -1
- package/dist/humain/web-access/vendor/fetch-params.js +1 -1
- package/dist/humain/web-access/vendor/fetch-params.js.map +1 -1
- package/dist/humain/web-access/vendor/gemini-search.d.ts +2 -2
- package/dist/humain/web-access/vendor/gemini-search.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/gemini-search.js +12 -5
- package/dist/humain/web-access/vendor/gemini-search.js.map +1 -1
- package/dist/humain/web-access/vendor/index.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/index.js +23 -19
- package/dist/humain/web-access/vendor/index.js.map +1 -1
- package/dist/humain/web-access/vendor/openai-search.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/openai-search.js +40 -14
- package/dist/humain/web-access/vendor/openai-search.js.map +1 -1
- package/dist/humain/web-access/vendor/page-query.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/page-query.js +6 -2
- package/dist/humain/web-access/vendor/page-query.js.map +1 -1
- package/dist/humain/web-access/vendor/query-rewrite.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/query-rewrite.js +6 -2
- package/dist/humain/web-access/vendor/query-rewrite.js.map +1 -1
- package/dist/humain/web-access/vendor/serpapi.d.ts +4 -0
- package/dist/humain/web-access/vendor/serpapi.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/serpapi.js +215 -0
- package/dist/humain/web-access/vendor/serpapi.js.map +1 -0
- package/dist/humain/web-access/vendor/ssrf-protection.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/ssrf-protection.js +5 -1
- package/dist/humain/web-access/vendor/ssrf-protection.js.map +1 -1
- package/dist/humain/web-access/vendor/storage.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/storage.js +9 -0
- package/dist/humain/web-access/vendor/storage.js.map +1 -1
- package/dist/humain/web-access/vendor/summary-review.d.ts +1 -1
- package/dist/humain/web-access/vendor/summary-review.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/summary-review.js +35 -24
- package/dist/humain/web-access/vendor/summary-review.js.map +1 -1
- package/dist/humain/web-access/vendor/utils.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/utils.js +5 -3
- package/dist/humain/web-access/vendor/utils.js.map +1 -1
- package/dist/index.js +1 -51
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +16 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +7 -2
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +46 -21
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +10 -13
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/json-event.d.ts +8 -0
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +17 -0
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +3 -2
- package/dist/modes/print-mode.js.map +1 -1
- package/docs/environment-variables.md +8 -0
- package/docs/humain-terminal.md +6 -0
- package/docs/json.md +16 -0
- package/docs/providers.md +19 -1
- package/npm-shrinkwrap.json +6 -6
- package/package.json +2 -2
- package/src/humain/mcp-adapter/UPSTREAM.md +56 -7
- package/src/humain/mcp-adapter/upstream.json +6 -4
- package/src/humain/mcp-adapter/vendor/CHANGELOG.md +78 -0
- package/src/humain/web-access/UPSTREAM.md +18 -8
- package/src/humain/web-access/upstream.json +6 -5
- package/dist/bundle/chunks/chunk-2LC3S3VV.js +0 -105
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import { Readability } from "@mozilla/readability";
|
|
3
|
-
import { resizeImage } from "../host.js";
|
|
4
|
-
import { parseHTML } from "linkedom";
|
|
5
|
-
import TurndownService from "turndown";
|
|
6
2
|
import pLimit from "p-limit";
|
|
7
3
|
import { activityMonitor } from "./activity.js";
|
|
8
4
|
import { extractRSCContent } from "./rsc-extract.js";
|
|
@@ -20,6 +16,7 @@ import { extractWithQuerit, isQueritAvailable } from "./querit.js";
|
|
|
20
16
|
import { extractWithKagi, isKagiExtractAvailable } from "./kagi.js";
|
|
21
17
|
import { extractWithOllama, isOllamaFetchAvailable } from "./ollama.js";
|
|
22
18
|
import { extractWithFirecrawl, isFirecrawlAvailable } from "./firecrawl.js";
|
|
19
|
+
import { extractWithCrawl4ai, isCrawl4aiAvailable } from "./crawl4ai.js";
|
|
23
20
|
import { extractWithBrightDataUnlocker, isBrightDataUnlockerAvailable } from "./brightdata-unlocker.js";
|
|
24
21
|
import { isVideoFile, extractVideo, extractVideoFrame, getLocalVideoDuration } from "./video-extract.js";
|
|
25
22
|
import { appendDeclaredWebLinks, discoverDeclaredWebLinks } from "./declared-web-links.js";
|
|
@@ -68,8 +65,8 @@ function loadFetchTimeoutMs() {
|
|
|
68
65
|
const NON_RECOVERABLE_ERRORS = ["Unsupported content type", "Response too large", "PDF extraction is disabled", "Image fetching is disabled"];
|
|
69
66
|
const MIN_USEFUL_CONTENT = 500;
|
|
70
67
|
const SUPPORTED_IMAGE_TYPES = new Set(["image/png", "image/jpeg", "image/webp", "image/gif"]);
|
|
71
|
-
const FETCH_PROVIDERS = ["http", "firecrawl", "jina", "tinyfish", "search1api", "querit", "kagi", "ollama", "parallel", "parallel-mcp", "brightdata", "gemini"];
|
|
72
|
-
const DEFAULT_FETCH_PROVIDER_ORDER = ["http", "firecrawl", "jina", "tinyfish", "search1api", "querit", "kagi", "ollama", "parallel", "brightdata", "gemini"];
|
|
68
|
+
const FETCH_PROVIDERS = ["http", "firecrawl", "crawl4ai", "jina", "tinyfish", "search1api", "querit", "kagi", "ollama", "parallel", "parallel-mcp", "brightdata", "gemini"];
|
|
69
|
+
const DEFAULT_FETCH_PROVIDER_ORDER = ["http", "firecrawl", "crawl4ai", "jina", "tinyfish", "search1api", "querit", "kagi", "ollama", "parallel", "brightdata", "gemini"];
|
|
73
70
|
const REMOTE_HOSTED_FETCH_PROVIDERS = new Set(["jina", "tinyfish", "search1api", "querit", "kagi", "ollama", "parallel", "parallel-mcp", "brightdata", "gemini"]);
|
|
74
71
|
function isDefuddleConsoleError(args) {
|
|
75
72
|
const prefix = args[0];
|
|
@@ -77,6 +74,7 @@ function isDefuddleConsoleError(args) {
|
|
|
77
74
|
}
|
|
78
75
|
async function extractWithDefuddle(text, url) {
|
|
79
76
|
const { Defuddle } = await import("defuddle/node");
|
|
77
|
+
const { parseHTML } = await import("linkedom");
|
|
80
78
|
const { document } = parseHTML(text);
|
|
81
79
|
Object.defineProperty(document, "location", {
|
|
82
80
|
value: new URL(url),
|
|
@@ -122,6 +120,9 @@ function isConfigParseError(err) {
|
|
|
122
120
|
function isAbortError(err) {
|
|
123
121
|
return errorMessage(err).toLowerCase().includes("abort");
|
|
124
122
|
}
|
|
123
|
+
function isAbortException(err) {
|
|
124
|
+
return err instanceof DOMException && (err.name === "AbortError" || err.name === "TimeoutError");
|
|
125
|
+
}
|
|
125
126
|
function isRedirectPolicyError(message) {
|
|
126
127
|
return message.startsWith("Authenticated fetch refused cross-origin redirect") ||
|
|
127
128
|
message.startsWith("Blocked internal ") ||
|
|
@@ -257,10 +258,19 @@ function notFoundGuidance(result, toolNames) {
|
|
|
257
258
|
function abortedResult(url) {
|
|
258
259
|
return { url, title: "", content: "", error: "Aborted" };
|
|
259
260
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
});
|
|
261
|
+
// Share first-use initialization without loading Turndown at extension startup.
|
|
262
|
+
let turndownInstance;
|
|
263
|
+
async function loadTurndown() {
|
|
264
|
+
const { default: TurndownService } = await import("turndown");
|
|
265
|
+
return new TurndownService({
|
|
266
|
+
headingStyle: "atx",
|
|
267
|
+
codeBlockStyle: "fenced",
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
function getTurndown() {
|
|
271
|
+
turndownInstance ??= loadTurndown();
|
|
272
|
+
return turndownInstance;
|
|
273
|
+
}
|
|
264
274
|
const fetchLimit = pLimit(CONCURRENT_LIMIT);
|
|
265
275
|
/** Resolve the direct HTTP/Jina fetch budget, with a per-call override taking precedence. */
|
|
266
276
|
export function resolveFetchTimeoutMs(options) {
|
|
@@ -689,6 +699,7 @@ export async function extractContent(url, signal, options) {
|
|
|
689
699
|
return null;
|
|
690
700
|
};
|
|
691
701
|
let firecrawlError = null;
|
|
702
|
+
let crawl4aiError = null;
|
|
692
703
|
let tinyfishError = null;
|
|
693
704
|
let search1apiError = null;
|
|
694
705
|
let queritError = null;
|
|
@@ -733,6 +744,28 @@ export async function extractContent(url, signal, options) {
|
|
|
733
744
|
}
|
|
734
745
|
continue;
|
|
735
746
|
}
|
|
747
|
+
if (provider === "crawl4ai") {
|
|
748
|
+
try {
|
|
749
|
+
if (isCrawl4aiAvailable()) {
|
|
750
|
+
const ssrf = loadSsrfConfig();
|
|
751
|
+
const crawl4aiResult = await extractWithCrawl4ai(url, signal, {
|
|
752
|
+
timeoutMs: options?.timeoutMs,
|
|
753
|
+
...(options?.lookup ? { lookup: options.lookup } : {}),
|
|
754
|
+
ssrf,
|
|
755
|
+
});
|
|
756
|
+
if (crawl4aiResult)
|
|
757
|
+
return withDeclaredLinks(crawl4aiResult);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
catch (err) {
|
|
761
|
+
if (signal?.aborted || isAbortException(err))
|
|
762
|
+
return abortedResult(url);
|
|
763
|
+
crawl4aiError = errorMessage(err);
|
|
764
|
+
if (isConfigParseError(err))
|
|
765
|
+
return parseErrorResult(crawl4aiError);
|
|
766
|
+
}
|
|
767
|
+
continue;
|
|
768
|
+
}
|
|
736
769
|
if (provider === "jina") {
|
|
737
770
|
const jinaResult = await extractWithJinaReader(url, fetchTimeoutMs, signal, options?.lookup);
|
|
738
771
|
if (jinaResult)
|
|
@@ -920,6 +953,7 @@ export async function extractContent(url, signal, options) {
|
|
|
920
953
|
const guidance = [
|
|
921
954
|
finalHttpResult?.error ?? "No fetch_content provider returned content",
|
|
922
955
|
...(firecrawlError ? [`Firecrawl fallback failed: ${firecrawlError}`] : []),
|
|
956
|
+
...(crawl4aiError ? [`Crawl4AI fallback failed: ${crawl4aiError}`] : []),
|
|
923
957
|
...(tinyfishError ? [`TinyFish fallback failed: ${tinyfishError}`] : []),
|
|
924
958
|
...(search1apiError ? [`Search1API fallback failed: ${search1apiError}`] : []),
|
|
925
959
|
...(queritError ? [`Querit fallback failed: ${queritError}`] : []),
|
|
@@ -931,6 +965,7 @@ export async function extractContent(url, signal, options) {
|
|
|
931
965
|
"",
|
|
932
966
|
"Fallback options:",
|
|
933
967
|
` • Set firecrawlBaseUrl in ${WEB_SEARCH_CONFIG_PATH} to a self-hosted Firecrawl instance`,
|
|
968
|
+
` • Set crawl4aiBaseUrl in ${WEB_SEARCH_CONFIG_PATH} to a self-hosted Crawl4AI instance`,
|
|
934
969
|
` • Set tinyfishApiKey in ${WEB_SEARCH_CONFIG_PATH} or TINYFISH_API_KEY`,
|
|
935
970
|
` • Set search1apiApiKey in ${WEB_SEARCH_CONFIG_PATH} or SEARCH1API_KEY`,
|
|
936
971
|
` • Set queritApiKey in ${WEB_SEARCH_CONFIG_PATH} or QUERIT_API_KEY`,
|
|
@@ -1029,6 +1064,7 @@ function responseSizeLimitError(maxBytes) {
|
|
|
1029
1064
|
async function extractViaHttp(url, timeoutMs, signal, options) {
|
|
1030
1065
|
const activityId = activityMonitor.logStart({ type: "fetch", url });
|
|
1031
1066
|
const controller = new AbortController();
|
|
1067
|
+
const startedAt = Date.now();
|
|
1032
1068
|
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
1033
1069
|
const onAbort = () => controller.abort();
|
|
1034
1070
|
signal?.addEventListener("abort", onAbort);
|
|
@@ -1111,6 +1147,7 @@ async function extractViaHttp(url, timeoutMs, signal, options) {
|
|
|
1111
1147
|
}
|
|
1112
1148
|
try {
|
|
1113
1149
|
const buffer = await readResponseBufferWithLimit(response, maxResponseSize, () => responseSizeLimitError(maxResponseSize));
|
|
1150
|
+
const { resizeImage } = await import("../host.js");
|
|
1114
1151
|
const resized = await resizeImage(new Uint8Array(buffer), mimeType, { maxWidth: 2000, maxHeight: 2000 });
|
|
1115
1152
|
activityMonitor.logComplete(activityId, response.status);
|
|
1116
1153
|
if (!resized)
|
|
@@ -1178,9 +1215,11 @@ async function extractViaHttp(url, timeoutMs, signal, options) {
|
|
|
1178
1215
|
const title = extractTextTitle(text, url);
|
|
1179
1216
|
return { url, title, content: text, error: null };
|
|
1180
1217
|
}
|
|
1218
|
+
const { parseHTML } = await import("linkedom");
|
|
1181
1219
|
const { document } = parseHTML(text);
|
|
1182
1220
|
const documentTitle = document.title?.trim() ?? "";
|
|
1183
1221
|
const declaredLinks = discoverDeclaredWebLinks(document, response.headers.get("link"), response.url || url);
|
|
1222
|
+
const { Readability } = await import("@mozilla/readability");
|
|
1184
1223
|
const reader = new Readability(document);
|
|
1185
1224
|
const article = reader.parse();
|
|
1186
1225
|
if (!article) {
|
|
@@ -1224,7 +1263,7 @@ async function extractViaHttp(url, timeoutMs, signal, options) {
|
|
|
1224
1263
|
if (typeof article.content !== "string") {
|
|
1225
1264
|
throw new Error("Readability returned invalid article content");
|
|
1226
1265
|
}
|
|
1227
|
-
const markdown =
|
|
1266
|
+
const markdown = (await getTurndown()).turndown(article.content);
|
|
1228
1267
|
activityMonitor.logComplete(activityId, response.status);
|
|
1229
1268
|
if (markdown.length < MIN_USEFUL_CONTENT) {
|
|
1230
1269
|
const rscResult = extractRSCContent(text);
|
|
@@ -1280,6 +1319,14 @@ async function extractViaHttp(url, timeoutMs, signal, options) {
|
|
|
1280
1319
|
finally {
|
|
1281
1320
|
clearTimeout(timeoutId);
|
|
1282
1321
|
signal?.removeEventListener("abort", onAbort);
|
|
1322
|
+
// Imports and CPU-bound processing need not observe the fetch signal, and
|
|
1323
|
+
// can finish before an expired timer gets a turn. Guard every exit, with
|
|
1324
|
+
// caller cancellation taking precedence over the internal deadline.
|
|
1325
|
+
if (signal?.aborted)
|
|
1326
|
+
return abortedResult(url);
|
|
1327
|
+
if (controller.signal.aborted || Date.now() - startedAt >= timeoutMs) {
|
|
1328
|
+
return { url, title: "", content: "", error: "The operation was aborted." };
|
|
1329
|
+
}
|
|
1283
1330
|
}
|
|
1284
1331
|
}
|
|
1285
1332
|
export function extractHeadingTitle(text) {
|