@xapp/arachne-web-service 1.33.0 → 1.34.1

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.
@@ -0,0 +1,541 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ServiceExtractor = exports.DEFAULT_MAX_INPUT_TOKENS = exports.EXTRACTOR_VERSION = void 0;
13
+ exports.normalizeText = normalizeText;
14
+ /*! Copyright (c) 2026, XAPP AI */
15
+ const stentor_logger_1 = require("stentor-logger");
16
+ const ServiceTaxonomy_1 = require("../taxonomy/ServiceTaxonomy");
17
+ /**
18
+ * Bumped whenever the prompt, schema or normalizer changes, so stored extractions can be compared by version.
19
+ */
20
+ exports.EXTRACTOR_VERSION = "2026-10-30.2";
21
+ /**
22
+ * Default cap on the page text sent to the LLM, in tokens (estimated at four characters a token).
23
+ */
24
+ exports.DEFAULT_MAX_INPUT_TOKENS = 40000;
25
+ const MAX_SECONDARY_TRADES = 3;
26
+ const CLASSIFY_PAGE_CHARS = 3000;
27
+ const CLASSIFY_MAX_TOKENS = 1024;
28
+ const EXTRACT_MAX_TOKENS = 16384;
29
+ const MATCH_MAX_TOKENS = 4096;
30
+ const CHARS_PER_TOKEN = 4;
31
+ const ATTRIBUTE_KINDS = {
32
+ certification: "certifications",
33
+ equipment_type: "equipmentTypes",
34
+ specialty_material: "specialtyMaterials",
35
+ gear: "gear",
36
+ sub_trade: "subTrades",
37
+ };
38
+ const LIST_KINDS = {
39
+ programs: "programs",
40
+ home_warranty_networks: "homeWarrantyNetworks",
41
+ written_reports_certifications: "writtenReportsCertifications",
42
+ languages: "languages",
43
+ };
44
+ const AREA_KINDS = { city: "cities", county: "counties", zip: "zips", radius_miles: "radiusMiles" };
45
+ /**
46
+ * Text as a reader sees it: markdown links, emphasis, escapes and heading underlines removed, quotes and dashes
47
+ * straightened, case and spacing folded.
48
+ */
49
+ function normalizeText(text) {
50
+ return text
51
+ .normalize("NFKC")
52
+ // setext heading underlines, then the backslash escapes turndown adds, e.g. "80123\." for "80123."
53
+ .replace(/^\s*[=-]{3,}\s*$/gm, " ")
54
+ .replace(/\\([\\`*_{}[\]()#+\-.!>~|])/g, "$1")
55
+ .replace(/!?\[([^\]]*)\]\([^)]*\)/g, "$1")
56
+ .replace(/[*_#`>|]/g, " ")
57
+ .replace(/[‘’]/g, "'")
58
+ .replace(/[“”]/g, '"')
59
+ .replace(/[–—]/g, "-")
60
+ .replace(/\s+/g, " ")
61
+ .trim()
62
+ .toLowerCase();
63
+ }
64
+ function evidenceSchema(urls) {
65
+ return {
66
+ type: "array",
67
+ items: {
68
+ type: "object",
69
+ properties: { url: { type: "string", enum: urls }, snippet: { type: "string" } },
70
+ required: ["url", "snippet"],
71
+ additionalProperties: false,
72
+ },
73
+ };
74
+ }
75
+ function objectSchema(properties) {
76
+ return { type: "object", properties, required: Object.keys(properties), additionalProperties: false };
77
+ }
78
+ function arrayOf(properties) {
79
+ return { type: "array", items: objectSchema(properties) };
80
+ }
81
+ const isString = (v) => typeof v === "string";
82
+ const isNumber = (v) => typeof v === "number" && Number.isFinite(v);
83
+ function isEvidence(v) {
84
+ return Array.isArray(v) && v.every((e) => e && isString(e.url) && isString(e.snippet));
85
+ }
86
+ function isArrayOf(v, check) {
87
+ return Array.isArray(v) && v.every((item) => !!item && typeof item === "object" && check(item));
88
+ }
89
+ function isTradeAnswer(v) {
90
+ return (!!v &&
91
+ isString(v.primary_trade) &&
92
+ isNumber(v.confidence) &&
93
+ Array.isArray(v.secondary_trades) &&
94
+ v.secondary_trades.every(isString) &&
95
+ isEvidence(v.evidence));
96
+ }
97
+ function isMatchAnswer(v) {
98
+ return (!!v &&
99
+ isArrayOf(v.matches, (i) => isString(i.value) && isString(i.slug) && isNumber(i.confidence)));
100
+ }
101
+ function isExtractionAnswer(v) {
102
+ const evidenced = (i) => isString(i.value) && isEvidence(i.evidence);
103
+ return (!!v &&
104
+ isArrayOf(v.services, (i) => isString(i.slug) && isNumber(i.confidence) && isEvidence(i.evidence)) &&
105
+ isArrayOf(v.unmapped_services, evidenced) &&
106
+ isArrayOf(v.explicit_exclusions, evidenced) &&
107
+ isArrayOf(v.flags, (i) => isString(i.flag) && typeof i.value === "boolean" && isNumber(i.confidence) && isEvidence(i.evidence)) &&
108
+ isArrayOf(v.attributes, (i) => isString(i.kind) && evidenced(i)) &&
109
+ isArrayOf(v.lists, (i) => isString(i.list) && evidenced(i)) &&
110
+ isArrayOf(v.brands_serviced, evidenced) &&
111
+ isArrayOf(v.service_area, (i) => isString(i.kind) && evidenced(i)));
112
+ }
113
+ const clamp = (n) => Math.min(1, Math.max(0, n));
114
+ /**
115
+ * Reads the pages of a business website and returns the services it advertises in Service Taxonomy terms.
116
+ *
117
+ * LLM calls at temperature 0: a classifier picks the trades from the start of each page (skipped when the trades
118
+ * are given), then the extractor chooses from those trades' advertised jobs. When it leaves services unmapped, a
119
+ * third call matches them against the jobs of every trade, since a site often advertises work outside the trades
120
+ * it was classified in. Each answer must match its JSON schema or it is retried once. Values whose snippet is not
121
+ * on the page they cite are dropped.
122
+ */
123
+ class ServiceExtractor {
124
+ constructor(props) {
125
+ var _a;
126
+ this.provider = props.provider;
127
+ this.taxonomy = (_a = props.taxonomy) !== null && _a !== void 0 ? _a : new ServiceTaxonomy_1.ServiceTaxonomy();
128
+ }
129
+ /**
130
+ * @param pages The pages to read, most important first
131
+ * @returns The extraction, or undefined when no page has text or an LLM answer is unusable after a retry
132
+ */
133
+ extract(pages_1) {
134
+ return __awaiter(this, arguments, void 0, function* (pages, options = {}) {
135
+ var _a, _b;
136
+ const fitted = this.fit(pages.filter((p) => p.markdown.trim()), ((_a = options.maxInputTokens) !== null && _a !== void 0 ? _a : exports.DEFAULT_MAX_INPUT_TOKENS) * CHARS_PER_TOKEN);
137
+ if (fitted.length === 0) {
138
+ (0, stentor_logger_1.log)().info(`No page text to extract services from.`);
139
+ return undefined;
140
+ }
141
+ // Spacing is ignored: the markdown can run words together that the model copies apart
142
+ const squash = (text) => normalizeText(text).replace(/ /g, "");
143
+ const texts = new Map(fitted.map((p) => [p.url, squash(p.markdown)]));
144
+ const rejected = [];
145
+ const onPage = (e) => {
146
+ var _a;
147
+ const snippet = squash(e.snippet);
148
+ return snippet.length >= 3 && !!((_a = texts.get(e.url)) === null || _a === void 0 ? void 0 : _a.includes(snippet));
149
+ };
150
+ const checked = (field, value, evidence) => {
151
+ const kept = evidence.filter(onPage);
152
+ if (kept.length === 0) {
153
+ rejected.push({ field, value, reason: "no_evidence", evidence });
154
+ return undefined;
155
+ }
156
+ return kept;
157
+ };
158
+ const result = {
159
+ taxonomyVersion: this.taxonomy.version,
160
+ extractorVersion: exports.EXTRACTOR_VERSION,
161
+ provider: this.provider.name,
162
+ secondaryTrades: [],
163
+ services: [],
164
+ unmappedServices: [],
165
+ explicitExclusions: [],
166
+ flags: {},
167
+ certifications: [],
168
+ equipmentTypes: [],
169
+ specialtyMaterials: [],
170
+ gear: [],
171
+ subTrades: [],
172
+ programs: [],
173
+ homeWarrantyNetworks: [],
174
+ writtenReportsCertifications: [],
175
+ languages: [],
176
+ brandsServiced: [],
177
+ serviceArea: { cities: [], counties: [], zips: [], radiusMiles: [] },
178
+ pagesRead: fitted.map((p) => p.url),
179
+ rejected,
180
+ extractedAt: new Date().toISOString(),
181
+ };
182
+ let trades = ((_b = options.trades) !== null && _b !== void 0 ? _b : []).filter((t) => this.taxonomy.isTrade(t));
183
+ if (trades.length > 0) {
184
+ result.primaryTrade = { value: trades[0], confidence: 1, evidence: [] };
185
+ result.secondaryTrades = trades.slice(1).map((value) => ({ value, confidence: 1, evidence: [] }));
186
+ }
187
+ else {
188
+ const answer = yield this.ask(this.classifyPrompt(fitted), this.classifySchema(fitted), CLASSIFY_MAX_TOKENS, isTradeAnswer, "services_trades");
189
+ if (!answer) {
190
+ return undefined;
191
+ }
192
+ if (!this.taxonomy.isTrade(answer.primary_trade)) {
193
+ (0, stentor_logger_1.log)().info(`Not a home-services business, no trade found.`);
194
+ return result;
195
+ }
196
+ const evidence = answer.evidence.filter(onPage);
197
+ const secondary = [...new Set(answer.secondary_trades)]
198
+ .filter((t) => t !== answer.primary_trade && this.taxonomy.isTrade(t))
199
+ .slice(0, MAX_SECONDARY_TRADES);
200
+ result.primaryTrade = { value: answer.primary_trade, confidence: clamp(answer.confidence), evidence };
201
+ result.secondaryTrades = secondary.map((value) => ({
202
+ value,
203
+ confidence: clamp(answer.confidence),
204
+ evidence: [],
205
+ }));
206
+ trades = [answer.primary_trade, ...secondary];
207
+ }
208
+ const catalog = this.catalog(trades);
209
+ const answer = yield this.ask(this.extractPrompt(fitted, catalog), this.extractSchema(fitted, catalog), EXTRACT_MAX_TOKENS, isExtractionAnswer, "services_extract");
210
+ if (!answer) {
211
+ return undefined;
212
+ }
213
+ this.normalize(answer, result, checked);
214
+ yield this.matchUnmapped(result);
215
+ (0, stentor_logger_1.log)().info(`Extracted ${result.services.length} services for ${trades.join(", ")} from ${fitted.length} pages, rejected ${rejected.length} values`);
216
+ return result;
217
+ });
218
+ }
219
+ normalize(answer, result, checked) {
220
+ const definitions = serviceLists(this.taxonomy);
221
+ for (const service of answer.services) {
222
+ const job = this.lookup(service.slug);
223
+ if (!job) {
224
+ const evidence = checked("unmappedServices", service.slug, service.evidence);
225
+ if (evidence) {
226
+ result.unmappedServices.push({ value: service.slug, evidence });
227
+ }
228
+ continue;
229
+ }
230
+ if (job.homeowner_only) {
231
+ result.rejected.push({ field: "services", value: service.slug, reason: "homeowner_only" });
232
+ continue;
233
+ }
234
+ const evidence = checked("services", service.slug, service.evidence);
235
+ if (evidence) {
236
+ this.addService(result, job, service.confidence, evidence);
237
+ }
238
+ }
239
+ const push = (field, target, item) => {
240
+ const evidence = checked(field, item.value, item.evidence);
241
+ if (evidence) {
242
+ target.push({ value: item.value, evidence });
243
+ }
244
+ };
245
+ answer.unmapped_services.forEach((item) => push("unmappedServices", result.unmappedServices, item));
246
+ answer.explicit_exclusions.forEach((item) => push("explicitExclusions", result.explicitExclusions, item));
247
+ answer.brands_serviced.forEach((item) => push("brandsServiced", result.brandsServiced, item));
248
+ for (const flag of answer.flags) {
249
+ if (!definitions.flags.includes(flag.flag)) {
250
+ result.rejected.push({ field: "flags", value: flag.flag, reason: "not_in_taxonomy" });
251
+ continue;
252
+ }
253
+ const evidence = checked("flags", flag.flag, flag.evidence);
254
+ if (evidence) {
255
+ result.flags[flag.flag] = { value: flag.value, confidence: clamp(flag.confidence), evidence };
256
+ }
257
+ }
258
+ for (const attribute of answer.attributes) {
259
+ const field = ATTRIBUTE_KINDS[attribute.kind];
260
+ if (!field ||
261
+ !definitions.attributes[attribute.kind].includes(attribute.value)) {
262
+ result.rejected.push({
263
+ field: field !== null && field !== void 0 ? field : "attributes",
264
+ value: attribute.value,
265
+ reason: "not_in_taxonomy",
266
+ });
267
+ continue;
268
+ }
269
+ push(field, result[field], attribute);
270
+ }
271
+ for (const item of answer.lists) {
272
+ const field = LIST_KINDS[item.list];
273
+ if (!field) {
274
+ result.rejected.push({ field: "lists", value: item.value, reason: "not_in_taxonomy" });
275
+ continue;
276
+ }
277
+ push(field, result[field], item);
278
+ }
279
+ for (const item of answer.service_area) {
280
+ const field = AREA_KINDS[item.kind];
281
+ if (!field) {
282
+ result.rejected.push({ field: "serviceArea", value: item.value, reason: "not_in_taxonomy" });
283
+ continue;
284
+ }
285
+ push(`serviceArea.${field}`, result.serviceArea[field], item);
286
+ }
287
+ }
288
+ /**
289
+ * Asks which job of any trade each unmapped service is, and moves the ones that match into services. A match in a
290
+ * trade the business was not classified in adds that trade to the secondary trades. When the answer is unusable
291
+ * the services stay unmapped.
292
+ */
293
+ matchUnmapped(result) {
294
+ return __awaiter(this, void 0, void 0, function* () {
295
+ const values = [...new Set(result.unmappedServices.map((s) => s.value))];
296
+ if (values.length === 0) {
297
+ return;
298
+ }
299
+ const catalog = this.catalog(serviceLists(this.taxonomy).trades);
300
+ const answer = yield this.ask(this.matchPrompt(values, catalog), objectSchema({
301
+ matches: arrayOf({
302
+ value: { type: "string", enum: values },
303
+ slug: { type: "string" },
304
+ confidence: { type: "number" },
305
+ }),
306
+ }), MATCH_MAX_TOKENS, isMatchAnswer, "services_match");
307
+ if (!answer) {
308
+ return;
309
+ }
310
+ for (const match of answer.matches) {
311
+ const job = this.lookup(match.slug);
312
+ if (!job || job.homeowner_only) {
313
+ continue;
314
+ }
315
+ const moved = result.unmappedServices.filter((s) => s.value === match.value);
316
+ if (moved.length === 0) {
317
+ continue;
318
+ }
319
+ result.unmappedServices = result.unmappedServices.filter((s) => s.value !== match.value);
320
+ const evidence = moved.flatMap((s) => s.evidence);
321
+ this.addService(result, job, match.confidence, evidence);
322
+ const known = [result.primaryTrade, ...result.secondaryTrades].some((t) => (t === null || t === void 0 ? void 0 : t.value) === job.trade);
323
+ if (!known) {
324
+ result.secondaryTrades.push({ value: job.trade, confidence: clamp(match.confidence), evidence });
325
+ }
326
+ }
327
+ });
328
+ }
329
+ /**
330
+ * The job or family a slug names, following aliases and deprecations.
331
+ */
332
+ lookup(slug) {
333
+ if (this.taxonomy.isFamily(slug)) {
334
+ return { slug, trade: slug.split(".")[0], family: slug, homeowner_only: false };
335
+ }
336
+ const canonical = this.taxonomy.resolve(slug);
337
+ return canonical ? this.taxonomy.job(canonical) : undefined;
338
+ }
339
+ addService(result, job, confidence, evidence) {
340
+ const existing = result.services.find((s) => s.slug === job.slug);
341
+ if (existing) {
342
+ existing.confidence = Math.max(existing.confidence, clamp(confidence));
343
+ existing.evidence.push(...evidence);
344
+ }
345
+ else {
346
+ result.services.push(Object.assign(Object.assign({ slug: job.slug, trade: job.trade }, (job.family ? { family: job.family } : {})), { confidence: clamp(confidence), evidence }));
347
+ }
348
+ }
349
+ /**
350
+ * Keeps every page, trimming the longest ones until the total fits the budget.
351
+ */
352
+ fit(pages, budgetChars) {
353
+ const lengths = pages.map((p) => p.markdown.length).sort((a, b) => a - b);
354
+ if (lengths.reduce((sum, n) => sum + n, 0) <= budgetChars) {
355
+ return pages;
356
+ }
357
+ // Pages shorter than an even share keep their text and hand what they leave over to the longer ones
358
+ let remaining = budgetChars;
359
+ let cap = 0;
360
+ for (let i = 0; i < lengths.length; i++) {
361
+ cap = Math.floor(remaining / (lengths.length - i));
362
+ if (lengths[i] > cap) {
363
+ break;
364
+ }
365
+ remaining -= lengths[i];
366
+ }
367
+ return pages.map((p) => (p.markdown.length > cap ? Object.assign(Object.assign({}, p), { markdown: p.markdown.slice(0, cap) }) : p));
368
+ }
369
+ pagesBlock(pages, chars) {
370
+ return pages
371
+ .map((p) => `=== PAGE ${p.url} (${p.kind}) ===\n${chars ? p.markdown.slice(0, chars) : p.markdown}`)
372
+ .join("\n\n");
373
+ }
374
+ classifyPrompt(pages) {
375
+ const trades = serviceLists(this.taxonomy).trades.join(", ");
376
+ return `You read the start of each page of a business website and decide which home-service trades the business works in.
377
+
378
+ Trades: ${trades}
379
+
380
+ Rules:
381
+ - primary_trade is the trade most of its services belong to, or "none" when it is not a home-services business (e.g. a spa, a retailer, a software company).
382
+ - secondary_trades are other trades it clearly advertises, at most ${MAX_SECONDARY_TRADES}.
383
+ - evidence is one or two snippets copied exactly from the pages that show the primary trade.
384
+
385
+ ${this.pagesBlock(pages, CLASSIFY_PAGE_CHARS)}`;
386
+ }
387
+ classifySchema(pages) {
388
+ const trades = serviceLists(this.taxonomy).trades;
389
+ return objectSchema({
390
+ primary_trade: { type: "string", enum: [...trades, "none"] },
391
+ confidence: { type: "number" },
392
+ secondary_trades: { type: "array", items: { type: "string", enum: trades } },
393
+ evidence: evidenceSchema(pages.map((p) => p.url)),
394
+ });
395
+ }
396
+ /**
397
+ * The slugs the extractor may choose for the trades: each family, for a service advertised in general terms,
398
+ * followed by its advertised jobs, then the jobs that sit directly under a trade.
399
+ */
400
+ catalog(trades) {
401
+ var _a, _b;
402
+ const jobs = this.taxonomy.extractableJobs(trades);
403
+ const entries = [];
404
+ for (const trade of this.taxonomy.definition.trades.filter((t) => trades.includes(t.slug))) {
405
+ for (const family of (_a = trade.families) !== null && _a !== void 0 ? _a : []) {
406
+ entries.push({ slug: family.slug, general: true, terms: (_b = family.website_terms) !== null && _b !== void 0 ? _b : [] });
407
+ jobs.filter((j) => j.family === family.slug).forEach((j) => { var _a; return entries.push({ slug: j.slug, terms: (_a = j.synonyms) !== null && _a !== void 0 ? _a : [] }); });
408
+ }
409
+ jobs.filter((j) => j.trade === trade.slug && !j.family).forEach((j) => { var _a; return entries.push({ slug: j.slug, terms: (_a = j.synonyms) !== null && _a !== void 0 ? _a : [] }); });
410
+ }
411
+ return entries;
412
+ }
413
+ catalogText(catalog) {
414
+ return catalog
415
+ .map((e) => `- ${e.slug}${e.general ? " (general)" : ""}${e.terms.length ? `: ${e.terms.join("; ")}` : ""}`)
416
+ .join("\n");
417
+ }
418
+ matchPrompt(values, catalog) {
419
+ return `A home-services business website advertises the services below, worded as the site words them. For each one, give the catalog slug for the same job, or "none" when no slug is the same job. Do not pick a broader, narrower or merely related job. A slug marked (general) is for a service named only in general terms, e.g. "AC repair".
420
+
421
+ Services:
422
+ ${values.map((v) => `- ${v}`).join("\n")}
423
+
424
+ Catalog (slug: words customers and websites use):
425
+ ${this.catalogText(catalog)}`;
426
+ }
427
+ extractPrompt(pages, catalog) {
428
+ const lists = serviceLists(this.taxonomy);
429
+ const catalogText = this.catalogText(catalog);
430
+ const flags = this.taxonomy.definition.capability_flags
431
+ .map((f) => `- ${f.slug}: ${f.definition}`)
432
+ .join("\n");
433
+ const listDefs = this.taxonomy.definition.capability_lists
434
+ .map((l) => `- ${l.slug}: ${l.definition}`)
435
+ .join("\n");
436
+ const attributes = Object.entries(lists.attributes)
437
+ .map(([kind, values]) => `- ${kind}: ${values.join(", ")}`)
438
+ .join("\n");
439
+ return `You read the pages of a home-services business website and list what the business advertises, using the catalog below.
440
+
441
+ Every value needs evidence: the URL of the page it is on and a snippet copied exactly, word for word, from that page (5 to 25 words). No evidence, no value. Do not infer, guess or generalise.
442
+
443
+ - services: catalog slugs for jobs the business says it performs. Pick the most specific slug the page supports; a slug marked (general) is for a service the site advertises only in general terms, e.g. "AC repair". Anything the business offers that has no catalog slug goes in unmapped_services, worded as the site words it.
444
+ - explicit_exclusions: anything the site says it does not do.
445
+ - flags: include a flag only when the pages state it. value is false only when the site says the opposite. Leave out flags the pages do not mention.
446
+ - attributes: certifications, equipment types, specialty materials, gear and sub-trade specialisms from the lists below that the pages name.
447
+ - lists: financing programs, home warranty networks, written reports and languages the pages name, as free text.
448
+ - brands_serviced: equipment or product brands the business installs or services.
449
+ - service_area: cities, counties, ZIP codes, or a radius in miles that the business says it serves.
450
+
451
+ Catalog (slug: words customers and websites use):
452
+ ${catalogText}
453
+
454
+ Flags:
455
+ ${flags}
456
+
457
+ Attributes:
458
+ ${attributes}
459
+
460
+ Lists:
461
+ ${listDefs}
462
+
463
+ ${this.pagesBlock(pages)}`;
464
+ }
465
+ extractSchema(pages, catalog) {
466
+ const lists = serviceLists(this.taxonomy);
467
+ const evidence = evidenceSchema(pages.map((p) => p.url));
468
+ const valued = (extra = {}) => arrayOf(Object.assign(Object.assign({}, extra), { value: { type: "string" }, evidence }));
469
+ const attributeValues = [...new Set(Object.values(lists.attributes).flat())];
470
+ return objectSchema({
471
+ services: arrayOf({
472
+ slug: { type: "string", enum: catalog.map((e) => e.slug) },
473
+ confidence: { type: "number" },
474
+ evidence,
475
+ }),
476
+ unmapped_services: valued(),
477
+ explicit_exclusions: valued(),
478
+ flags: arrayOf({
479
+ flag: { type: "string", enum: lists.flags },
480
+ value: { type: "boolean" },
481
+ confidence: { type: "number" },
482
+ evidence,
483
+ }),
484
+ attributes: arrayOf({
485
+ kind: { type: "string", enum: Object.keys(ATTRIBUTE_KINDS) },
486
+ value: { type: "string", enum: attributeValues },
487
+ evidence,
488
+ }),
489
+ lists: valued({ list: { type: "string", enum: Object.keys(LIST_KINDS) } }),
490
+ brands_serviced: valued(),
491
+ service_area: valued({ kind: { type: "string", enum: Object.keys(AREA_KINDS) } }),
492
+ });
493
+ }
494
+ /**
495
+ * Calls the LLM and checks the answer's shape, retrying once.
496
+ */
497
+ ask(prompt, jsonSchema, maxTokens, check, label) {
498
+ return __awaiter(this, void 0, void 0, function* () {
499
+ for (let attempt = 1; attempt <= 2; attempt++) {
500
+ const text = yield this.provider.complete({
501
+ prompt,
502
+ jsonSchema,
503
+ maxTokens,
504
+ temperature: 0,
505
+ label: `${label}_${attempt}`,
506
+ });
507
+ let parsed;
508
+ try {
509
+ parsed = text === undefined ? undefined : JSON.parse(text);
510
+ }
511
+ catch (_a) {
512
+ parsed = undefined;
513
+ }
514
+ if (check(parsed)) {
515
+ return parsed;
516
+ }
517
+ (0, stentor_logger_1.log)().warn(`${label}: answer ${text === undefined ? "missing" : "does not match the schema"} on attempt ${attempt}`);
518
+ }
519
+ return undefined;
520
+ });
521
+ }
522
+ }
523
+ exports.ServiceExtractor = ServiceExtractor;
524
+ /**
525
+ * The enumerations the prompts and schemas offer.
526
+ */
527
+ function serviceLists(taxonomy) {
528
+ const d = taxonomy.definition;
529
+ return {
530
+ trades: d.trades.map((t) => t.slug),
531
+ flags: d.capability_flags.map((f) => f.slug),
532
+ attributes: {
533
+ certification: d.certifications,
534
+ equipment_type: d.equipment_types,
535
+ specialty_material: d.specialty_materials,
536
+ gear: d.gear,
537
+ sub_trade: d.sub_trades,
538
+ },
539
+ };
540
+ }
541
+ //# sourceMappingURL=ServiceExtractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ServiceExtractor.js","sourceRoot":"","sources":["../../src/services/ServiceExtractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { SubpageTab } from "../utils/subpageDetection";
2
+ import { ServicePage } from "./selectServicePages";
3
+ import { ServicePageText } from "./ServiceExtractor";
4
+ export interface ReadServicePagesProps {
5
+ /**
6
+ * Opens a new tab with the crawler's page setup.
7
+ */
8
+ openTab: () => Promise<SubpageTab>;
9
+ homepageUrl: string;
10
+ /**
11
+ * Pages to read, in order. The homepage is not visited again.
12
+ */
13
+ targets: ServicePage[];
14
+ /**
15
+ * Converts a page's HTML to the markdown sent to the LLM.
16
+ */
17
+ toMarkdown: (html: string) => string;
18
+ /**
19
+ * Budget for each page.
20
+ */
21
+ pageTimeoutMs: number;
22
+ /**
23
+ * No page is started after this time (epoch ms).
24
+ */
25
+ deadline: number;
26
+ /**
27
+ * HTML of pages already loaded during the crawl, by URL. These are not visited again.
28
+ */
29
+ loaded?: Map<string, string>;
30
+ }
31
+ /**
32
+ * Loads each target on its own tab, in order, and returns its text.
33
+ *
34
+ * A page that errors, times out or redirects off-site is skipped. Pages are not started once the deadline is
35
+ * near.
36
+ */
37
+ export declare function readServicePages(props: ReadServicePagesProps): Promise<ServicePageText[]>;