@absolutejs/rag 0.12.0 → 0.14.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/CHANGELOG.md +20 -0
- package/README.md +17 -3
- package/changelog.json +40 -0
- package/dist/src/web/website.d.ts +16 -0
- package/dist/web/index.js +29 -8
- package/dist/web/index.js.map +3 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,26 @@ This file is generated by `absolute-changelog` from the entries in
|
|
|
6
6
|
`changelog/`. Edit an entry, not this file — and add new ones under
|
|
7
7
|
`changelog/unreleased/`.
|
|
8
8
|
|
|
9
|
+
## 0.14.0 — 2026-09-18
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **Return copy-ready source citations before website evidence and repeat links beside each retrieved page; exclude failed reads and unread links from the source list.** (`readRAGWebsite`)
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- **Require nearby source links for factual answers and distinguish supported customer examples from unsupported exclusions, ownership relationships and rebrand history.** (`readRAGWebsite`)
|
|
18
|
+
|
|
19
|
+
## 0.13.0 — 2026-09-18
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **Expose stop reasons and actual incomplete page reads separately from unvisited links; guide targeted continuation and concise nontechnical answers.** (`readRAGWebsite`)
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- **Balance repeated customer, service and company reads across an eight-page default budget (maximum twelve) with 48000 characters, preventing case-study archives from starving service details.** (`readRAGWebsite`)
|
|
28
|
+
|
|
9
29
|
## 0.12.0 — 2026-09-18
|
|
10
30
|
|
|
11
31
|
### Added
|
package/README.md
CHANGED
|
@@ -165,15 +165,29 @@ must enforce equivalent network controls.
|
|
|
165
165
|
|
|
166
166
|
### Research related website pages with attributable evidence
|
|
167
167
|
|
|
168
|
-
`readRAGWebsite` from `@absolutejs/rag/web` reads
|
|
169
|
-
|
|
168
|
+
`readRAGWebsite` from `@absolutejs/rag/web` reads up to eight pages by default, balancing
|
|
169
|
+
same-origin customer, service and company pages so service details are not
|
|
170
|
+
starved by large case-study archives. The configurable ceiling is twelve pages;
|
|
171
|
+
the overall deadline remains 75 seconds and default text budget is 48,000 characters. Pass the
|
|
170
172
|
optional Playwright renderer as for `readRAGWebpage`. `maxPages: 1` retains a
|
|
171
173
|
single-page read; `mode: "browser"` retries content missed by static extraction.
|
|
172
174
|
Results attribute text to exact page URLs and retain per-page redirects,
|
|
173
175
|
retrieval attempts, semantic image labels, link destinations, media URLs and
|
|
174
176
|
available caption text. Coverage includes unvisited relevant links and deadline
|
|
175
|
-
limits.
|
|
177
|
+
limits. `incompleteReads` identifies failed, partial or truncated page reads;
|
|
178
|
+
unvisited links and successful browser fallback are not failed reads.
|
|
179
|
+
`stopReason` distinguishes a page limit, deadline and exhausted relevant links.
|
|
180
|
+
A per-call limit is not a reason to stop research when a material question remains:
|
|
181
|
+
use targeted follow-up reads. Present business answers first and keep technical
|
|
182
|
+
diagnostics for explicit debugging requests. HTTP redirects carry their actual status; client navigation is labeled
|
|
176
183
|
separately. Empty image labels are not proof of an absent client list, and media
|
|
177
184
|
URLs are not proof that a video was watched. Consumers must cite source URLs,
|
|
178
185
|
distinguish extracted evidence from inference, and finish the requested research
|
|
179
186
|
without treating a successful page fetch as complete company coverage.
|
|
187
|
+
|
|
188
|
+
Website results also lead with a `sources` array containing each readable page's
|
|
189
|
+
`title`, `url` and ready-to-use Markdown `citation`, repeated next to that page's
|
|
190
|
+
evidence text. Failed pages and unvisited links are not citable source entries.
|
|
191
|
+
`citationRequirements` asks consumers to place links beside supported claims,
|
|
192
|
+
avoid unsupported exclusions or ownership relationships, and keep verified brand
|
|
193
|
+
changes brief. Host applications still control their generated final answers.
|
package/changelog.json
CHANGED
|
@@ -2,6 +2,46 @@
|
|
|
2
2
|
"contract": 1,
|
|
3
3
|
"name": "@absolutejs/rag",
|
|
4
4
|
"releases": [
|
|
5
|
+
{
|
|
6
|
+
"changes": [
|
|
7
|
+
{
|
|
8
|
+
"kind": "changed",
|
|
9
|
+
"summary": "Require nearby source links for factual answers and distinguish supported customer examples from unsupported exclusions, ownership relationships and rebrand history.",
|
|
10
|
+
"symbols": [
|
|
11
|
+
"readRAGWebsite"
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"kind": "added",
|
|
16
|
+
"summary": "Return copy-ready source citations before website evidence and repeat links beside each retrieved page; exclude failed reads and unread links from the source list.",
|
|
17
|
+
"symbols": [
|
|
18
|
+
"readRAGWebsite"
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"date": "2026-09-18",
|
|
23
|
+
"version": "0.14.0"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"changes": [
|
|
27
|
+
{
|
|
28
|
+
"kind": "changed",
|
|
29
|
+
"summary": "Balance repeated customer, service and company reads across an eight-page default budget (maximum twelve) with 48000 characters, preventing case-study archives from starving service details.",
|
|
30
|
+
"symbols": [
|
|
31
|
+
"readRAGWebsite"
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"kind": "added",
|
|
36
|
+
"summary": "Expose stop reasons and actual incomplete page reads separately from unvisited links; guide targeted continuation and concise nontechnical answers.",
|
|
37
|
+
"symbols": [
|
|
38
|
+
"readRAGWebsite"
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"date": "2026-09-18",
|
|
43
|
+
"version": "0.13.0"
|
|
44
|
+
},
|
|
5
45
|
{
|
|
6
46
|
"changes": [
|
|
7
47
|
{
|
|
@@ -34,6 +34,16 @@ export declare const readRAGWebsite: (options: ReadWebpageOptions & {
|
|
|
34
34
|
remainingRelevantLinks: string[];
|
|
35
35
|
deadlineReached: boolean;
|
|
36
36
|
exhaustive: boolean;
|
|
37
|
+
stopReason: string;
|
|
38
|
+
incompleteReads: {
|
|
39
|
+
url: string;
|
|
40
|
+
status: "error" | "partial" | "ok";
|
|
41
|
+
truncated: boolean;
|
|
42
|
+
error: {
|
|
43
|
+
code: string;
|
|
44
|
+
message: string;
|
|
45
|
+
} | undefined;
|
|
46
|
+
}[];
|
|
37
47
|
};
|
|
38
48
|
citationGuidance: string;
|
|
39
49
|
url: string;
|
|
@@ -49,4 +59,10 @@ export declare const readRAGWebsite: (options: ReadWebpageOptions & {
|
|
|
49
59
|
redirects: import("./transport").WebRedirect[];
|
|
50
60
|
evidence: import("./evidence").WebEvidence;
|
|
51
61
|
limitations: string[];
|
|
62
|
+
sources: {
|
|
63
|
+
title: string;
|
|
64
|
+
url: string;
|
|
65
|
+
citation: string;
|
|
66
|
+
}[];
|
|
67
|
+
citationRequirements: string;
|
|
52
68
|
}>;
|
package/dist/web/index.js
CHANGED
|
@@ -17718,14 +17718,14 @@ var pagePriority = (url, label) => {
|
|
|
17718
17718
|
};
|
|
17719
17719
|
var readRAGWebsite = async (options) => {
|
|
17720
17720
|
const signal = options.signal ?? AbortSignal.timeout(75000);
|
|
17721
|
-
const maxPages = Math.max(1, Math.min(options.maxPages ??
|
|
17722
|
-
const maxChars = Math.max(1000, Math.min(options.maxChars ??
|
|
17721
|
+
const maxPages = Math.max(1, Math.min(options.maxPages ?? 8, 12));
|
|
17722
|
+
const maxChars = Math.max(1000, Math.min(options.maxChars ?? 48000, 1e5));
|
|
17723
17723
|
const pages = [];
|
|
17724
17724
|
const queue = [
|
|
17725
17725
|
{ url: options.url, label: "Requested page" }
|
|
17726
17726
|
];
|
|
17727
17727
|
const visited = new Set;
|
|
17728
|
-
const
|
|
17728
|
+
const topicVisits = new Map;
|
|
17729
17729
|
let origin;
|
|
17730
17730
|
while (queue.length && pages.length < maxPages && !signal.aborted) {
|
|
17731
17731
|
const next = queue.shift();
|
|
@@ -17740,7 +17740,8 @@ var readRAGWebsite = async (options) => {
|
|
|
17740
17740
|
if (visited.has(key2.href))
|
|
17741
17741
|
continue;
|
|
17742
17742
|
visited.add(key2.href);
|
|
17743
|
-
|
|
17743
|
+
const topic = pagePriority(next.url, next.label);
|
|
17744
|
+
topicVisits.set(topic, (topicVisits.get(topic) ?? 0) + 1);
|
|
17744
17745
|
const page = await readRAGWebpage({
|
|
17745
17746
|
...options,
|
|
17746
17747
|
url: next.url,
|
|
@@ -17754,7 +17755,11 @@ var readRAGWebsite = async (options) => {
|
|
|
17754
17755
|
continue;
|
|
17755
17756
|
const links = page.evidence.links.filter((link) => new URL(link.url).origin === origin && pagePriority(link.url, link.label) > 0 && !visited.has(link.url.split("#")[0]));
|
|
17756
17757
|
queue.push(...links);
|
|
17757
|
-
queue.sort((a, b) =>
|
|
17758
|
+
queue.sort((a, b) => {
|
|
17759
|
+
const aTopic = pagePriority(a.url, a.label);
|
|
17760
|
+
const bTopic = pagePriority(b.url, b.label);
|
|
17761
|
+
return (topicVisits.get(aTopic) ?? 0) - (topicVisits.get(bTopic) ?? 0) || bTopic - aTopic;
|
|
17762
|
+
});
|
|
17758
17763
|
}
|
|
17759
17764
|
const first = pages[0] ?? await readRAGWebpage({ ...options, signal });
|
|
17760
17765
|
const captionEvidence = [];
|
|
@@ -17781,7 +17786,14 @@ var readRAGWebsite = async (options) => {
|
|
|
17781
17786
|
});
|
|
17782
17787
|
}
|
|
17783
17788
|
}
|
|
17789
|
+
const sources = pages.filter((page) => page.status !== "error" && page.text).map((page) => {
|
|
17790
|
+
const title = (page.title || new URL(page.finalUrl).hostname).replace(/\s+/gu, " ").trim();
|
|
17791
|
+
const label = title.replace(/[\\[\]]/gu, "\\$&");
|
|
17792
|
+
const href = page.finalUrl.replace(/[<>]/gu, encodeURIComponent);
|
|
17793
|
+
return { title, url: page.finalUrl, citation: `[${label}](<${href}>)` };
|
|
17794
|
+
});
|
|
17784
17795
|
const evidenceText = pages.filter((page) => page.status !== "error").map((page) => `SOURCE: ${page.finalUrl}
|
|
17796
|
+
CITATION: ${sources.find((source) => source.url === page.finalUrl)?.citation ?? page.finalUrl}
|
|
17785
17797
|
TITLE: ${page.title ?? "Untitled"}
|
|
17786
17798
|
${page.text}`).join(`
|
|
17787
17799
|
|
|
@@ -17790,6 +17802,8 @@ ${page.text}`).join(`
|
|
|
17790
17802
|
const incomplete = pages.some((page) => page.status !== "ok") || signal.aborted;
|
|
17791
17803
|
const unvisited = queue.filter((link) => !visited.has(link.url.split("#")[0]));
|
|
17792
17804
|
return {
|
|
17805
|
+
sources,
|
|
17806
|
+
citationRequirements: "The final answer must contain clickable Markdown source links, not just source names or bare domain mentions. Reuse sources[].citation beside the factual paragraph, list or table row it supports. Cite the actual supporting page, not the homepage for everything. Every factual section needs its supporting links. Do not invent sources or use unread links as evidence. Before responding, check that company facts, service descriptions, customer examples and numerical claims have supporting links; retrieve or omit unsupported claims. A list of large customers does not prove smaller customers are excluded. Preserve the brands actually named in the evidence; do not append parent companies, ownership relationships, current-account status, market rankings or rebrand history from memory. Label reasoned inferences as such. A verified brand change needs at most one short, cited sentence unless the user asks for its history.",
|
|
17793
17807
|
...first,
|
|
17794
17808
|
status: readable.length ? incomplete ? "partial" : "ok" : "error",
|
|
17795
17809
|
text: evidenceText.slice(0, maxChars),
|
|
@@ -17803,9 +17817,16 @@ ${page.text}`).join(`
|
|
|
17803
17817
|
...new Set(unvisited.map((link) => link.url))
|
|
17804
17818
|
].slice(0, 20),
|
|
17805
17819
|
deadlineReached: signal.aborted,
|
|
17806
|
-
exhaustive: false
|
|
17820
|
+
exhaustive: false,
|
|
17821
|
+
stopReason: signal.aborted ? "deadline" : unvisited.length ? "page_limit" : "links_exhausted",
|
|
17822
|
+
incompleteReads: pages.filter((page) => page.status !== "ok" || page.truncated).map((page) => ({
|
|
17823
|
+
url: page.finalUrl,
|
|
17824
|
+
status: page.status,
|
|
17825
|
+
truncated: page.truncated,
|
|
17826
|
+
error: page.error
|
|
17827
|
+
}))
|
|
17807
17828
|
},
|
|
17808
|
-
citationGuidance: "
|
|
17829
|
+
citationGuidance: "Answer the user's question first, with exact source page URLs. Distinguish retrieved facts from inference. A page limit bounds this call, not the research task: if a material question remains unanswered, read the relevant remaining links in another call, using maxPages 1 for targeted detail pages. Do not stop with a list of next steps when those reads are needed to finish the request. Conversely, unvisited links do not by themselves mean the answer is incomplete. Report only gaps that materially limit the answer, unless a retrieval audit was explicitly requested. Successful browser fallback is a completed read, not an incomplete read. Normally summarize a redirected destination in one brief sentence; omit HTTP codes, hop chains, character counts and rendering mechanics unless explicitly requested for debugging. A redirect alone does not prove a rebrand; verify that claim from a source. Image labels do not establish customer relationships and media URLs are not watched video evidence."
|
|
17809
17830
|
};
|
|
17810
17831
|
};
|
|
17811
17832
|
|
|
@@ -17981,5 +18002,5 @@ export {
|
|
|
17981
18002
|
validatePublicWebUrl
|
|
17982
18003
|
};
|
|
17983
18004
|
|
|
17984
|
-
//# debugId=
|
|
18005
|
+
//# debugId=C770BC61DAD3A78A64756E2164756E21
|
|
17985
18006
|
//# sourceMappingURL=index.js.map
|