@autorag/librarian 2.5.1 → 2.5.2
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/NOTICE +3 -0
- package/README.md +229 -490
- package/dist/agent/agent.d.ts +44 -2
- package/dist/agent/index.d.ts +1 -0
- package/dist/agent/search-datasource-tool.d.ts +1 -0
- package/dist/agent/search-single-datasource-tool.d.ts +57 -0
- package/dist/agent/web-fetch-tool.d.ts +32 -0
- package/dist/agent/web-search-tool.d.ts +48 -0
- package/dist/cli/commands/lite-retrieve.d.ts +15 -0
- package/dist/cli/commands/search.d.ts +6 -0
- package/dist/cli/config.d.ts +20 -0
- package/dist/cli/index.js +6478 -372
- package/dist/core.d.ts +3 -1
- package/dist/core.js +6499 -409
- package/dist/datasource/connector-skill.d.ts +6 -0
- package/dist/datasource/crawler-skill.d.ts +2 -0
- package/dist/datasource/errors.d.ts +26 -0
- package/dist/datasource/skills/slack/index.d.ts +8 -0
- package/dist/datasource/tool-naming.d.ts +11 -0
- package/dist/index.js +6508 -419
- package/dist/minsync/types.d.ts +7 -0
- package/dist/retrieval/engine.d.ts +14 -5
- package/dist/retrieval/index.d.ts +2 -1
- package/dist/retrieval/merger.d.ts +30 -5
- package/dist/retrieval/skip.d.ts +41 -0
- package/dist/retrieval/types.d.ts +23 -2
- package/dist/web/entities.d.ts +10 -0
- package/dist/web/fetch/convert.d.ts +35 -0
- package/dist/web/fetch/feeds.d.ts +37 -0
- package/dist/web/fetch/html-renderer.d.ts +54 -0
- package/dist/web/fetch/index.d.ts +12 -0
- package/dist/web/fetch/negotiate.d.ts +27 -0
- package/dist/web/fetch/page-loader.d.ts +60 -0
- package/dist/web/fetch/render.d.ts +23 -0
- package/dist/web/fetch/turndown/gfm.d.ts +11 -0
- package/dist/web/fetch/turndown/html.d.ts +5 -0
- package/dist/web/fetch/turndown/index.d.ts +10 -0
- package/dist/web/fetch/turndown/service.d.ts +21 -0
- package/dist/web/fetch/turndown/types.d.ts +73 -0
- package/dist/web/fetch/url-target.d.ts +29 -0
- package/dist/web/search/browser-headers.d.ts +17 -0
- package/dist/web/search/browser-loader.d.ts +56 -0
- package/dist/web/search/browser-page.d.ts +41 -0
- package/dist/web/search/credentials.d.ts +10 -0
- package/dist/web/search/format.d.ts +30 -0
- package/dist/web/search/index.d.ts +46 -0
- package/dist/web/search/model-auth.d.ts +36 -0
- package/dist/web/search/provider.d.ts +62 -0
- package/dist/web/search/providers/anthropic.d.ts +9 -0
- package/dist/web/search/providers/base.d.ts +106 -0
- package/dist/web/search/providers/codex.d.ts +9 -0
- package/dist/web/search/providers/duckduckgo.d.ts +22 -0
- package/dist/web/search/providers/ecosia.d.ts +29 -0
- package/dist/web/search/providers/gemini.d.ts +9 -0
- package/dist/web/search/providers/google.d.ts +22 -0
- package/dist/web/search/providers/mojeek.d.ts +24 -0
- package/dist/web/search/providers/parallel.d.ts +10 -0
- package/dist/web/search/providers/perplexity.d.ts +10 -0
- package/dist/web/search/providers/public.d.ts +15 -0
- package/dist/web/search/providers/responses-api.d.ts +26 -0
- package/dist/web/search/providers/searxng.d.ts +19 -0
- package/dist/web/search/providers/startpage.d.ts +25 -0
- package/dist/web/search/providers/utils.d.ts +39 -0
- package/dist/web/search/providers/xai.d.ts +9 -0
- package/dist/web/search/query.d.ts +193 -0
- package/dist/web/search/types.d.ts +198 -0
- package/dist/web/search/utils.d.ts +8 -0
- package/package.json +2 -1
- package/skills/autorag/SKILL.md +2 -1
- package/skills/autorag-doctor/SKILL.md +237 -0
- package/skills/autorag-lite-search/SKILL.md +29 -7
- package/skills/autorag-lite-setup/SKILL.md +20 -13
- package/skills/autorag-setup/SKILL.md +32 -14
package/dist/minsync/types.d.ts
CHANGED
|
@@ -50,4 +50,11 @@ export interface MinSyncQueryHit {
|
|
|
50
50
|
readonly path: string;
|
|
51
51
|
readonly score: number;
|
|
52
52
|
readonly text: string;
|
|
53
|
+
/**
|
|
54
|
+
* MinSync's per-chunk identity (`doc_id` in its JSON). Several chunks of one
|
|
55
|
+
* parsed mirror share a `path`, so this is what distinguishes them; without
|
|
56
|
+
* it every passage of a document collapses into a single evidence id.
|
|
57
|
+
* Optional because older MinSync builds omit it.
|
|
58
|
+
*/
|
|
59
|
+
readonly docId?: string;
|
|
53
60
|
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { DatasourceAccessContext, type DatasourceAccessContextOptions } from "../datasource/access-context.js";
|
|
17
17
|
import { RetrievalMethodRegistry } from "./registry.js";
|
|
18
|
-
import type { RetrievalDiagnostic, RetrievalMethod, RetrievalOptions, RetrievalResult } from "./types.js";
|
|
18
|
+
import type { RetrievalDiagnostic, RetrievalMethod, RetrievalOptions, RetrievalResult, RetrievalUnsearchedSurface } from "./types.js";
|
|
19
19
|
/** Options for constructing a standalone {@link RetrievalEngine}. */
|
|
20
20
|
export interface RetrievalEngineOptions {
|
|
21
21
|
/**
|
|
@@ -23,7 +23,12 @@ export interface RetrievalEngineOptions {
|
|
|
23
23
|
* @default { allowedTags: undefined, allowedScopes: undefined }
|
|
24
24
|
*/
|
|
25
25
|
readonly datasourceAccess?: DatasourceAccessContextOptions;
|
|
26
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Default `topK` when the caller omits it. This is a safety ceiling on
|
|
28
|
+
* merged evidence, not a relevance cut: the merger returns every distinct
|
|
29
|
+
* chunk, so the effective size is whatever the registered methods returned.
|
|
30
|
+
* @default 500
|
|
31
|
+
*/
|
|
27
32
|
readonly defaultTopK?: number;
|
|
28
33
|
/** Default deduplication flag. @default true */
|
|
29
34
|
readonly defaultDedup?: boolean;
|
|
@@ -44,7 +49,7 @@ export interface RetrievalEngineOptions {
|
|
|
44
49
|
* methods = registry.list()
|
|
45
50
|
* byMethod = retriever.retrieveWithDiagnostics(methods, query, options)
|
|
46
51
|
* filtered = filter.filter(byMethod, methods, ctx, options.scope)
|
|
47
|
-
* merged = merger.merge(filtered, { topK, dedup: true })
|
|
52
|
+
* merged = merger.merge(filtered, { topK, dedup: true }) // distinct chunks, pure duplicates dropped
|
|
48
53
|
* → { results: merged, diagnostics }
|
|
49
54
|
* ```
|
|
50
55
|
*
|
|
@@ -93,6 +98,7 @@ export declare class RetrievalEngine {
|
|
|
93
98
|
retrieve(query: string, options?: RetrievalOptions): Promise<{
|
|
94
99
|
results: RetrievalResult[];
|
|
95
100
|
diagnostics: RetrievalDiagnostic[];
|
|
101
|
+
unsearched: RetrievalUnsearchedSurface[];
|
|
96
102
|
}>;
|
|
97
103
|
/**
|
|
98
104
|
* Run retrieval and return results keyed per method (unmerged) with
|
|
@@ -102,6 +108,7 @@ export declare class RetrievalEngine {
|
|
|
102
108
|
retrieveByMethod(query: string, options?: RetrievalOptions): Promise<{
|
|
103
109
|
byMethod: Map<string, RetrievalResult[]>;
|
|
104
110
|
diagnostics: RetrievalDiagnostic[];
|
|
111
|
+
unsearched: RetrievalUnsearchedSurface[];
|
|
105
112
|
}>;
|
|
106
113
|
/**
|
|
107
114
|
* Post-check for MinSync binary-missing diagnostic.
|
|
@@ -111,9 +118,11 @@ export declare class RetrievalEngine {
|
|
|
111
118
|
* a diagnostic. This method checks whether the minsync binary is unavailable
|
|
112
119
|
* and emits a `minsync-unavailable` diagnostic when every minsync method's
|
|
113
120
|
* result set is empty, exactly matching the existing {@link AutoRAGAgent}
|
|
114
|
-
* behavior (see `agent.src/agent/agent.ts` `retrieveWithDiagnostics`).
|
|
121
|
+
* behavior (see `agent.src/agent/agent.ts` `retrieveWithDiagnostics`). The
|
|
122
|
+
* same check reports the MinSync surface as unsearched, so a caller reading
|
|
123
|
+
* only the skip report still learns that local sources were not queried.
|
|
115
124
|
*/
|
|
116
|
-
private
|
|
125
|
+
private appendMinSyncUnavailable;
|
|
117
126
|
/**
|
|
118
127
|
* Build a datasource access context scoped to the caller's options.
|
|
119
128
|
* Model/tool arguments (allowedTags, allowedScopes) from options can only
|
|
@@ -3,4 +3,5 @@ export type { MergeOptions } from "./merger.js";
|
|
|
3
3
|
export { ParallelRetriever, ResultMerger } from "./merger.js";
|
|
4
4
|
export { RetrievalMethodRegistry } from "./registry.js";
|
|
5
5
|
export { matchesVirtualPathScope, normalizeVirtualPath, normalizeVirtualPathScope, virtualPathScopeToRegExp, } from "./scope.js";
|
|
6
|
-
export
|
|
6
|
+
export { describeRetrievalError, groupUnsearchedSurfaces, MINSYNC_SURFACE, type RetrievalSkip, retrievalSurfaceFor, } from "./skip.js";
|
|
7
|
+
export type { CuratedResult, NumberedResult, RetrievalDiagnostic, RetrievalDiagnosticCode, RetrievalMethod, RetrievalMethodDescriptor, RetrievalOptions, RetrievalResult, RetrievalUnsearchedSurface, RetrievalWithDiagnostics, } from "./types.js";
|
|
@@ -1,19 +1,44 @@
|
|
|
1
1
|
import type { RetrievalMethod, RetrievalOptions, RetrievalResult, RetrievalWithDiagnostics } from "./types.js";
|
|
2
2
|
export interface MergeOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Upper bound on returned evidence. This is a safety ceiling, not a
|
|
5
|
+
* relevance filter: the merger is expected to return every distinct chunk
|
|
6
|
+
* it was given. Callers that want the full pool pass a large value.
|
|
7
|
+
*/
|
|
3
8
|
topK: number;
|
|
4
|
-
/** Retained for API compatibility;
|
|
9
|
+
/** Retained for API compatibility; pure-duplicate removal is always enabled. */
|
|
5
10
|
dedup: boolean;
|
|
6
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Cross-method evidence collator.
|
|
14
|
+
*
|
|
15
|
+
* `search_all_documents` is the *exhaustive* retrieval surface: it fans out to
|
|
16
|
+
* every configured method and the librarian is expected to judge the evidence
|
|
17
|
+
* itself. Collapsing that fan-out to one chunk per source threw away most of
|
|
18
|
+
* what was retrieved — a document whose several passages all matched surfaced
|
|
19
|
+
* only its single best chunk, and a datasource that returned twenty relevant
|
|
20
|
+
* messages could be reduced to one. Modern context windows hold the full pool
|
|
21
|
+
* (a live 16-method run over this repository's own corpus measured ~26k tokens
|
|
22
|
+
* on average, ~53k at its worst), so withholding it bought nothing.
|
|
23
|
+
*
|
|
24
|
+
* This merger therefore preserves every distinct chunk and removes only *pure*
|
|
25
|
+
* duplicates: the same evidence identity (`source` + `id`) seen more than once.
|
|
26
|
+
* Ranking still normalizes each method's scores into a comparable 0..1 band and
|
|
27
|
+
* gives a bounded bonus to sources corroborated by several chunks or methods,
|
|
28
|
+
* so the strongest evidence stays at the top of a complete list.
|
|
29
|
+
*/
|
|
7
30
|
export declare class ResultMerger {
|
|
8
31
|
merge(results: Map<string, RetrievalResult[]>, options: MergeOptions): RetrievalResult[];
|
|
9
32
|
}
|
|
10
33
|
export declare class ParallelRetriever {
|
|
11
34
|
retrieve(methods: RetrievalMethod[], query: string, options: RetrievalOptions): Promise<Map<string, RetrievalResult[]>>;
|
|
12
35
|
/**
|
|
13
|
-
* Like {@link retrieve} but also returns
|
|
14
|
-
*
|
|
15
|
-
* methods
|
|
16
|
-
*
|
|
36
|
+
* Like {@link retrieve} but also returns diagnostics for methods that failed,
|
|
37
|
+
* plus the retrieval surfaces those methods belong to. Partial results from
|
|
38
|
+
* healthy methods are preserved; a failed method yields an empty result set,
|
|
39
|
+
* a diagnostic quoting the underlying error, and an entry in `unsearched`
|
|
40
|
+
* carrying that error verbatim. The legacy {@link retrieve} return shape is
|
|
41
|
+
* intentionally unchanged for compatibility.
|
|
17
42
|
*/
|
|
18
43
|
retrieveWithDiagnostics(methods: RetrievalMethod[], query: string, options: RetrievalOptions): Promise<RetrievalWithDiagnostics>;
|
|
19
44
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skip reporting for the retrieval pipeline.
|
|
3
|
+
*
|
|
4
|
+
* A method that throws is skipped, not fatal: healthy methods still answer. The
|
|
5
|
+
* helpers here turn those skips into a first-class report of the retrieval
|
|
6
|
+
* *surfaces* (local MinSync files, a datasource) that were not searched.
|
|
7
|
+
*
|
|
8
|
+
* The reason is the underlying error, verbatim. AutoRAG does not classify,
|
|
9
|
+
* rewrite, or suppress it: the operator searching their own machine is the one
|
|
10
|
+
* who has to debug the failure, so they get the CLI's own words — exit codes,
|
|
11
|
+
* stderr, paths and all.
|
|
12
|
+
*/
|
|
13
|
+
import type { RetrievalMethodDescriptor, RetrievalUnsearchedSurface } from "./types.js";
|
|
14
|
+
/** Surface label shared by every MinSync-backed local method (vector, BM25, hybrid). */
|
|
15
|
+
export declare const MINSYNC_SURFACE = "minsync";
|
|
16
|
+
/** One method that did not run, with the error that stopped it. */
|
|
17
|
+
export interface RetrievalSkip {
|
|
18
|
+
readonly method: string;
|
|
19
|
+
readonly surface: string;
|
|
20
|
+
/** The underlying failure, verbatim. */
|
|
21
|
+
readonly reason: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Map a method descriptor onto the surface a caller reasons about: datasource
|
|
25
|
+
* methods keep their datasource id, MinSync-backed local methods collapse into
|
|
26
|
+
* one shared surface, and anything else reports under its own method name.
|
|
27
|
+
*/
|
|
28
|
+
export declare function retrievalSurfaceFor(descriptor: RetrievalMethodDescriptor): string;
|
|
29
|
+
/**
|
|
30
|
+
* Render a thrown value as the text a human needs to debug it. Nothing is
|
|
31
|
+
* stripped: whatever the method (or the CLI behind it) said comes through,
|
|
32
|
+
* including paths and exit status. The JS stack is left out because it points at
|
|
33
|
+
* AutoRAG's own frames, not at the failure the operator has to fix.
|
|
34
|
+
*/
|
|
35
|
+
export declare function describeRetrievalError(error: unknown): string;
|
|
36
|
+
/**
|
|
37
|
+
* Collapse per-method skips into one entry per surface. Distinct failures on
|
|
38
|
+
* the same surface are all preserved verbatim in the reason; methods are
|
|
39
|
+
* merged. Deterministically ordered.
|
|
40
|
+
*/
|
|
41
|
+
export declare function groupUnsearchedSurfaces(skips: readonly RetrievalSkip[]): RetrievalUnsearchedSurface[];
|
|
@@ -27,17 +27,38 @@ export interface RetrievalMethod {
|
|
|
27
27
|
retrieve(query: string, options: RetrievalOptions): Promise<RetrievalResult[]>;
|
|
28
28
|
}
|
|
29
29
|
export type RetrievalDiagnosticCode = "retrieval-method-failed" | "minsync-unavailable";
|
|
30
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* A retrieval surface (local MinSync files or one datasource) that was not
|
|
32
|
+
* searched for this query. Reported next to partial results so a caller that
|
|
33
|
+
* reads only the result list can still tell the answer is incomplete.
|
|
34
|
+
*/
|
|
35
|
+
export interface RetrievalUnsearchedSurface {
|
|
36
|
+
/** Surface label: "minsync" for local files, or the datasource id. */
|
|
37
|
+
surface: string;
|
|
38
|
+
/** Registered retrieval method names on this surface that did not run. */
|
|
39
|
+
methods: string[];
|
|
40
|
+
/**
|
|
41
|
+
* Why the surface did not run: the underlying error verbatim (CLI stderr,
|
|
42
|
+
* exit status, paths included). Never classified or suppressed — the operator
|
|
43
|
+
* debugging their own machine needs the real text.
|
|
44
|
+
*/
|
|
45
|
+
reason: string;
|
|
46
|
+
}
|
|
47
|
+
/** Diagnostic emitted by the multi-method retrieval pipeline. */
|
|
31
48
|
export interface RetrievalDiagnostic {
|
|
32
49
|
code: RetrievalDiagnosticCode;
|
|
33
50
|
severity: "info" | "warning" | "error";
|
|
34
51
|
message: string;
|
|
35
|
-
/** Component/method label
|
|
52
|
+
/** Component/method label. */
|
|
36
53
|
source?: string;
|
|
54
|
+
/** The underlying failure verbatim when the diagnostic reports a method that did not run. */
|
|
55
|
+
reason?: string;
|
|
37
56
|
}
|
|
38
57
|
export interface RetrievalWithDiagnostics {
|
|
39
58
|
results: Map<string, RetrievalResult[]>;
|
|
40
59
|
diagnostics: RetrievalDiagnostic[];
|
|
60
|
+
/** Surfaces that were not searched for this query. Empty when every method ran. */
|
|
61
|
+
unsearched: RetrievalUnsearchedSurface[];
|
|
41
62
|
}
|
|
42
63
|
export interface NumberedResult {
|
|
43
64
|
index: number;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML entity decoding shared by the web search providers and the fetch
|
|
3
|
+
* pipeline.
|
|
4
|
+
*
|
|
5
|
+
* Single-pass by construction: one alternation regex decodes each entity
|
|
6
|
+
* exactly once, so an entity produced by decoding (`&lt;` → `<`) is
|
|
7
|
+
* never re-decoded into markup (CodeQL js/double-escaping). Unknown entities
|
|
8
|
+
* and bare ampersands pass through untouched.
|
|
9
|
+
*/
|
|
10
|
+
export declare function decodeHtmlEntities(value: string): string;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binary download and conversion — adapted from oh-my-pi's
|
|
3
|
+
* `packages/coding-agent/src/web/scrapers/utils.ts` (MIT licensed).
|
|
4
|
+
*
|
|
5
|
+
* `convertBinaryPayload` uses AutoRAG's parser registry for PDF/DOCX/PPTX/XLSX.
|
|
6
|
+
* EPUB and other unsupported extensions fall through to the binary-notice
|
|
7
|
+
* fallback, since AutoRAG's default registry has no EPUB parser. This is a
|
|
8
|
+
* deliberate deviation from oh-my-pi (which uses markit for all convertible
|
|
9
|
+
* types including EPUB) — see the report for rationale.
|
|
10
|
+
*/
|
|
11
|
+
import { buildBinaryNotice } from "./url-target.js";
|
|
12
|
+
export interface BinaryFetchSuccess {
|
|
13
|
+
ok: true;
|
|
14
|
+
buffer: Uint8Array;
|
|
15
|
+
contentDisposition?: string;
|
|
16
|
+
}
|
|
17
|
+
export type BinaryFetchResult = BinaryFetchSuccess | {
|
|
18
|
+
ok: false;
|
|
19
|
+
error?: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Fetch binary content from a URL with a size limit.
|
|
23
|
+
*/
|
|
24
|
+
export declare function fetchBinary(url: string, timeout?: number, signal?: AbortSignal, fetchImpl?: typeof fetch): Promise<BinaryFetchResult>;
|
|
25
|
+
export interface ConvertResult {
|
|
26
|
+
content: string;
|
|
27
|
+
ok: boolean;
|
|
28
|
+
error?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Convert a binary payload to markdown using AutoRAG's parser registry.
|
|
32
|
+
* Falls back to the binary-notice string when no parser handles the extension.
|
|
33
|
+
*/
|
|
34
|
+
export declare function convertBinaryPayload(buffer: Uint8Array, extension: string, _finalUrl: string, signal?: AbortSignal): Promise<ConvertResult>;
|
|
35
|
+
export { buildBinaryNotice };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RSS/Atom feed parsing and JSON formatting — ported from oh-my-pi's
|
|
3
|
+
* `packages/coding-agent/src/tools/fetch.ts` (MIT licensed).
|
|
4
|
+
*
|
|
5
|
+
* Feed parsing uses `fast-xml-parser` (already an AutoRAG dependency) instead
|
|
6
|
+
* of oh-my-pi's `parseHTML`/DOM utils, which are not available here.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Read a single HTML attribute from a tag string.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getHtmlAttribute(tag: string, attribute: string): string | null;
|
|
12
|
+
/**
|
|
13
|
+
* Extract bounded `<head>` markup to avoid expensive whole-page parsing.
|
|
14
|
+
*/
|
|
15
|
+
export declare function extractHeadHtml(html: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Parse alternate links from HTML head.
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseAlternateLinks(html: string, pageUrl: string): string[];
|
|
20
|
+
/**
|
|
21
|
+
* Extract document links from HTML (for PDF/DOCX wrapper pages).
|
|
22
|
+
*/
|
|
23
|
+
export declare function extractDocumentLinks(html: string, baseUrl: string): string[];
|
|
24
|
+
/**
|
|
25
|
+
* Strip a CDATA wrapper and clean text. Only a full-string wrapper is
|
|
26
|
+
* unwrapped (anchored): a stray `]]>` inside content is data, not markup.
|
|
27
|
+
* Entity decoding is single-pass (see `../entities.ts`).
|
|
28
|
+
*/
|
|
29
|
+
export declare function cleanFeedText(text: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Parse RSS/Atom feed XML to markdown using fast-xml-parser.
|
|
32
|
+
*/
|
|
33
|
+
export declare function parseFeedToMarkdown(content: string, maxItems?: number): string;
|
|
34
|
+
/**
|
|
35
|
+
* Pretty-print JSON content.
|
|
36
|
+
*/
|
|
37
|
+
export declare function formatJson(content: string): string;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML rendering backend chain — ported from oh-my-pi's
|
|
3
|
+
* `packages/coding-agent/src/tools/fetch.ts` (MIT licensed).
|
|
4
|
+
*
|
|
5
|
+
* FetchProvider order: native → lynx → firecrawl → jina.
|
|
6
|
+
* trafilatura is dropped (requires oh-my-pi's pip ensureTool).
|
|
7
|
+
* parallel is dropped (requires oh-my-pi's keyed client port).
|
|
8
|
+
* lynx is used only when found on PATH via a `which` check.
|
|
9
|
+
* firecrawl via FIRECRAWL_API_KEY env.
|
|
10
|
+
* jina via keyless https://r.jina.ai/ with optional JINA_API_KEY.
|
|
11
|
+
*/
|
|
12
|
+
export type FetchProvider = "native" | "lynx" | "firecrawl" | "jina";
|
|
13
|
+
export interface RenderHtmlToTextOptions {
|
|
14
|
+
/** Overall render budget in seconds (default 30). */
|
|
15
|
+
timeoutSeconds?: number;
|
|
16
|
+
signal?: AbortSignal;
|
|
17
|
+
fetch?: typeof fetch;
|
|
18
|
+
firecrawlApiKey?: string;
|
|
19
|
+
jinaApiKey?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Inject custom backend runners for testing. Keys must cover every
|
|
22
|
+
* FetchProvider in FETCH_PROVIDER_ORDER. A runner returns the rendered
|
|
23
|
+
* markdown or null to signal "not available / low quality / error."
|
|
24
|
+
*/
|
|
25
|
+
runners?: Record<FetchProvider, () => Promise<string | null>>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parse the `Markdown Content:` marker from a Jina Reader response body.
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseJinaReaderContent(responseBody: string): string | null;
|
|
31
|
+
/**
|
|
32
|
+
* Check if rendered output looks JS-gated or mostly navigation.
|
|
33
|
+
*/
|
|
34
|
+
export declare function isLowQualityOutput(content: string): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Convert HTML to markdown using the vendored Turndown with GFM support.
|
|
37
|
+
* Script/style elements are dropped by a parser-level turndown rule — never
|
|
38
|
+
* by regex pre-stripping (CodeQL js/bad-tag-filter,
|
|
39
|
+
* js/incomplete-multi-character-sanitization).
|
|
40
|
+
*/
|
|
41
|
+
export declare function htmlToBasicMarkdown(html: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Render HTML to markdown by trying reader backends in priority order:
|
|
44
|
+
* native (in-process), lynx, firecrawl, then jina.
|
|
45
|
+
*
|
|
46
|
+
* Every backend's output must clear the quality gate (>100 non-whitespace
|
|
47
|
+
* chars and not isLowQualityOutput) before it is accepted; otherwise the
|
|
48
|
+
* next backend is tried.
|
|
49
|
+
*/
|
|
50
|
+
export declare function renderHtmlToText(url: string, html: string, options: RenderHtmlToTextOptions): Promise<{
|
|
51
|
+
content: string;
|
|
52
|
+
ok: boolean;
|
|
53
|
+
method: FetchProvider | "none";
|
|
54
|
+
}>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URL fetch/render pipeline — self-contained module backing the future
|
|
3
|
+
* `web_fetch` agent tool. Ported from oh-my-pi (MIT licensed).
|
|
4
|
+
*/
|
|
5
|
+
export { type BinaryFetchResult, type ConvertResult, convertBinaryPayload, fetchBinary } from "./convert.js";
|
|
6
|
+
export { cleanFeedText, extractDocumentLinks, extractHeadHtml, formatJson, getHtmlAttribute, parseAlternateLinks, parseFeedToMarkdown, } from "./feeds.js";
|
|
7
|
+
export { type FetchProvider, htmlToBasicMarkdown, isLowQualityOutput, parseJinaReaderContent, type RenderHtmlToTextOptions, renderHtmlToText, } from "./html-renderer.js";
|
|
8
|
+
export { buildLlmEndpointCandidates, tryContentNegotiation, tryLlmEndpoints, tryMdSuffix } from "./negotiate.js";
|
|
9
|
+
export type { LoadPageOptions, LoadPageResult, RenderResult } from "./page-loader.js";
|
|
10
|
+
export { decodeHtmlEntities, finalizeOutput, loadPage, looksLikeHtml, MAX_BYTES, MAX_OUTPUT_CHARS, } from "./page-loader.js";
|
|
11
|
+
export { type RenderUrlOptions, renderUrl } from "./render.js";
|
|
12
|
+
export { buildBinaryNotice, getExtensionHint, getFilenameExtensionHint, isConvertible, normalizeMime, normalizeUrl, sampleLooksBinary, } from "./url-target.js";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content negotiation and LLM endpoint discovery — ported from oh-my-pi's
|
|
3
|
+
* `packages/coding-agent/src/tools/fetch.ts` (MIT licensed).
|
|
4
|
+
*/
|
|
5
|
+
import { type FetchImpl } from "./page-loader.js";
|
|
6
|
+
/**
|
|
7
|
+
* Build llms.txt / llms.md candidates scoped to the requested URL.
|
|
8
|
+
*/
|
|
9
|
+
export declare function buildLlmEndpointCandidates(url: string): string[];
|
|
10
|
+
/**
|
|
11
|
+
* Try fetching URL with .md appended (llms.txt convention).
|
|
12
|
+
*/
|
|
13
|
+
export declare function tryMdSuffix(url: string, timeout: number, signal?: AbortSignal, fetchImpl?: FetchImpl): Promise<string | null>;
|
|
14
|
+
/**
|
|
15
|
+
* Try to fetch LLM-friendly endpoints (llms.txt, llms.md).
|
|
16
|
+
*/
|
|
17
|
+
export declare function tryLlmEndpoints(url: string, timeout: number, signal?: AbortSignal, fetchImpl?: FetchImpl): Promise<{
|
|
18
|
+
content: string;
|
|
19
|
+
endpoint: string;
|
|
20
|
+
} | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Try content negotiation for markdown/plain.
|
|
23
|
+
*/
|
|
24
|
+
export declare function tryContentNegotiation(url: string, timeout: number, signal?: AbortSignal, fetchImpl?: FetchImpl): Promise<{
|
|
25
|
+
content: string;
|
|
26
|
+
type: string;
|
|
27
|
+
} | null>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page loader and output finalization — ported from oh-my-pi's
|
|
3
|
+
* `packages/coding-agent/src/web/scrapers/types.ts` (MIT licensed).
|
|
4
|
+
*
|
|
5
|
+
* Provides: loadPage (UA rotation, 429 Retry-After backoff, streaming
|
|
6
|
+
* maxBytes cap, charset-aware decodeBody), finalizeOutput, looksLikeHtml,
|
|
7
|
+
* decodeHtmlEntities, MAX_BYTES, MAX_OUTPUT_CHARS, RenderResult types.
|
|
8
|
+
*/
|
|
9
|
+
export interface RenderResult {
|
|
10
|
+
readonly url: string;
|
|
11
|
+
readonly finalUrl: string;
|
|
12
|
+
readonly contentType: string;
|
|
13
|
+
readonly method: string;
|
|
14
|
+
readonly content: string;
|
|
15
|
+
readonly fetchedAt: string;
|
|
16
|
+
readonly truncated: boolean;
|
|
17
|
+
readonly notes: string[];
|
|
18
|
+
}
|
|
19
|
+
export declare const MAX_OUTPUT_CHARS = 500000;
|
|
20
|
+
export declare const MAX_BYTES: number;
|
|
21
|
+
/** Transport signature accepted for injection (tests, proxies). */
|
|
22
|
+
export type FetchImpl = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
23
|
+
export interface LoadPageOptions {
|
|
24
|
+
timeout?: number;
|
|
25
|
+
/** Transport injection; defaults to global fetch. */
|
|
26
|
+
fetch?: FetchImpl;
|
|
27
|
+
headers?: Record<string, string>;
|
|
28
|
+
method?: string;
|
|
29
|
+
body?: string;
|
|
30
|
+
maxBytes?: number;
|
|
31
|
+
signal?: AbortSignal;
|
|
32
|
+
skipBodyForContentType?: (contentType: string) => boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface LoadPageResult {
|
|
35
|
+
content: string;
|
|
36
|
+
contentType: string;
|
|
37
|
+
finalUrl: string;
|
|
38
|
+
ok: boolean;
|
|
39
|
+
status?: number;
|
|
40
|
+
truncated?: boolean;
|
|
41
|
+
error?: string;
|
|
42
|
+
bodySkipped?: boolean;
|
|
43
|
+
}
|
|
44
|
+
export declare function finalizeOutput(content: string): {
|
|
45
|
+
content: string;
|
|
46
|
+
truncated: boolean;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Fetch a page with timeout and size limit.
|
|
50
|
+
*/
|
|
51
|
+
export declare function loadPage(url: string, options?: LoadPageOptions): Promise<LoadPageResult>;
|
|
52
|
+
/**
|
|
53
|
+
* Check if content looks like HTML by inspecting the leading tag.
|
|
54
|
+
*/
|
|
55
|
+
export declare function looksLikeHtml(content: string): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Decode common HTML entities. Single-pass: an entity produced by decoding
|
|
58
|
+
* is never re-decoded (see `../entities.ts`).
|
|
59
|
+
*/
|
|
60
|
+
export { decodeHtmlEntities } from "../entities.js";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* renderUrl — the full URL-fetch/render pipeline — ported from oh-my-pi's
|
|
3
|
+
* `packages/coding-agent/src/tools/fetch.ts` (MIT licensed).
|
|
4
|
+
*
|
|
5
|
+
* Special site handlers (step 1), images, sqlite, archives, and notebooks
|
|
6
|
+
* are NOT ported. Binary payloads (zip, pdf, etc.) return a textual binary
|
|
7
|
+
* notice. The markit conversion step uses AutoRAG's parser registry for
|
|
8
|
+
* PDF/DOCX/PPTX/XLSX; EPUB and other unsupported types fall through to the
|
|
9
|
+
* binary-notice fallback.
|
|
10
|
+
*/
|
|
11
|
+
import { type RenderResult } from "./page-loader.js";
|
|
12
|
+
export interface RenderUrlOptions {
|
|
13
|
+
timeoutSeconds?: number;
|
|
14
|
+
raw?: boolean;
|
|
15
|
+
signal?: AbortSignal;
|
|
16
|
+
fetch?: typeof fetch;
|
|
17
|
+
firecrawlApiKey?: string;
|
|
18
|
+
jinaApiKey?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Fetch and render a URL to markdown or text.
|
|
22
|
+
*/
|
|
23
|
+
export declare function renderUrl(url: string, options?: RenderUrlOptions): Promise<RenderResult>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TurndownPlugin } from "./types.js";
|
|
2
|
+
/** Install GitHub fenced code blocks selected by `highlight-source-*` wrappers. */
|
|
3
|
+
export declare const highlightedCodeBlock: TurndownPlugin;
|
|
4
|
+
/** Install GFM strikethrough conversion. */
|
|
5
|
+
export declare const strikethrough: TurndownPlugin;
|
|
6
|
+
/** Install GFM task-list checkbox conversion. */
|
|
7
|
+
export declare const taskListItems: TurndownPlugin;
|
|
8
|
+
/** Install GFM table conversion for tables with a heading row. */
|
|
9
|
+
export declare const tables: TurndownPlugin;
|
|
10
|
+
/** Install every GFM rule used by the coding agent. */
|
|
11
|
+
export declare const gfm: TurndownPlugin;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { TurndownNode } from "./types.js";
|
|
2
|
+
/** Parse an HTML fragment into the small DOM subset needed by Turndown. */
|
|
3
|
+
export declare function parseHtmlFragment(html: string): TurndownNode;
|
|
4
|
+
/** Serialize a standards-shaped or internal HTML node. */
|
|
5
|
+
export declare function serializeNode(node: TurndownNode): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendored from oh-my-pi (packages/utils/src/turndown) — MIT licensed.
|
|
3
|
+
* Behavior-compatible Turndown reimplementation used as the `native`
|
|
4
|
+
* HTML-to-markdown backend by `src/web/fetch/html-renderer.ts`.
|
|
5
|
+
*
|
|
6
|
+
* Source: https://github.com/oh-my-pi/oh-my-pi
|
|
7
|
+
*/
|
|
8
|
+
export * from "./gfm.js";
|
|
9
|
+
export { default, default as TurndownService } from "./service.js";
|
|
10
|
+
export * from "./types.js";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ResolvedTurndownOptions, RuleFilter, TurndownNode, TurndownOptions, TurndownPlugin, TurndownRule } from "./types.js";
|
|
2
|
+
/** Convert HTML fragments to Markdown with extensible Turndown-compatible rules. */
|
|
3
|
+
export default class TurndownService {
|
|
4
|
+
#private;
|
|
5
|
+
readonly options: ResolvedTurndownOptions;
|
|
6
|
+
constructor(options?: TurndownOptions);
|
|
7
|
+
/** Install a highest-priority named conversion rule. */
|
|
8
|
+
addRule(key: string, rule: TurndownRule): this;
|
|
9
|
+
/** Preserve matching elements as HTML when no custom rule handles them. */
|
|
10
|
+
keep(filter: RuleFilter): this;
|
|
11
|
+
/** Drop matching elements and all of their converted content. */
|
|
12
|
+
remove(filter: RuleFilter): this;
|
|
13
|
+
/** Install one plugin or an ordered list of plugins. */
|
|
14
|
+
use(plugin: TurndownPlugin | readonly TurndownPlugin[]): this;
|
|
15
|
+
/** Escape Markdown punctuation using Turndown's public escaping rules. */
|
|
16
|
+
escape(text: string): string;
|
|
17
|
+
/** Convert an HTML string or standards-shaped DOM node to Markdown. */
|
|
18
|
+
turndown(input: string | TurndownNode): string;
|
|
19
|
+
/** Convert only a node's children within the active conversion. */
|
|
20
|
+
convertChildren(node: TurndownNode): string;
|
|
21
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Behavior-compatible reimplementation of turndown's used surface.
|
|
3
|
+
* Vendored from oh-my-pi (can1357/oh-my-pi, MIT) `packages/utils/src/turndown/types.ts`.
|
|
4
|
+
*/
|
|
5
|
+
/** A DOM-shaped node accepted by conversion rules. */
|
|
6
|
+
export interface TurndownNode {
|
|
7
|
+
readonly nodeType: number;
|
|
8
|
+
readonly nodeName: string;
|
|
9
|
+
readonly parentNode: TurndownNode | null;
|
|
10
|
+
readonly childNodes: ArrayLike<TurndownNode>;
|
|
11
|
+
readonly children: ArrayLike<TurndownNode>;
|
|
12
|
+
readonly firstChild: TurndownNode | null;
|
|
13
|
+
readonly lastChild: TurndownNode | null;
|
|
14
|
+
readonly nextSibling: TurndownNode | null;
|
|
15
|
+
readonly previousSibling: TurndownNode | null;
|
|
16
|
+
readonly textContent: string | null;
|
|
17
|
+
readonly outerHTML?: string;
|
|
18
|
+
getAttribute(name: string): string | null;
|
|
19
|
+
hasAttribute(name: string): boolean;
|
|
20
|
+
}
|
|
21
|
+
/** Options supported by the HTML-to-Markdown converter. */
|
|
22
|
+
export interface TurndownOptions {
|
|
23
|
+
headingStyle?: "setext" | "atx";
|
|
24
|
+
hr?: string;
|
|
25
|
+
bulletListMarker?: "*" | "-" | "+";
|
|
26
|
+
codeBlockStyle?: "indented" | "fenced";
|
|
27
|
+
fence?: string;
|
|
28
|
+
emDelimiter?: "_" | "*";
|
|
29
|
+
strongDelimiter?: "**" | "__";
|
|
30
|
+
linkStyle?: "inlined" | "referenced";
|
|
31
|
+
linkReferenceStyle?: "full" | "collapsed" | "shortcut";
|
|
32
|
+
preformattedCode?: boolean;
|
|
33
|
+
blankReplacement?: ReplacementFunction;
|
|
34
|
+
keepReplacement?: ReplacementFunction;
|
|
35
|
+
defaultReplacement?: ReplacementFunction;
|
|
36
|
+
}
|
|
37
|
+
/** Fully resolved options passed to replacement callbacks. */
|
|
38
|
+
export interface ResolvedTurndownOptions {
|
|
39
|
+
headingStyle: "setext" | "atx";
|
|
40
|
+
hr: string;
|
|
41
|
+
bulletListMarker: "*" | "-" | "+";
|
|
42
|
+
codeBlockStyle: "indented" | "fenced";
|
|
43
|
+
fence: string;
|
|
44
|
+
emDelimiter: "_" | "*";
|
|
45
|
+
strongDelimiter: "**" | "__";
|
|
46
|
+
linkStyle: "inlined" | "referenced";
|
|
47
|
+
linkReferenceStyle: "full" | "collapsed" | "shortcut";
|
|
48
|
+
preformattedCode: boolean;
|
|
49
|
+
blankReplacement?: ReplacementFunction;
|
|
50
|
+
keepReplacement?: ReplacementFunction;
|
|
51
|
+
defaultReplacement?: ReplacementFunction;
|
|
52
|
+
}
|
|
53
|
+
/** A tag name, list of tag names, or predicate selecting nodes for a rule. */
|
|
54
|
+
export type RuleFilter = string | readonly string[] | ((node: TurndownNode, options: ResolvedTurndownOptions) => boolean);
|
|
55
|
+
/** Produces Markdown for a matched node and its already-converted children. */
|
|
56
|
+
export type ReplacementFunction = (content: string, node: TurndownNode, options: ResolvedTurndownOptions) => string;
|
|
57
|
+
/** A named conversion rule accepted by `addRule`. */
|
|
58
|
+
export interface TurndownRule {
|
|
59
|
+
filter: RuleFilter;
|
|
60
|
+
replacement: ReplacementFunction;
|
|
61
|
+
}
|
|
62
|
+
/** A plugin that installs one or more conversion rules. */
|
|
63
|
+
export type TurndownPlugin = (service: TurndownServiceLike) => void;
|
|
64
|
+
/** Structural service surface available to plugins. */
|
|
65
|
+
export interface TurndownServiceLike {
|
|
66
|
+
readonly options: ResolvedTurndownOptions;
|
|
67
|
+
addRule(key: string, rule: TurndownRule): this;
|
|
68
|
+
convertChildren(node: TurndownNode): string;
|
|
69
|
+
keep(filter: RuleFilter): this;
|
|
70
|
+
remove(filter: RuleFilter): this;
|
|
71
|
+
turndown(input: string | TurndownNode): string;
|
|
72
|
+
escape(text: string): string;
|
|
73
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URL normalization, MIME classification, and binary detection — ported from
|
|
3
|
+
* oh-my-pi's `packages/coding-agent/src/tools/fetch.ts` (MIT licensed).
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Normalize a URL: repair a collapsed scheme, then add `https://` if missing.
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizeUrl(url: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Normalize a MIME type (lowercase, strip charset/params).
|
|
11
|
+
*/
|
|
12
|
+
export declare function normalizeMime(contentType: string): string;
|
|
13
|
+
export declare function getFilenameExtensionHint(filename: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Get extension from URL or Content-Disposition.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getExtensionHint(url: string, contentDisposition?: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Check if content type is convertible via AutoRAG's parser registry.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isConvertible(mime: string, extensionHint: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Heuristic: does the text sample look like binary (NUL bytes or high U+FFFD density)?
|
|
24
|
+
*/
|
|
25
|
+
export declare function sampleLooksBinary(text: string): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Build a textual binary notice for unsupported binary payloads.
|
|
28
|
+
*/
|
|
29
|
+
export declare function buildBinaryNotice(finalUrl: string, mime: string, byteLength?: number): string;
|