@absolutejs/rag 0.22.7 → 0.22.9
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 +12 -0
- package/changelog.json +471 -440
- package/dist/research/index.js +59 -15
- package/dist/research/index.js.map +8 -7
- package/dist/src/research/sourceExcerpts.d.ts +3 -0
- package/dist/src/research/types.d.ts +7 -0
- package/dist/src/web/index.d.ts +3 -0
- package/dist/src/web/website.d.ts +6 -0
- package/dist/web/index.js +19 -10
- package/dist/web/index.js.map +5 -5
- package/dist/web-index/index.js +59 -15
- package/dist/web-index/index.js.map +8 -7
- package/package.json +1 -1
package/dist/research/index.js
CHANGED
|
@@ -101400,6 +101400,28 @@ var init_pdf = __esm(() => {
|
|
|
101400
101400
|
};
|
|
101401
101401
|
});
|
|
101402
101402
|
|
|
101403
|
+
// src/research/sourceExcerpts.ts
|
|
101404
|
+
import { createAITextSource } from "@absolutejs/ai";
|
|
101405
|
+
var selectResearchExcerpts = (text, budget, query) => {
|
|
101406
|
+
if (budget <= 0)
|
|
101407
|
+
return [];
|
|
101408
|
+
if (text.length <= budget)
|
|
101409
|
+
return [text];
|
|
101410
|
+
const source = createAITextSource([{ role: "user", content: text }]);
|
|
101411
|
+
const hits = source.search(query);
|
|
101412
|
+
const passages = hits.length ? hits : source.search("");
|
|
101413
|
+
let remaining = budget;
|
|
101414
|
+
const selected = [];
|
|
101415
|
+
for (const passage of passages) {
|
|
101416
|
+
if (!remaining)
|
|
101417
|
+
break;
|
|
101418
|
+
const excerpt = passage.text.slice(0, remaining);
|
|
101419
|
+
selected.push({ start: passage.start, text: excerpt });
|
|
101420
|
+
remaining -= excerpt.length;
|
|
101421
|
+
}
|
|
101422
|
+
return selected.sort((a, b) => a.start - b.start).map((passage) => passage.text);
|
|
101423
|
+
};
|
|
101424
|
+
|
|
101403
101425
|
// src/research/budget.ts
|
|
101404
101426
|
var createResearchBudgetAdmission = (config) => {
|
|
101405
101427
|
if (!config.scope.trim())
|
|
@@ -120842,7 +120864,7 @@ var readRAGWebsite = async (options) => {
|
|
|
120842
120864
|
const page = await readRAGWebpage({
|
|
120843
120865
|
...options,
|
|
120844
120866
|
url: next.url,
|
|
120845
|
-
maxChars
|
|
120867
|
+
maxChars,
|
|
120846
120868
|
signal: AbortSignal.any([signal, AbortSignal.timeout(30000)])
|
|
120847
120869
|
});
|
|
120848
120870
|
pages.push(page);
|
|
@@ -120898,24 +120920,27 @@ var readRAGWebsite = async (options) => {
|
|
|
120898
120920
|
let remainingDocumentChars = maxChars;
|
|
120899
120921
|
const documents = sources.flatMap((source) => {
|
|
120900
120922
|
const page = pages.find((item) => item.finalUrl === source.url && item.text);
|
|
120901
|
-
if (!page
|
|
120923
|
+
if (!page)
|
|
120902
120924
|
return [];
|
|
120903
120925
|
const imageLabels = page.evidence.images.filter((image) => image.label).map((image) => `${image.context ? `${image.context}: ` : ""}${image.label}`);
|
|
120904
120926
|
const fullText = [
|
|
120905
|
-
page.text,
|
|
120927
|
+
page.fullText ?? page.text,
|
|
120906
120928
|
...imageLabels.length ? [
|
|
120907
120929
|
"Image labels supplied by the website (not independently verified customer relationships):",
|
|
120908
120930
|
...imageLabels
|
|
120909
120931
|
] : []
|
|
120910
120932
|
].join(`
|
|
120911
120933
|
`);
|
|
120912
|
-
const text = fullText.slice(0, remainingDocumentChars);
|
|
120934
|
+
const text = fullText.slice(0, Math.max(0, remainingDocumentChars));
|
|
120913
120935
|
remainingDocumentChars -= text.length;
|
|
120914
120936
|
return [
|
|
120915
120937
|
{
|
|
120916
120938
|
sourceId: source.id,
|
|
120917
120939
|
text,
|
|
120918
|
-
|
|
120940
|
+
fullText,
|
|
120941
|
+
originalChars: fullText.length,
|
|
120942
|
+
sourceTruncated: page.status !== "ok" || page.fullText === undefined && page.truncated,
|
|
120943
|
+
truncated: page.fullText === undefined && page.truncated || text.length < fullText.length
|
|
120919
120944
|
}
|
|
120920
120945
|
];
|
|
120921
120946
|
});
|
|
@@ -120934,10 +120959,11 @@ ${page.text}`).join(`
|
|
|
120934
120959
|
sources,
|
|
120935
120960
|
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.",
|
|
120936
120961
|
...first,
|
|
120962
|
+
fullText: undefined,
|
|
120937
120963
|
status: readable.length ? incomplete ? "partial" : "ok" : "error",
|
|
120938
120964
|
text: evidenceText.slice(0, maxChars),
|
|
120939
120965
|
truncated: evidenceText.length > maxChars || pages.some((page) => page.truncated),
|
|
120940
|
-
pages: pages.map(({ text: _text, ...page }) => page),
|
|
120966
|
+
pages: pages.map(({ text: _text, fullText: _fullText, ...page }) => page),
|
|
120941
120967
|
captionEvidence,
|
|
120942
120968
|
coverage: {
|
|
120943
120969
|
pagesRead: pages.length,
|
|
@@ -120948,10 +120974,10 @@ ${page.text}`).join(`
|
|
|
120948
120974
|
deadlineReached: signal.aborted,
|
|
120949
120975
|
exhaustive: false,
|
|
120950
120976
|
stopReason: signal.aborted ? "deadline" : unvisited.length ? "page_limit" : "links_exhausted",
|
|
120951
|
-
incompleteReads: pages.filter((page) => page.status !== "ok" || page.truncated).map((page) => ({
|
|
120977
|
+
incompleteReads: pages.filter((page) => page.status !== "ok" || page.fullText === undefined && page.truncated).map((page) => ({
|
|
120952
120978
|
url: page.finalUrl,
|
|
120953
120979
|
status: page.status,
|
|
120954
|
-
truncated: page.truncated,
|
|
120980
|
+
truncated: page.fullText === undefined && page.truncated,
|
|
120955
120981
|
error: page.error
|
|
120956
120982
|
}))
|
|
120957
120983
|
},
|
|
@@ -121066,12 +121092,15 @@ var createWebpageReaderClient = (options) => {
|
|
|
121066
121092
|
if (![evidence.links, evidence.images, evidence.media].every(Array.isArray))
|
|
121067
121093
|
throw new Error("Invalid page evidence");
|
|
121068
121094
|
const limit = Math.max(1000, Math.min(input.maxChars ?? 24000, 1e5));
|
|
121095
|
+
const fullText = typeof document2.fullText === "string" ? document2.fullText : document2.text;
|
|
121069
121096
|
return {
|
|
121070
121097
|
status: result.status,
|
|
121071
121098
|
url: input.url,
|
|
121072
121099
|
finalUrl: result.finalUrl,
|
|
121073
121100
|
title: typeof result.title === "string" ? result.title : null,
|
|
121074
|
-
text:
|
|
121101
|
+
text: fullText.slice(0, limit),
|
|
121102
|
+
fullText,
|
|
121103
|
+
originalChars: fullText.length,
|
|
121075
121104
|
method: result.method,
|
|
121076
121105
|
truncated: result.truncated === true || document2.truncated === true || document2.text.length > limit,
|
|
121077
121106
|
fetchedAt: result.fetchedAt,
|
|
@@ -121114,6 +121143,8 @@ var readRAGWebpage = async (options) => {
|
|
|
121114
121143
|
finalUrl,
|
|
121115
121144
|
title,
|
|
121116
121145
|
text: text.slice(0, maxChars),
|
|
121146
|
+
fullText: text,
|
|
121147
|
+
originalChars: text.length,
|
|
121117
121148
|
method,
|
|
121118
121149
|
truncated: text.length > maxChars,
|
|
121119
121150
|
attempts,
|
|
@@ -121453,6 +121484,7 @@ ${prompt}`,
|
|
|
121453
121484
|
const requiredPhrases = input.requiredPhrases ?? (input.queryMode === "task" ? [] : [...input.query.matchAll(/"([^"\n]+)"/gu)].map((match) => match[1]));
|
|
121454
121485
|
const urls = new Set;
|
|
121455
121486
|
const queries = new Set;
|
|
121487
|
+
const discoveredLinks = new Map;
|
|
121456
121488
|
let evidenceChars = 0;
|
|
121457
121489
|
const sourceText = new Map;
|
|
121458
121490
|
const rebalanceEvidence = () => {
|
|
@@ -121464,8 +121496,8 @@ ${prompt}`,
|
|
|
121464
121496
|
const text = sourceText.get(source.url);
|
|
121465
121497
|
const allowance = Math.floor(remaining * weight(source) / remainingWeight);
|
|
121466
121498
|
remainingWeight -= weight(source);
|
|
121467
|
-
source.excerpts = [
|
|
121468
|
-
remaining -= source.excerpts
|
|
121499
|
+
source.excerpts = selectResearchExcerpts(text, allowance, [input.query, ...input.queries ?? []].join(" "));
|
|
121500
|
+
remaining -= source.excerpts.reduce((sum, excerpt) => sum + excerpt.length, 0);
|
|
121469
121501
|
}
|
|
121470
121502
|
evidenceChars = limits.evidenceChars - remaining;
|
|
121471
121503
|
};
|
|
@@ -121524,7 +121556,7 @@ ${prompt}`,
|
|
|
121524
121556
|
const doRead = async (url) => {
|
|
121525
121557
|
if (urls.has(url) || urls.size >= limits.reads)
|
|
121526
121558
|
return;
|
|
121527
|
-
if (!result.searches.some((search) => search.sources.some((source) => source.url === url)))
|
|
121559
|
+
if (!discoveredLinks.has(url) && !result.searches.some((search) => search.sources.some((source) => source.url === url)))
|
|
121528
121560
|
return;
|
|
121529
121561
|
urls.add(url);
|
|
121530
121562
|
const page = await operate("read", () => (config.reader ?? readRAGWebpage)({
|
|
@@ -121537,9 +121569,19 @@ ${prompt}`,
|
|
|
121537
121569
|
if (page.status !== "ok")
|
|
121538
121570
|
result.limitations.push(`Page read ${page.status}: ${url}`);
|
|
121539
121571
|
if (page.text && page.status !== "error") {
|
|
121572
|
+
for (const link of page.evidence.links) {
|
|
121573
|
+
if (discoveredLinks.size >= 64)
|
|
121574
|
+
break;
|
|
121575
|
+
try {
|
|
121576
|
+
const target = validatePublicWebUrl(new URL(link.url, page.finalUrl).href);
|
|
121577
|
+
target.hash = "";
|
|
121578
|
+
if (!discoveredLinks.has(target.href))
|
|
121579
|
+
discoveredLinks.set(target.href, { url: target.href, label: link.label.slice(0, 200), discoveredOn: page.finalUrl });
|
|
121580
|
+
} catch {}
|
|
121581
|
+
}
|
|
121540
121582
|
const prior = result.sources.find((source) => source.url === url);
|
|
121541
121583
|
if (prior) {
|
|
121542
|
-
sourceText.set(prior.url, page.
|
|
121584
|
+
sourceText.set(prior.url, page.fullText ?? page.text);
|
|
121543
121585
|
prior.contentFetchedAt = page.fetchedAt;
|
|
121544
121586
|
prior.metadata = { ...prior.metadata, readFinalUrl: page.finalUrl };
|
|
121545
121587
|
if (page.finalUrl !== prior.url)
|
|
@@ -121575,11 +121617,12 @@ ${prompt}`,
|
|
|
121575
121617
|
break;
|
|
121576
121618
|
let plan;
|
|
121577
121619
|
try {
|
|
121578
|
-
plan = await generate("plan", PlanSchema, "Select follow-up searches for missing evidence and primary-source URLs to read. For current people or roles, seek the organization\u2019s own leadership/about/team pages; testimonials, package authors, and job listings are not staff identity evidence. For policies, read the full policy or agreement to preserve section scope and exceptions. URLs must come from the supplied search results. done means available evidence addresses the requested schema, not merely that some results exist. Return no actions if further work is not useful.", {
|
|
121620
|
+
plan = await generate("plan", PlanSchema, "Select follow-up searches for missing evidence and primary-source URLs to read. For current people or roles, seek the organization\u2019s own leadership/about/team pages; testimonials, package authors, and job listings are not staff identity evidence. For policies, read the full policy or agreement to preserve section scope and exceptions. URLs must come from the supplied search results or discoveredLinks. Discovered links are unread navigation hints, not evidence; read relevant product, pricing, checkout or policy details before concluding information is absent. done means available evidence addresses the requested schema, not merely that some results exist. Return no actions if further work is not useful.", {
|
|
121579
121621
|
query: input.query,
|
|
121580
121622
|
schema: task.schema,
|
|
121581
121623
|
instructions: task.instructions,
|
|
121582
121624
|
sources: result.sources,
|
|
121625
|
+
discoveredLinks: [...discoveredLinks.values()].filter((link) => !urls.has(link.url)),
|
|
121583
121626
|
searched: [...queries],
|
|
121584
121627
|
read: [...urls],
|
|
121585
121628
|
remainingSearches: limits.searches - queries.size,
|
|
@@ -121651,6 +121694,7 @@ ${prompt}`,
|
|
|
121651
121694
|
result.status = result.sources.length ? "partial" : "unavailable";
|
|
121652
121695
|
return result;
|
|
121653
121696
|
} finally {
|
|
121697
|
+
result.documents = result.sources.filter((source) => source.contentFetchedAt).map((source) => ({ sourceId: source.id, url: source.url, text: sourceText.get(source.url) ?? "", originalChars: (sourceText.get(source.url) ?? "").length }));
|
|
121654
121698
|
result.limitations = [...new Set(result.limitations)];
|
|
121655
121699
|
input.onProgress?.({
|
|
121656
121700
|
phase: "complete",
|
|
@@ -122499,5 +122543,5 @@ export {
|
|
|
122499
122543
|
selectResearchMonitorEvents
|
|
122500
122544
|
};
|
|
122501
122545
|
|
|
122502
|
-
//# debugId=
|
|
122546
|
+
//# debugId=B2B2CCEDC66F56B564756E2164756E21
|
|
122503
122547
|
//# sourceMappingURL=index.js.map
|