@absolutejs/rag 0.22.12 → 0.22.14

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.
@@ -114902,15 +114902,18 @@ import {
114902
114902
  import { lookup } from "dns/promises";
114903
114903
  import { isIP } from "net";
114904
114904
  import { brotliDecompressSync, gunzipSync, inflateSync } from "zlib";
114905
+ var WEB_READ_ERROR = Symbol.for("@absolutejs/rag/WebReadError");
114905
114906
 
114906
114907
  class WebReadError extends Error {
114907
114908
  code;
114909
+ [WEB_READ_ERROR] = true;
114908
114910
  constructor(code, message) {
114909
114911
  super(message);
114910
114912
  this.code = code;
114911
114913
  this.name = "WebReadError";
114912
114914
  }
114913
114915
  }
114916
+ var isWebReadError = (error) => error instanceof Error && Reflect.get(error, WEB_READ_ERROR) === true && typeof Reflect.get(error, "code") === "string";
114914
114917
  var isPublicWebAddress = (address) => isPublicNetworkAddress(address);
114915
114918
  var validatePublicWebUrl = (raw) => {
114916
114919
  let url;
@@ -121780,7 +121783,7 @@ var createWebpageReaderClient = (options) => {
121780
121783
  });
121781
121784
  if (result.status === "error") {
121782
121785
  const error = result.error;
121783
- throw new Error(error?.message ?? "Isolated page read failed");
121786
+ throw new WebReadError(error?.code ?? "reader_unavailable", error?.message ?? "Isolated page read failed");
121784
121787
  }
121785
121788
  const documents = result.documents;
121786
121789
  const sources = result.sources;
@@ -121814,7 +121817,7 @@ var createWebpageReaderClient = (options) => {
121814
121817
 
121815
121818
  // src/web/index.ts
121816
121819
  var messageFor = (error) => error instanceof Error ? error.message : "Website retrieval failed.";
121817
- var codeFor = (error) => error instanceof WebReadError ? error.code : error instanceof Error && /^(?:AbortError|TimeoutError)$/u.test(error.name) ? "timeout" : "fetch_failed";
121820
+ var codeFor = (error) => isWebReadError(error) ? error.code : error instanceof Error && /^(?:AbortError|TimeoutError)$/u.test(error.name) ? "timeout" : "fetch_failed";
121818
121821
  var cleanHtml = websiteHtmlText;
121819
121822
  var titleOf = (html) => {
121820
121823
  const title = /<title\b[^>]*>([\s\S]*?)<\/title>/iu.exec(html)?.[1];
@@ -121861,7 +121864,7 @@ var readRAGWebpage = async (options) => {
121861
121864
  response = await (options.fetchResource ?? fetchPublicWebResource)(options.url, { signal, maxBytes: 5000000 });
121862
121865
  } catch (error) {
121863
121866
  attempts.push({ method: "http", status: codeFor(error) });
121864
- if (error instanceof WebReadError && error.code === "blocked_url")
121867
+ if (isWebReadError(error) && error.code === "blocked_url")
121865
121868
  throw error;
121866
121869
  if (!options.render)
121867
121870
  throw error;
@@ -122119,6 +122122,8 @@ var createResearch = (config) => {
122119
122122
  const extract = async (task, input) => {
122120
122123
  if (!input.query.trim() || input.query.length > 8000)
122121
122124
  throw new Error("Research query must contain 1\u20138000 characters");
122125
+ 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("/"))))
122126
+ throw new Error("Invalid research collection requirement");
122122
122127
  const signal = AbortSignal.any([
122123
122128
  AbortSignal.timeout(limits.timeoutMs),
122124
122129
  ...input.signal ? [input.signal] : []
@@ -122132,7 +122137,14 @@ var createResearch = (config) => {
122132
122137
  searches: [],
122133
122138
  limitations: [],
122134
122139
  generatedAt: new Date().toISOString(),
122135
- operations: []
122140
+ operations: [],
122141
+ ...task.collection ? {
122142
+ coverage: {
122143
+ requested: task.collection.minimum,
122144
+ supported: 0,
122145
+ complete: false
122146
+ }
122147
+ } : {}
122136
122148
  };
122137
122149
  const operationLimit = limits.searches + limits.reads + limits.rounds + 2 + 2 * validationRepairs;
122138
122150
  const operate = async (kind, call, usage = () => ({})) => {
@@ -122305,16 +122317,68 @@ Correct the previous schema-invalid response using the validation diagnostics. T
122305
122317
  if (!discoveredLinks.has(url) && !result.searches.some((search) => search.sources.some((source) => source.url === url)))
122306
122318
  return;
122307
122319
  urls.add(url);
122308
- const page = await operate("read", () => (config.reader ?? readRAGWebpage)({
122309
- url,
122310
- signal,
122311
- render: config.render,
122312
- maxChars: Math.min(limits.evidenceChars, 24000)
122313
- }));
122320
+ const page = await operate("read", async () => {
122321
+ try {
122322
+ return await (config.reader ?? readRAGWebpage)({
122323
+ url,
122324
+ signal,
122325
+ render: config.render,
122326
+ maxChars: Math.min(limits.evidenceChars, 24000)
122327
+ });
122328
+ } catch (error) {
122329
+ signal.throwIfAborted();
122330
+ const messages = {
122331
+ access_blocked: "Website blocked automated access",
122332
+ authentication_required: "Page requires sign-in",
122333
+ http_error: "Page returned an HTTP error",
122334
+ reader_unavailable: "Website reader unavailable",
122335
+ fetch_failed: "Page could not be retrieved",
122336
+ timeout: "Page retrieval timed out"
122337
+ };
122338
+ if (!isWebReadError(error) || !messages[error.code])
122339
+ throw error;
122340
+ return {
122341
+ status: "error",
122342
+ url,
122343
+ finalUrl: url,
122344
+ title: null,
122345
+ text: "",
122346
+ method: "http",
122347
+ truncated: false,
122348
+ attempts: [],
122349
+ fetchedAt: new Date().toISOString(),
122350
+ redirects: [],
122351
+ evidence: { links: [], images: [], media: [], canonicalUrl: null },
122352
+ limitations: [],
122353
+ error: { code: error.code, message: messages[error.code] }
122354
+ };
122355
+ }
122356
+ });
122357
+ if (page.status === "error") {
122358
+ const code = page.error?.code ?? "read_failed";
122359
+ if ([
122360
+ "unsafe_url",
122361
+ "blocked_address",
122362
+ "blocked_url",
122363
+ "invalid_url"
122364
+ ].includes(code))
122365
+ throw new WebReadError(code, "Unsafe research source URL");
122366
+ const message = "Source unavailable (" + code + ")";
122367
+ (result.sourceFailures ??= []).push({ url, code, message });
122368
+ result.limitations.push(`${message}: ${url}`);
122369
+ try {
122370
+ config.onError?.({
122371
+ runId: result.id,
122372
+ phase: "read",
122373
+ error: new WebReadError(code, message)
122374
+ });
122375
+ } catch {}
122376
+ return;
122377
+ }
122314
122378
  result.limitations.push(...page.limitations);
122315
122379
  if (page.status !== "ok")
122316
122380
  result.limitations.push(`Page read ${page.status}: ${url}`);
122317
- if (page.text && page.status !== "error") {
122381
+ if (page.text) {
122318
122382
  for (const link of page.evidence.links) {
122319
122383
  if (discoveredLinks.size >= 64)
122320
122384
  break;
@@ -122351,7 +122415,7 @@ Correct the previous schema-invalid response using the validation diagnostics. T
122351
122415
  try {
122352
122416
  const needsInitialPlan = !input.queries && (input.queryMode === "task" || boundedQueries(input.query).length > 1) && limits.rounds > 0;
122353
122417
  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.", {
122418
+ 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
122419
  query: input.query,
122356
122420
  instructions: task.instructions,
122357
122421
  remainingSearches: limits.searches
@@ -122417,12 +122481,32 @@ Correct the previous schema-invalid response using the validation diagnostics. T
122417
122481
  instructions: task.instructions,
122418
122482
  schema: task.schema,
122419
122483
  fields: leaves,
122420
- sources: reviewSources
122484
+ sources: reviewSources.map(({ passages, ...source }) => ({
122485
+ ...source,
122486
+ passages: passages.map(({ id, text }) => ({ id, text }))
122487
+ }))
122421
122488
  });
122422
122489
  result.fields = bindResearchReview(leaves, reviewed.fields.map((field) => ({
122423
122490
  ...field,
122424
122491
  citations: resolveResearchPassages(field.citations, reviewSources)
122425
122492
  })), result.sources);
122493
+ if (task.collection) {
122494
+ const { path, minimum, requiredFields } = task.collection;
122495
+ const indices = new Set(result.fields.flatMap((field) => {
122496
+ if (!field.path.startsWith(path + "/"))
122497
+ return [];
122498
+ const index = field.path.slice(path.length + 1).split("/")[0];
122499
+ return /^\d+$/.test(index) ? [index] : [];
122500
+ }));
122501
+ 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;
122502
+ result.coverage = {
122503
+ requested: minimum,
122504
+ supported,
122505
+ complete: supported >= minimum
122506
+ };
122507
+ if (!result.coverage.complete)
122508
+ result.limitations.push(`Requested ${minimum} evidence-backed items; established ${supported}.`);
122509
+ }
122426
122510
  const complete = result.fields.length > 0 && result.fields.every((field) => field.verdict === "supported");
122427
122511
  result.data = complete ? data : null;
122428
122512
  result.status = complete && !result.limitations.length ? "reviewed" : "partial";
@@ -123298,5 +123382,5 @@ export {
123298
123382
  selectResearchMonitorEvents
123299
123383
  };
123300
123384
 
123301
- //# debugId=A230972C656C21A464756E2164756E21
123385
+ //# debugId=7CFBFAA05587CF8964756E2164756E21
123302
123386
  //# sourceMappingURL=index.js.map