@absolutejs/rag 0.22.12 → 0.22.13
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 +10 -0
- package/changelog.json +21 -0
- package/dist/research/index.js +93 -12
- package/dist/research/index.js.map +4 -4
- package/dist/src/research/types.d.ts +16 -0
- package/dist/web/index.js +2 -2
- package/dist/web/index.js.map +3 -3
- package/dist/web-index/index.js +93 -12
- package/dist/web-index/index.js.map +4 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,16 @@ 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.22.13 — 2026-10-31
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **Track evidence-backed collection coverage independently of execution completion** (`ResearchTask`, `ResearchResult`)
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **Continue research after inaccessible sources without hiding accounting failures; preserve typed reader reasons and remove duplicated review context** (`createResearch`)
|
|
18
|
+
|
|
9
19
|
## 0.22.12 — 2026-10-29
|
|
10
20
|
|
|
11
21
|
### Fixed
|
package/changelog.json
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
"contract": 1,
|
|
3
3
|
"name": "@absolutejs/rag",
|
|
4
4
|
"releases": [
|
|
5
|
+
{
|
|
6
|
+
"changes": [
|
|
7
|
+
{
|
|
8
|
+
"kind": "fixed",
|
|
9
|
+
"summary": "Continue research after inaccessible sources without hiding accounting failures; preserve typed reader reasons and remove duplicated review context",
|
|
10
|
+
"symbols": [
|
|
11
|
+
"createResearch"
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"kind": "added",
|
|
16
|
+
"summary": "Track evidence-backed collection coverage independently of execution completion",
|
|
17
|
+
"symbols": [
|
|
18
|
+
"ResearchTask",
|
|
19
|
+
"ResearchResult"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"date": "2026-10-31",
|
|
24
|
+
"version": "0.22.13"
|
|
25
|
+
},
|
|
5
26
|
{
|
|
6
27
|
"changes": [
|
|
7
28
|
{
|
package/dist/research/index.js
CHANGED
|
@@ -121780,7 +121780,7 @@ var createWebpageReaderClient = (options) => {
|
|
|
121780
121780
|
});
|
|
121781
121781
|
if (result.status === "error") {
|
|
121782
121782
|
const error = result.error;
|
|
121783
|
-
throw new
|
|
121783
|
+
throw new WebReadError(error?.code ?? "reader_unavailable", error?.message ?? "Isolated page read failed");
|
|
121784
121784
|
}
|
|
121785
121785
|
const documents = result.documents;
|
|
121786
121786
|
const sources = result.sources;
|
|
@@ -122119,6 +122119,8 @@ var createResearch = (config) => {
|
|
|
122119
122119
|
const extract = async (task, input) => {
|
|
122120
122120
|
if (!input.query.trim() || input.query.length > 8000)
|
|
122121
122121
|
throw new Error("Research query must contain 1\u20138000 characters");
|
|
122122
|
+
if (task.collection && (!/^\/(?:[^~]|~[01])+$/.test(task.collection.path) || !Number.isSafeInteger(task.collection.minimum) || task.collection.minimum < 1 || !task.collection.requiredFields.length || task.collection.requiredFields.some((key) => !key || key.includes("/"))))
|
|
122123
|
+
throw new Error("Invalid research collection requirement");
|
|
122122
122124
|
const signal = AbortSignal.any([
|
|
122123
122125
|
AbortSignal.timeout(limits.timeoutMs),
|
|
122124
122126
|
...input.signal ? [input.signal] : []
|
|
@@ -122132,7 +122134,14 @@ var createResearch = (config) => {
|
|
|
122132
122134
|
searches: [],
|
|
122133
122135
|
limitations: [],
|
|
122134
122136
|
generatedAt: new Date().toISOString(),
|
|
122135
|
-
operations: []
|
|
122137
|
+
operations: [],
|
|
122138
|
+
...task.collection ? {
|
|
122139
|
+
coverage: {
|
|
122140
|
+
requested: task.collection.minimum,
|
|
122141
|
+
supported: 0,
|
|
122142
|
+
complete: false
|
|
122143
|
+
}
|
|
122144
|
+
} : {}
|
|
122136
122145
|
};
|
|
122137
122146
|
const operationLimit = limits.searches + limits.reads + limits.rounds + 2 + 2 * validationRepairs;
|
|
122138
122147
|
const operate = async (kind, call, usage = () => ({})) => {
|
|
@@ -122305,16 +122314,68 @@ Correct the previous schema-invalid response using the validation diagnostics. T
|
|
|
122305
122314
|
if (!discoveredLinks.has(url) && !result.searches.some((search) => search.sources.some((source) => source.url === url)))
|
|
122306
122315
|
return;
|
|
122307
122316
|
urls.add(url);
|
|
122308
|
-
const page = await operate("read", () =>
|
|
122309
|
-
|
|
122310
|
-
|
|
122311
|
-
|
|
122312
|
-
|
|
122313
|
-
|
|
122317
|
+
const page = await operate("read", async () => {
|
|
122318
|
+
try {
|
|
122319
|
+
return await (config.reader ?? readRAGWebpage)({
|
|
122320
|
+
url,
|
|
122321
|
+
signal,
|
|
122322
|
+
render: config.render,
|
|
122323
|
+
maxChars: Math.min(limits.evidenceChars, 24000)
|
|
122324
|
+
});
|
|
122325
|
+
} catch (error) {
|
|
122326
|
+
signal.throwIfAborted();
|
|
122327
|
+
const messages = {
|
|
122328
|
+
access_blocked: "Website blocked automated access",
|
|
122329
|
+
authentication_required: "Page requires sign-in",
|
|
122330
|
+
http_error: "Page returned an HTTP error",
|
|
122331
|
+
reader_unavailable: "Website reader unavailable",
|
|
122332
|
+
fetch_failed: "Page could not be retrieved",
|
|
122333
|
+
timeout: "Page retrieval timed out"
|
|
122334
|
+
};
|
|
122335
|
+
if (!(error instanceof WebReadError) || !messages[error.code])
|
|
122336
|
+
throw error;
|
|
122337
|
+
return {
|
|
122338
|
+
status: "error",
|
|
122339
|
+
url,
|
|
122340
|
+
finalUrl: url,
|
|
122341
|
+
title: null,
|
|
122342
|
+
text: "",
|
|
122343
|
+
method: "http",
|
|
122344
|
+
truncated: false,
|
|
122345
|
+
attempts: [],
|
|
122346
|
+
fetchedAt: new Date().toISOString(),
|
|
122347
|
+
redirects: [],
|
|
122348
|
+
evidence: { links: [], images: [], media: [], canonicalUrl: null },
|
|
122349
|
+
limitations: [],
|
|
122350
|
+
error: { code: error.code, message: messages[error.code] }
|
|
122351
|
+
};
|
|
122352
|
+
}
|
|
122353
|
+
});
|
|
122354
|
+
if (page.status === "error") {
|
|
122355
|
+
const code = page.error?.code ?? "read_failed";
|
|
122356
|
+
if ([
|
|
122357
|
+
"unsafe_url",
|
|
122358
|
+
"blocked_address",
|
|
122359
|
+
"blocked_url",
|
|
122360
|
+
"invalid_url"
|
|
122361
|
+
].includes(code))
|
|
122362
|
+
throw new WebReadError(code, "Unsafe research source URL");
|
|
122363
|
+
const message = "Source unavailable (" + code + ")";
|
|
122364
|
+
(result.sourceFailures ??= []).push({ url, code, message });
|
|
122365
|
+
result.limitations.push(`${message}: ${url}`);
|
|
122366
|
+
try {
|
|
122367
|
+
config.onError?.({
|
|
122368
|
+
runId: result.id,
|
|
122369
|
+
phase: "read",
|
|
122370
|
+
error: new WebReadError(code, message)
|
|
122371
|
+
});
|
|
122372
|
+
} catch {}
|
|
122373
|
+
return;
|
|
122374
|
+
}
|
|
122314
122375
|
result.limitations.push(...page.limitations);
|
|
122315
122376
|
if (page.status !== "ok")
|
|
122316
122377
|
result.limitations.push(`Page read ${page.status}: ${url}`);
|
|
122317
|
-
if (page.text
|
|
122378
|
+
if (page.text) {
|
|
122318
122379
|
for (const link of page.evidence.links) {
|
|
122319
122380
|
if (discoveredLinks.size >= 64)
|
|
122320
122381
|
break;
|
|
@@ -122351,7 +122412,7 @@ Correct the previous schema-invalid response using the validation diagnostics. T
|
|
|
122351
122412
|
try {
|
|
122352
122413
|
const needsInitialPlan = !input.queries && (input.queryMode === "task" || boundedQueries(input.query).length > 1) && limits.rounds > 0;
|
|
122353
122414
|
if (needsInitialPlan) {
|
|
122354
|
-
const initial = await generate("plan", PlanSchema, "Turn the research task into concise search-engine queries. Preserve the requested company identity and target criteria, but never copy instructions, JSON, internal markers, or the whole brief into a query. Prioritize the most useful query first. Return at most remainingSearches queries. Return no URLs: source URLs must be discovered rather than invented.", {
|
|
122415
|
+
const initial = await generate("plan", PlanSchema, "Turn the research task into concise search-engine queries. Search for the requested answer entities, not merely the client named in the brief. For new partners, pursue external candidate companies across the requested categories; client background and existing partnerships do not fulfill that task. Preserve the requested company identity and target criteria, but never copy instructions, JSON, internal markers, or the whole brief into a query. Prioritize the most useful query first. Return at most remainingSearches queries. Return no URLs: source URLs must be discovered rather than invented.", {
|
|
122355
122416
|
query: input.query,
|
|
122356
122417
|
instructions: task.instructions,
|
|
122357
122418
|
remainingSearches: limits.searches
|
|
@@ -122417,12 +122478,32 @@ Correct the previous schema-invalid response using the validation diagnostics. T
|
|
|
122417
122478
|
instructions: task.instructions,
|
|
122418
122479
|
schema: task.schema,
|
|
122419
122480
|
fields: leaves,
|
|
122420
|
-
sources: reviewSources
|
|
122481
|
+
sources: reviewSources.map(({ passages, ...source }) => ({
|
|
122482
|
+
...source,
|
|
122483
|
+
passages: passages.map(({ id, text }) => ({ id, text }))
|
|
122484
|
+
}))
|
|
122421
122485
|
});
|
|
122422
122486
|
result.fields = bindResearchReview(leaves, reviewed.fields.map((field) => ({
|
|
122423
122487
|
...field,
|
|
122424
122488
|
citations: resolveResearchPassages(field.citations, reviewSources)
|
|
122425
122489
|
})), result.sources);
|
|
122490
|
+
if (task.collection) {
|
|
122491
|
+
const { path, minimum, requiredFields } = task.collection;
|
|
122492
|
+
const indices = new Set(result.fields.flatMap((field) => {
|
|
122493
|
+
if (!field.path.startsWith(path + "/"))
|
|
122494
|
+
return [];
|
|
122495
|
+
const index = field.path.slice(path.length + 1).split("/")[0];
|
|
122496
|
+
return /^\d+$/.test(index) ? [index] : [];
|
|
122497
|
+
}));
|
|
122498
|
+
const supported = [...indices].filter((index) => requiredFields.every((key) => result.fields.some((field) => field.path === `${path}/${index}/${key}` && field.verdict === "supported" && field.value !== null && field.value !== ""))).length;
|
|
122499
|
+
result.coverage = {
|
|
122500
|
+
requested: minimum,
|
|
122501
|
+
supported,
|
|
122502
|
+
complete: supported >= minimum
|
|
122503
|
+
};
|
|
122504
|
+
if (!result.coverage.complete)
|
|
122505
|
+
result.limitations.push(`Requested ${minimum} evidence-backed items; established ${supported}.`);
|
|
122506
|
+
}
|
|
122426
122507
|
const complete = result.fields.length > 0 && result.fields.every((field) => field.verdict === "supported");
|
|
122427
122508
|
result.data = complete ? data : null;
|
|
122428
122509
|
result.status = complete && !result.limitations.length ? "reviewed" : "partial";
|
|
@@ -123298,5 +123379,5 @@ export {
|
|
|
123298
123379
|
selectResearchMonitorEvents
|
|
123299
123380
|
};
|
|
123300
123381
|
|
|
123301
|
-
//# debugId=
|
|
123382
|
+
//# debugId=44DB610A26179E0164756E2164756E21
|
|
123302
123383
|
//# sourceMappingURL=index.js.map
|