alys-akusa 0.1.20 → 0.1.22
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/README.md +27 -0
- package/dist/index.cjs +417 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,6 +51,8 @@ answer support, grounding, hallucination risk, and regressions.
|
|
|
51
51
|
|
|
52
52
|
## Local Development
|
|
53
53
|
|
|
54
|
+
Do not publish to npm for normal testing. Use the repo CLI directly first:
|
|
55
|
+
|
|
54
56
|
```bash
|
|
55
57
|
pnpm install
|
|
56
58
|
pnpm alys -- audit ./knowledge-base --yes
|
|
@@ -61,3 +63,28 @@ pnpm alys -- prepare ./docs --profile all --yes
|
|
|
61
63
|
pnpm alys -- ingest ./knowledge-base --profile rag,embeddings,eval --yes
|
|
62
64
|
pnpm alys -- finetune-ready ./tickets --profile openai,anthropic,qa --yes
|
|
63
65
|
```
|
|
66
|
+
|
|
67
|
+
Recommended pre-publish loop:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pnpm cli:test
|
|
71
|
+
pnpm cli:smoke:local
|
|
72
|
+
pnpm cli:pack
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`pnpm cli:smoke:local` does not call the hosted generation API. It audits the repo
|
|
76
|
+
docs folder and writes disposable artifacts to `./.alys-test`.
|
|
77
|
+
|
|
78
|
+
Use the API smoke only when you explicitly want to test the live hosted generation
|
|
79
|
+
path with a tiny run:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pnpm cli:smoke:api
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Only after those pass should you publish:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
cd apps/cli
|
|
89
|
+
npm publish --access public
|
|
90
|
+
```
|
package/dist/index.cjs
CHANGED
|
@@ -5074,7 +5074,7 @@ async function discoverResearchSources(topic, options = {}) {
|
|
|
5074
5074
|
const searches = await Promise.allSettled(
|
|
5075
5075
|
activeProviders.flatMap(
|
|
5076
5076
|
(provider) => queries.map(async (query) => {
|
|
5077
|
-
const results = await provider.search(query, { limit: Math.max(
|
|
5077
|
+
const results = await provider.search(query, { limit: Math.max(12, Math.ceil(limit / queries.length) + 6), timeoutMs: SEARCH_TIMEOUT_MS });
|
|
5078
5078
|
return results.map((result) => ({ ...result, query, provider: result.provider || provider.name }));
|
|
5079
5079
|
})
|
|
5080
5080
|
)
|
|
@@ -5091,7 +5091,7 @@ async function discoverResearchSources(topic, options = {}) {
|
|
|
5091
5091
|
const fallback = new LocalHeuristicSearchProvider(options.seed ?? 0);
|
|
5092
5092
|
warnings.push("No configured search provider returned results; used local heuristic source candidates.");
|
|
5093
5093
|
for (const query of queries) {
|
|
5094
|
-
rawResults.push(...await fallback.search(query, { limit: Math.max(
|
|
5094
|
+
rawResults.push(...await fallback.search(query, { limit: Math.max(12, Math.ceil(limit / queries.length) + 6) }));
|
|
5095
5095
|
}
|
|
5096
5096
|
}
|
|
5097
5097
|
const deduped = dedupeSearchResults(rawResults);
|
|
@@ -5103,12 +5103,12 @@ async function discoverResearchSources(topic, options = {}) {
|
|
|
5103
5103
|
warnings.push("No search result passed Alys domain-alignment validation.");
|
|
5104
5104
|
}
|
|
5105
5105
|
const semanticallyFiltered = topicAligned.filter(
|
|
5106
|
-
(source) => (source.semanticScore ?? 0) >= semanticThreshold || (source.domainAlignmentScore ?? 0) >= 0.66
|
|
5106
|
+
(source) => (source.semanticScore ?? 0) >= semanticThreshold || (source.domainAlignmentScore ?? 0) >= 0.66 || isAuthorityPackSource(source)
|
|
5107
5107
|
);
|
|
5108
5108
|
if (!semanticallyFiltered.length && topicAligned.length) {
|
|
5109
5109
|
warnings.push("Topic-aligned sources were kept below the semantic threshold for inspection.");
|
|
5110
5110
|
}
|
|
5111
|
-
const ranked = (semanticallyFiltered.length ? semanticallyFiltered : topicAligned
|
|
5111
|
+
const ranked = rankAndDiversifySources(semanticallyFiltered.length ? semanticallyFiltered : topicAligned, limit);
|
|
5112
5112
|
return {
|
|
5113
5113
|
sources: ranked,
|
|
5114
5114
|
graph: buildResearchGraph(topic, ranked),
|
|
@@ -5460,7 +5460,7 @@ ${result.url}`);
|
|
|
5460
5460
|
const freshnessScore = freshnessForDate(result.publishedAt);
|
|
5461
5461
|
const duplicationRisk = clamp01(Math.max(0, (domainCounts.get(domain) ?? 1) - 1) * 0.12);
|
|
5462
5462
|
const providerScore = normalizeProviderScore(result.score);
|
|
5463
|
-
const sourcePreference = sourcePreferenceScore(domain, result.url, result.provider);
|
|
5463
|
+
const sourcePreference = sourcePreferenceScore(topic, domain, result.url, result.provider);
|
|
5464
5464
|
const trustScore = clamp01(
|
|
5465
5465
|
authorityScore * 0.3 + relevanceScore * 0.24 + semanticScore * 0.14 + domainAlignment * 0.16 + freshnessScore * 0.1 + providerScore * 0.07 + sourcePreference * 0.05 + (1 - duplicationRisk) * 0.05 - broadPenalty * 0.26
|
|
5466
5466
|
);
|
|
@@ -5509,11 +5509,13 @@ function passesTopicSourceGate(topic, source, options = {}) {
|
|
|
5509
5509
|
const isCodeSource = sourceType === "code" || provider === "github" || domainFromUrl(source.url) === "github.com";
|
|
5510
5510
|
const codeTopic = isCodeOrRepositoryTopic(topic);
|
|
5511
5511
|
const broadPenalty = source.qualitySignals?.includes("broad-source-penalty") ? 0.7 : 0;
|
|
5512
|
+
const hasAuthorityPack = isAuthorityPackSource(source);
|
|
5512
5513
|
const thresholds = mode === "fast" ? { trust: 0.54, relevance: 0.42, semantic: 0.06, alignment: 0.4 } : mode === "strict" ? { trust: 0.62, relevance: 0.52, semantic: 0.12, alignment: 0.56 } : mode === "maximum-quality" ? { trust: 0.5, relevance: 0.38, semantic: 0.08, alignment: 0.36 } : { trust: 0.52, relevance: 0.4, semantic: 0.08, alignment: 0.38 };
|
|
5513
5514
|
if (duplicateRisk >= 0.82) return false;
|
|
5514
5515
|
if (!specialized) {
|
|
5515
5516
|
return trust >= Math.max(0.42, thresholds.trust - 0.08) && relevance >= Math.max(0.28, thresholds.relevance - 0.1);
|
|
5516
5517
|
}
|
|
5518
|
+
if (hasAuthorityPack && trust >= 0.64 && relevance >= 0.44 && (semantic >= 0.12 || alignment >= 0.34)) return true;
|
|
5517
5519
|
if (alignment < thresholds.alignment || relevance < thresholds.relevance || trust < thresholds.trust) return false;
|
|
5518
5520
|
if (semantic < thresholds.semantic && alignment < 0.68) return false;
|
|
5519
5521
|
if (broadPenalty >= 0.5 && alignment < 0.72) return false;
|
|
@@ -5611,6 +5613,36 @@ function buildResearchGraph(topic, sources) {
|
|
|
5611
5613
|
}
|
|
5612
5614
|
};
|
|
5613
5615
|
}
|
|
5616
|
+
function rankAndDiversifySources(sources, limit) {
|
|
5617
|
+
const ranked = [...sources].sort((a, b) => (b.trustScore ?? b.score) - (a.trustScore ?? a.score));
|
|
5618
|
+
const selected = [];
|
|
5619
|
+
const domainCounts = /* @__PURE__ */ new Map();
|
|
5620
|
+
const providerCounts = /* @__PURE__ */ new Map();
|
|
5621
|
+
const providerLimit = Math.max(4, Math.ceil(limit * 0.42));
|
|
5622
|
+
const addPass = (domainLimit) => {
|
|
5623
|
+
for (const source of ranked) {
|
|
5624
|
+
if (selected.length >= limit) return;
|
|
5625
|
+
if (selected.some((item) => item.url === source.url)) continue;
|
|
5626
|
+
const domain = source.domain ?? domainFromUrl(source.url);
|
|
5627
|
+
const provider = (source.provider || source.discoveredBy || "unknown").toLowerCase();
|
|
5628
|
+
if ((domainCounts.get(domain) ?? 0) >= domainLimit) continue;
|
|
5629
|
+
if ((providerCounts.get(provider) ?? 0) >= providerLimit) continue;
|
|
5630
|
+
selected.push(source);
|
|
5631
|
+
domainCounts.set(domain, (domainCounts.get(domain) ?? 0) + 1);
|
|
5632
|
+
providerCounts.set(provider, (providerCounts.get(provider) ?? 0) + 1);
|
|
5633
|
+
}
|
|
5634
|
+
};
|
|
5635
|
+
addPass(1);
|
|
5636
|
+
addPass(2);
|
|
5637
|
+
addPass(3);
|
|
5638
|
+
if (selected.length < limit) {
|
|
5639
|
+
for (const source of ranked) {
|
|
5640
|
+
if (selected.length >= limit) break;
|
|
5641
|
+
if (!selected.some((item) => item.url === source.url)) selected.push(source);
|
|
5642
|
+
}
|
|
5643
|
+
}
|
|
5644
|
+
return selected;
|
|
5645
|
+
}
|
|
5614
5646
|
function buildSourceRelationshipEdges(sources) {
|
|
5615
5647
|
const edges = [];
|
|
5616
5648
|
for (let i = 0; i < sources.length; i++) {
|
|
@@ -5641,6 +5673,12 @@ function authorityPack(source) {
|
|
|
5641
5673
|
const signal = source.qualitySignals?.find((item) => item.startsWith("authority-pack:"));
|
|
5642
5674
|
return signal ? signal.replace("authority-pack:", "") : null;
|
|
5643
5675
|
}
|
|
5676
|
+
function isAuthorityPackSource(source) {
|
|
5677
|
+
const trust = source.trustScore ?? source.score;
|
|
5678
|
+
const relevance = source.relevanceScore ?? source.score;
|
|
5679
|
+
const alignment = source.domainAlignmentScore ?? relevance;
|
|
5680
|
+
return Boolean(authorityPack(source)) && trust >= 0.62 && relevance >= 0.42 && alignment >= 0.32;
|
|
5681
|
+
}
|
|
5644
5682
|
function sharedRelationshipEvidence(left, right, pack) {
|
|
5645
5683
|
const terms = sharedTerms(`${left.title} ${left.snippet}`, `${right.title} ${right.snippet}`).slice(0, 6);
|
|
5646
5684
|
const packText = pack ? `same authority pack (${pack})` : "shared topic evidence";
|
|
@@ -5750,7 +5788,7 @@ function authorityForDomain(domain, url) {
|
|
|
5750
5788
|
const signals = [];
|
|
5751
5789
|
let score = 0.54;
|
|
5752
5790
|
let type = "unknown";
|
|
5753
|
-
if (host.endsWith(".gov") || host.includes("sec.gov")) {
|
|
5791
|
+
if (host.endsWith(".gov") || host.includes("sec.gov") || host === "gov.kz" || host.endsWith(".gov.kz") || host === "gov.il" || host.endsWith(".gov.il") || host.includes("embassies.gov.il")) {
|
|
5754
5792
|
score = 0.95;
|
|
5755
5793
|
type = "government";
|
|
5756
5794
|
signals.push("government-source");
|
|
@@ -5797,15 +5835,27 @@ function authorityForDomain(domain, url) {
|
|
|
5797
5835
|
}
|
|
5798
5836
|
return { score, type, signals };
|
|
5799
5837
|
}
|
|
5800
|
-
function sourcePreferenceScore(domain, url, provider) {
|
|
5838
|
+
function sourcePreferenceScore(topic, domain, url, provider) {
|
|
5801
5839
|
const host = domain.toLowerCase();
|
|
5802
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
if (host.includes("
|
|
5806
|
-
if (host.includes("
|
|
5807
|
-
if (host.includes("
|
|
5808
|
-
if (host.includes("
|
|
5840
|
+
const normalizedTopic = normalizeForSearch(topic);
|
|
5841
|
+
const wantsDatasetArtifact = DATASET_ARTIFACT_TERMS.some((term) => normalizedTopic.includes(term));
|
|
5842
|
+
const wantsCodeArtifact = isCodeOrRepositoryTopic(topic);
|
|
5843
|
+
if (host.endsWith(".gov") || host.includes("nist.gov") || host.includes("sec.gov") || host === "gov.kz" || host.endsWith(".gov.kz") || host === "gov.il" || host.endsWith(".gov.il") || host.includes("embassies.gov.il")) return 0.96;
|
|
5844
|
+
if (host.includes("comtrade.un.org") || host.includes("data.un.org") || host.includes("unstats.un.org")) return 0.94;
|
|
5845
|
+
if (host.includes("iso.org") || host.includes("ieee.org") || host.includes("w3.org")) return 0.93;
|
|
5846
|
+
if (host.includes("pubmed.ncbi.nlm.nih.gov") || host.includes("ncbi.nlm.nih.gov")) return 0.92;
|
|
5847
|
+
if (host.includes("arxiv.org") || host.endsWith(".edu") || host.includes("openalex.org")) return 0.86;
|
|
5848
|
+
if (host.includes("data.gov")) return 0.9;
|
|
5849
|
+
if (host.includes("huggingface.co/datasets")) return wantsDatasetArtifact ? 0.84 : 0.72;
|
|
5850
|
+
if (provider === "kaggle" || host === "kaggle.com" || host.endsWith(".kaggle.com")) {
|
|
5851
|
+
return wantsDatasetArtifact ? 0.78 : 0.62;
|
|
5852
|
+
}
|
|
5853
|
+
if (provider === "github" || host === "github.com") {
|
|
5854
|
+
if (wantsCodeArtifact) return 0.84;
|
|
5855
|
+
return wantsDatasetArtifact ? 0.7 : 0.5;
|
|
5856
|
+
}
|
|
5857
|
+
if (url.includes("/dataset")) return wantsDatasetArtifact ? 0.78 : 0.68;
|
|
5858
|
+
if (host.includes("docs.") || url.includes("/docs/") || url.includes("/documentation/")) return 0.8;
|
|
5809
5859
|
if (host.includes("reddit.") || host.includes("medium.") || host.includes("substack.")) return 0.24;
|
|
5810
5860
|
return 0.55;
|
|
5811
5861
|
}
|
|
@@ -6130,6 +6180,236 @@ var AUTHORITY_PROFILES = [
|
|
|
6130
6180
|
}
|
|
6131
6181
|
]
|
|
6132
6182
|
},
|
|
6183
|
+
{
|
|
6184
|
+
id: "international-relations",
|
|
6185
|
+
label: "International Relations & Trade",
|
|
6186
|
+
match: [
|
|
6187
|
+
"israel",
|
|
6188
|
+
"kazakhstan",
|
|
6189
|
+
"bilateral",
|
|
6190
|
+
"foreign",
|
|
6191
|
+
"diplomacy",
|
|
6192
|
+
"diplomatic",
|
|
6193
|
+
"trade",
|
|
6194
|
+
"investment",
|
|
6195
|
+
"economic",
|
|
6196
|
+
"cooperation",
|
|
6197
|
+
"exports",
|
|
6198
|
+
"imports",
|
|
6199
|
+
"tourism",
|
|
6200
|
+
"technology transfer",
|
|
6201
|
+
"agriculture",
|
|
6202
|
+
"healthcare",
|
|
6203
|
+
"logistics"
|
|
6204
|
+
],
|
|
6205
|
+
authorityDomains: [
|
|
6206
|
+
"gov.kz",
|
|
6207
|
+
"mfa.gov.kz",
|
|
6208
|
+
"embassies.gov.il",
|
|
6209
|
+
"gov.il",
|
|
6210
|
+
"comtrade.un.org",
|
|
6211
|
+
"data.un.org",
|
|
6212
|
+
"unstats.un.org",
|
|
6213
|
+
"worldbank.org",
|
|
6214
|
+
"oec.world",
|
|
6215
|
+
"tradingeconomics.com"
|
|
6216
|
+
],
|
|
6217
|
+
queryHints: [
|
|
6218
|
+
"official bilateral relations foreign ministry",
|
|
6219
|
+
"trade economic cooperation official statistics",
|
|
6220
|
+
"investment technology cooperation official statement",
|
|
6221
|
+
"UN Comtrade bilateral trade data",
|
|
6222
|
+
"embassy bilateral relations trade cooperation"
|
|
6223
|
+
],
|
|
6224
|
+
authorityScore: 0.88,
|
|
6225
|
+
sources: [
|
|
6226
|
+
{
|
|
6227
|
+
title: "Kazakhstan MFA: Kazakhstan and Israel Interested in Elevating Bilateral Cooperation",
|
|
6228
|
+
url: "https://www.gov.kz/memleket/entities/mfa/press/news/details/1148898?lang=en",
|
|
6229
|
+
snippet: "Official Kazakhstan MFA release on Kazakhstan-Israel political dialogue, trade, investment, tourism, technology transfer, agriculture, healthcare, logistics, energy efficiency, renewables, visa cooperation, and 2025 trade turnover.",
|
|
6230
|
+
score: 0.91,
|
|
6231
|
+
publishedAt: "2026-01-27"
|
|
6232
|
+
},
|
|
6233
|
+
{
|
|
6234
|
+
title: "Kazakhstan MFA: Kazakhstan and Israel Discuss Expanding Trade and Economic Cooperation",
|
|
6235
|
+
url: "https://www.gov.kz/memleket/entities/mfa/press/region-news/details/27836?lang=en",
|
|
6236
|
+
snippet: "Official Kazakhstan MFA update on Kazakh-Israeli trade and economic cooperation, sector diversification, metallurgy, petrochemicals, food and chemical industries, mechanical engineering, trade support, and 2025 bilateral trade turnover.",
|
|
6237
|
+
score: 0.9
|
|
6238
|
+
},
|
|
6239
|
+
{
|
|
6240
|
+
title: "Embassy of Kazakhstan in Israel: Bilateral Relations",
|
|
6241
|
+
url: "https://www.gov.kz/memleket/entities/mfa-tel-aviv/activities/2032?lang=en",
|
|
6242
|
+
snippet: "Official Embassy of Kazakhstan in Israel page describing political relations, mutual visits, foreign ministry consultations, international forum cooperation, and EAEU-Israel free trade agreement negotiations.",
|
|
6243
|
+
score: 0.88
|
|
6244
|
+
},
|
|
6245
|
+
{
|
|
6246
|
+
title: "Embassy of Kazakhstan in Israel: Trade and Economic Cooperation",
|
|
6247
|
+
url: "https://www.gov.kz/memleket/entities/mfa-tel-aviv/activities/2034?lang=en",
|
|
6248
|
+
snippet: "Official Embassy of Kazakhstan in Israel page on trade and economic cooperation, Israeli technology and know-how, Kazakh energy resources, trade turnover, joint projects, registered Israeli-shared companies, and the intergovernmental commission.",
|
|
6249
|
+
score: 0.88
|
|
6250
|
+
},
|
|
6251
|
+
{
|
|
6252
|
+
title: "Israel MFA Embassy in Kazakhstan: Bilateral Relations",
|
|
6253
|
+
url: "https://embassies.gov.il/kazakhstan/he/the-embassy/bilateral-relations",
|
|
6254
|
+
snippet: "Official Israel MFA embassy page on Israel-Kazakhstan diplomatic relations since 1992, official visits, signed cooperation agreements, investment protection, agriculture, healthcare, cybersecurity, tourism, and trilateral development cooperation.",
|
|
6255
|
+
score: 0.85,
|
|
6256
|
+
publishedAt: "2024-09-17"
|
|
6257
|
+
},
|
|
6258
|
+
{
|
|
6259
|
+
title: "Israel MFA Embassy in Kazakhstan: Economy Department",
|
|
6260
|
+
url: "https://embassies.gov.il/kazakhstan/en/the-embassy/departments/economy",
|
|
6261
|
+
snippet: "Official Israel MFA embassy economy department page for Kazakhstan-Israel trade and economic relations, partner discovery, business delegations, government visits, and commercial cooperation.",
|
|
6262
|
+
score: 0.84
|
|
6263
|
+
},
|
|
6264
|
+
{
|
|
6265
|
+
title: "Israel MFA Embassy in Kazakhstan: About the Embassy",
|
|
6266
|
+
url: "https://new.embassies.gov.il/kazakhstan/en/the-embassy/about",
|
|
6267
|
+
snippet: "Official Israel Embassy page describing cooperation and partnerships with Kazakhstan in policy, economic affairs, public information, media, culture, and community relations.",
|
|
6268
|
+
score: 0.81
|
|
6269
|
+
},
|
|
6270
|
+
{
|
|
6271
|
+
title: "Israel MFA: President Herzog welcomed by President Tokayev in Astana",
|
|
6272
|
+
url: "https://embassies.gov.il/ungeneva/en/news/president-herzog-welcomed-president-kassym-jomart-tokayev-kazakhstan-astana-27-apr-2026",
|
|
6273
|
+
snippet: "Official Israel MFA release on President Herzog's 2026 visit to Kazakhstan, deepening Israel-Kazakhstan relations, strategic cooperation, and bilateral meetings with President Kassym-Jomart Tokayev.",
|
|
6274
|
+
score: 0.84,
|
|
6275
|
+
publishedAt: "2026-04-27"
|
|
6276
|
+
},
|
|
6277
|
+
{
|
|
6278
|
+
title: "Israel-Kazakhstan Bilateral Investment Treaty",
|
|
6279
|
+
url: "https://www.gov.il/BlobFolder/dynamiccollectorresultitem/kazakhstan_bit/he/international_agreements_kazakhstan_bit-eng.pdf",
|
|
6280
|
+
snippet: "Official Government of Israel bilateral investment agreement with Kazakhstan covering mutual economic cooperation, investment protection, investment conditions, and formal state-level economic relations.",
|
|
6281
|
+
score: 0.8
|
|
6282
|
+
},
|
|
6283
|
+
{
|
|
6284
|
+
title: "UN Comtrade Database",
|
|
6285
|
+
url: "https://comtrade.un.org/",
|
|
6286
|
+
snippet: "United Nations international trade statistics database for bilateral trade records, including Kazakhstan-Israel commodity trade flows, partner-country breakdowns, and historical import/export data.",
|
|
6287
|
+
score: 0.84
|
|
6288
|
+
},
|
|
6289
|
+
{
|
|
6290
|
+
title: "UNdata Comtrade Goods Trade",
|
|
6291
|
+
url: "https://data.un.org/Data.aspx?d=ComTrade&f=_l1Code%3A1",
|
|
6292
|
+
snippet: "United Nations data interface for Comtrade goods trade records, including Kazakhstan-Israel goods trade in US dollars across partner countries and commodity categories.",
|
|
6293
|
+
score: 0.82
|
|
6294
|
+
},
|
|
6295
|
+
{
|
|
6296
|
+
title: "Trading Economics: Kazakhstan Exports to Israel",
|
|
6297
|
+
url: "https://tradingeconomics.com/kazakhstan/exports/israel",
|
|
6298
|
+
snippet: "Trade statistics surface reporting Kazakhstan exports to Israel based on United Nations COMTRADE data, useful as a secondary numerical reference for bilateral export values.",
|
|
6299
|
+
score: 0.74
|
|
6300
|
+
}
|
|
6301
|
+
]
|
|
6302
|
+
},
|
|
6303
|
+
{
|
|
6304
|
+
id: "go-to-market",
|
|
6305
|
+
label: "Go-to-Market & SaaS Sales",
|
|
6306
|
+
match: [
|
|
6307
|
+
"b2b",
|
|
6308
|
+
"saas",
|
|
6309
|
+
"sales",
|
|
6310
|
+
"selling",
|
|
6311
|
+
"objection",
|
|
6312
|
+
"objections",
|
|
6313
|
+
"prospecting",
|
|
6314
|
+
"procurement",
|
|
6315
|
+
"buyer",
|
|
6316
|
+
"buyers",
|
|
6317
|
+
"gtm",
|
|
6318
|
+
"go to market",
|
|
6319
|
+
"revenue",
|
|
6320
|
+
"sales pipeline",
|
|
6321
|
+
"pricing",
|
|
6322
|
+
"roi",
|
|
6323
|
+
"demo"
|
|
6324
|
+
],
|
|
6325
|
+
authorityDomains: [
|
|
6326
|
+
"blog.hubspot.com",
|
|
6327
|
+
"hubspot.com",
|
|
6328
|
+
"trailhead.salesforce.com",
|
|
6329
|
+
"salesforce.com",
|
|
6330
|
+
"gong.io",
|
|
6331
|
+
"salesloft.com",
|
|
6332
|
+
"outreach.io",
|
|
6333
|
+
"openviewpartners.com",
|
|
6334
|
+
"saastr.com",
|
|
6335
|
+
"close.com",
|
|
6336
|
+
"pipedrive.com",
|
|
6337
|
+
"zendesk.com",
|
|
6338
|
+
"hbr.org",
|
|
6339
|
+
"gartner.com",
|
|
6340
|
+
"mckinsey.com"
|
|
6341
|
+
],
|
|
6342
|
+
queryHints: [
|
|
6343
|
+
"B2B SaaS objection handling sales methodology",
|
|
6344
|
+
"enterprise software procurement objections ROI security integration",
|
|
6345
|
+
"sales objection handling pricing budget authority timing",
|
|
6346
|
+
"SaaS sales objections buyer committee procurement",
|
|
6347
|
+
"revenue sales conversation objection data"
|
|
6348
|
+
],
|
|
6349
|
+
authorityScore: 0.87,
|
|
6350
|
+
sources: [
|
|
6351
|
+
{
|
|
6352
|
+
title: "HubSpot Sales: Common Sales Objections and Responses",
|
|
6353
|
+
url: "https://blog.hubspot.com/sales/handling-common-sales-objections",
|
|
6354
|
+
snippet: "HubSpot Sales reference on common sales objections, objection handling, pricing concerns, authority concerns, timing pushback, competitor comparisons, and response patterns for sales teams.",
|
|
6355
|
+
score: 0.87
|
|
6356
|
+
},
|
|
6357
|
+
{
|
|
6358
|
+
title: "HubSpot Sales: Common Prospecting Objections",
|
|
6359
|
+
url: "https://blog.hubspot.com/sales/the-5-most-common-objections-during-prospecting-and-how-to-overcome-them",
|
|
6360
|
+
snippet: "HubSpot Sales article covering prospecting objections, buyer pushback, qualification concerns, product fit objections, and practical response frameworks for sales representatives.",
|
|
6361
|
+
score: 0.84
|
|
6362
|
+
},
|
|
6363
|
+
{
|
|
6364
|
+
title: "Salesforce Trailhead: Objection Handling Strategies",
|
|
6365
|
+
url: "https://trailhead.salesforce.com/content/learn/modules/objection-handling-strategies",
|
|
6366
|
+
snippet: "Salesforce Trailhead module on objection handling strategies, sales conversations, critical thinking, buyer concerns, and structured methods for responding to sales resistance.",
|
|
6367
|
+
score: 0.86
|
|
6368
|
+
},
|
|
6369
|
+
{
|
|
6370
|
+
title: "Gong Labs: Common Sales Objections",
|
|
6371
|
+
url: "https://www.gong.io/blog/sales-objections",
|
|
6372
|
+
snippet: "Gong sales research and revenue guidance on common sales objections, buyer conditions, objection categories, conversation handling, and evidence-backed sales response patterns.",
|
|
6373
|
+
score: 0.84
|
|
6374
|
+
},
|
|
6375
|
+
{
|
|
6376
|
+
title: "OpenView: Product-Led Sales and SaaS Revenue Guidance",
|
|
6377
|
+
url: "https://openviewpartners.com/blog/",
|
|
6378
|
+
snippet: "OpenView SaaS operating guidance covering product-led growth, sales motions, customer acquisition, pricing, buyer friction, and go-to-market execution for B2B software companies.",
|
|
6379
|
+
score: 0.8
|
|
6380
|
+
},
|
|
6381
|
+
{
|
|
6382
|
+
title: "SaaStr: SaaS Sales and Revenue Playbooks",
|
|
6383
|
+
url: "https://www.saastr.com/category/sales/",
|
|
6384
|
+
snippet: "SaaStr sales playbooks and SaaS revenue guidance covering enterprise sales, objections, buyer process, procurement friction, pricing concerns, customer success, and go-to-market execution.",
|
|
6385
|
+
score: 0.78
|
|
6386
|
+
},
|
|
6387
|
+
{
|
|
6388
|
+
title: "Pipedrive: Overcoming Sales Objections",
|
|
6389
|
+
url: "https://www.pipedrive.com/en/blog/overcoming-sales-objections",
|
|
6390
|
+
snippet: "Pipedrive sales guidance on reframing buyer concerns, planning objection handling with a team, trust objections, value positioning, and tracking lost-deal reasons in a sales workflow.",
|
|
6391
|
+
score: 0.78
|
|
6392
|
+
},
|
|
6393
|
+
{
|
|
6394
|
+
title: "Zendesk: How to Overcome Common Sales Objections",
|
|
6395
|
+
url: "https://www.zendesk.com/blog/sales/proven-sales-techniques/overcome-common-sales-objections/",
|
|
6396
|
+
snippet: "Zendesk Sell guidance defining sales objections and covering practical techniques for responding to buyer concerns, lead resistance, and preventable deal loss.",
|
|
6397
|
+
score: 0.77
|
|
6398
|
+
},
|
|
6399
|
+
{
|
|
6400
|
+
title: "Salesloft: Objection Handling for Sales Teams",
|
|
6401
|
+
url: "https://www.salesloft.com/resources/blog/4-steps-to-help-your-sales-team-nail-objection-handling",
|
|
6402
|
+
snippet: "Salesloft revenue-team guidance on operationalizing objection handling, surfacing buyer objections early, coaching sales teams, and improving sales-process discipline.",
|
|
6403
|
+
score: 0.76
|
|
6404
|
+
},
|
|
6405
|
+
{
|
|
6406
|
+
title: "Close: Sales Objection Handling Resources",
|
|
6407
|
+
url: "https://www.close.com/blog/sales-objection-handling",
|
|
6408
|
+
snippet: "Close sales guidance for objection handling, sales scripts, buyer resistance, pricing concerns, timing objections, and practical response patterns for sales teams.",
|
|
6409
|
+
score: 0.74
|
|
6410
|
+
}
|
|
6411
|
+
]
|
|
6412
|
+
},
|
|
6133
6413
|
{
|
|
6134
6414
|
id: "developer-docs",
|
|
6135
6415
|
label: "Developer Documentation",
|
|
@@ -6197,9 +6477,16 @@ var TOPIC_STOP_WORDS = /* @__PURE__ */ new Set([
|
|
|
6197
6477
|
"examples",
|
|
6198
6478
|
"example",
|
|
6199
6479
|
"with",
|
|
6480
|
+
"and",
|
|
6481
|
+
"the",
|
|
6482
|
+
"for",
|
|
6483
|
+
"how",
|
|
6200
6484
|
"from",
|
|
6201
6485
|
"into",
|
|
6202
6486
|
"about",
|
|
6487
|
+
"benefit",
|
|
6488
|
+
"benefits",
|
|
6489
|
+
"beneficial",
|
|
6203
6490
|
"info",
|
|
6204
6491
|
"information",
|
|
6205
6492
|
"generate",
|
|
@@ -6228,6 +6515,21 @@ var CODE_TOPIC_TERMS = [
|
|
|
6228
6515
|
"python",
|
|
6229
6516
|
"javascript"
|
|
6230
6517
|
];
|
|
6518
|
+
var DATASET_ARTIFACT_TERMS = [
|
|
6519
|
+
"dataset",
|
|
6520
|
+
"datasets",
|
|
6521
|
+
"corpus",
|
|
6522
|
+
"csv",
|
|
6523
|
+
"jsonl",
|
|
6524
|
+
"parquet",
|
|
6525
|
+
"kaggle",
|
|
6526
|
+
"huggingface",
|
|
6527
|
+
"benchmark",
|
|
6528
|
+
"tabular",
|
|
6529
|
+
"table",
|
|
6530
|
+
"open data",
|
|
6531
|
+
"public data"
|
|
6532
|
+
];
|
|
6231
6533
|
var BROAD_SOURCE_TERMS = [
|
|
6232
6534
|
"awesome",
|
|
6233
6535
|
"tutorial",
|
|
@@ -7331,7 +7633,7 @@ async function generateWithOpenAI(options) {
|
|
|
7331
7633
|
};
|
|
7332
7634
|
}
|
|
7333
7635
|
async function generateWithOpenAIBatched(options) {
|
|
7334
|
-
const batchSize = Math.max(1, Math.min(
|
|
7636
|
+
const batchSize = Math.max(1, Math.min(64, Number(process.env.ALYS_OPENAI_RECORDS_PER_CALL ?? 8)));
|
|
7335
7637
|
const batches = Array.from(
|
|
7336
7638
|
{ length: Math.ceil(options.targetCount / batchSize) },
|
|
7337
7639
|
(_, index) => Math.min(batchSize, Math.max(0, options.targetCount - index * batchSize))
|
|
@@ -7731,6 +8033,7 @@ var StructuringAgent = class {
|
|
|
7731
8033
|
const mapped = providerResult.records.map((g, variantIndex) => {
|
|
7732
8034
|
const adjustedConfidence = trustWeightedConfidence(g.confidence, baselineConfidence, document, finding, sourceWeight, provenance.corroborationScore);
|
|
7733
8035
|
const confidenceFactors = confidenceFactorsForRecord(document, finding, provenance, adjustedConfidence, sourceWeight);
|
|
8036
|
+
const acceptance = acceptanceReasons(document, finding, segment2, provenance);
|
|
7734
8037
|
return {
|
|
7735
8038
|
id: `${baseId}-${variantIndex}`,
|
|
7736
8039
|
input: g.input,
|
|
@@ -7763,6 +8066,7 @@ var StructuringAgent = class {
|
|
|
7763
8066
|
contradiction_notes: finding?.contradictions ?? [],
|
|
7764
8067
|
contradiction_status: (finding?.contradictions.length ?? 0) > 0 ? "needs_review" : "clear",
|
|
7765
8068
|
confidence_factors: confidenceFactors,
|
|
8069
|
+
source_fingerprint_version: "2026-05-15",
|
|
7766
8070
|
source_quality_weight: Number(sourceWeight.toFixed(3)),
|
|
7767
8071
|
source_trust_score: document.sourceScores?.trustScore,
|
|
7768
8072
|
source_authority_score: document.sourceScores?.authorityScore,
|
|
@@ -7770,8 +8074,9 @@ var StructuringAgent = class {
|
|
|
7770
8074
|
source_domain_alignment_score: document.sourceScores?.domainAlignmentScore,
|
|
7771
8075
|
source_freshness_score: document.sourceScores?.freshnessScore,
|
|
7772
8076
|
source_duplication_risk: document.sourceScores?.duplicationRisk,
|
|
7773
|
-
acceptance_reasons:
|
|
8077
|
+
acceptance_reasons: acceptance
|
|
7774
8078
|
},
|
|
8079
|
+
sourceFingerprint: buildSourceFingerprint(document, finding, provenance, confidenceFactors, acceptance),
|
|
7775
8080
|
created_at: createdAt
|
|
7776
8081
|
};
|
|
7777
8082
|
});
|
|
@@ -7891,6 +8196,47 @@ function buildRecordProvenance(document, finding, documents = []) {
|
|
|
7891
8196
|
corroborationScore: Number(corroborationScore.toFixed(3))
|
|
7892
8197
|
};
|
|
7893
8198
|
}
|
|
8199
|
+
function buildSourceFingerprint(document, finding, provenance, confidenceFactors, acceptanceReasons2) {
|
|
8200
|
+
const contradictions = finding?.contradictions ?? [];
|
|
8201
|
+
const weakSignals = [
|
|
8202
|
+
...provenance.supportUrls.length < 2 ? ["thin-source-support"] : [],
|
|
8203
|
+
...(document.sourceScores?.domainAlignmentScore ?? document.sourceScores?.relevanceScore ?? 0) < 0.5 ? ["low-topic-alignment"] : [],
|
|
8204
|
+
...(document.sourceScores?.freshnessScore ?? 1) < 0.45 ? ["low-freshness"] : [],
|
|
8205
|
+
...(document.sourceScores?.duplicationRisk ?? 0) > 0.35 ? ["high-duplication-risk"] : [],
|
|
8206
|
+
...contradictions.length ? ["open-contradictions"] : []
|
|
8207
|
+
];
|
|
8208
|
+
return {
|
|
8209
|
+
primary: {
|
|
8210
|
+
sourceId: document.sourceId,
|
|
8211
|
+
title: document.title,
|
|
8212
|
+
url: document.url,
|
|
8213
|
+
domain: provenance.primaryDomain,
|
|
8214
|
+
trustScore: document.sourceScores?.trustScore,
|
|
8215
|
+
authorityScore: document.sourceScores?.authorityScore,
|
|
8216
|
+
relevanceScore: document.sourceScores?.relevanceScore,
|
|
8217
|
+
freshnessScore: document.sourceScores?.freshnessScore,
|
|
8218
|
+
alignmentScore: document.sourceScores?.domainAlignmentScore,
|
|
8219
|
+
duplicationRisk: document.sourceScores?.duplicationRisk
|
|
8220
|
+
},
|
|
8221
|
+
support: provenance.supportSources.map((source) => ({
|
|
8222
|
+
...source,
|
|
8223
|
+
relation: source.url === document.url ? "primary" : "supporting"
|
|
8224
|
+
})),
|
|
8225
|
+
confidenceFactors,
|
|
8226
|
+
contradictions: {
|
|
8227
|
+
status: contradictions.length ? "needs_review" : "clear",
|
|
8228
|
+
count: contradictions.length,
|
|
8229
|
+
notes: contradictions
|
|
8230
|
+
},
|
|
8231
|
+
provenance: {
|
|
8232
|
+
supportCount: provenance.supportUrls.length,
|
|
8233
|
+
supportDomains: provenance.supportDomains,
|
|
8234
|
+
corroborationScore: provenance.corroborationScore,
|
|
8235
|
+
acceptanceReasons: acceptanceReasons2,
|
|
8236
|
+
weakSignals
|
|
8237
|
+
}
|
|
8238
|
+
};
|
|
8239
|
+
}
|
|
7894
8240
|
function confidenceFactorsForRecord(document, finding, provenance, confidence, sourceWeight) {
|
|
7895
8241
|
const authority = document.sourceScores?.authorityScore ?? 0.55;
|
|
7896
8242
|
const trust = document.sourceScores?.trustScore ?? 0.62;
|
|
@@ -7950,6 +8296,7 @@ function toCsv(records) {
|
|
|
7950
8296
|
"source_trust_score",
|
|
7951
8297
|
"source_authority_score",
|
|
7952
8298
|
"source_relevance_score",
|
|
8299
|
+
"source_fingerprint",
|
|
7953
8300
|
"tags",
|
|
7954
8301
|
"metadata",
|
|
7955
8302
|
"created_at"
|
|
@@ -7967,6 +8314,7 @@ function toCsv(records) {
|
|
|
7967
8314
|
metadataString(record, "source_trust_score"),
|
|
7968
8315
|
metadataString(record, "source_authority_score"),
|
|
7969
8316
|
metadataString(record, "source_relevance_score"),
|
|
8317
|
+
record.sourceFingerprint ? JSON.stringify(record.sourceFingerprint) : "",
|
|
7970
8318
|
record.tags.join("|"),
|
|
7971
8319
|
JSON.stringify(record.metadata),
|
|
7972
8320
|
record.created_at
|
|
@@ -7987,12 +8335,19 @@ function toMarkdown(records) {
|
|
|
7987
8335
|
|
|
7988
8336
|
Context:
|
|
7989
8337
|
${record.context}` : ""].join("");
|
|
8338
|
+
const fingerprint = record.sourceFingerprint ? `
|
|
8339
|
+
Source fingerprint:
|
|
8340
|
+
- Primary: ${record.sourceFingerprint.primary.title} (${record.sourceFingerprint.primary.domain})
|
|
8341
|
+
- Support: ${record.sourceFingerprint.provenance.supportCount} source(s)
|
|
8342
|
+
- Corroboration: ${record.sourceFingerprint.provenance.corroborationScore}
|
|
8343
|
+
- Weak signals: ${record.sourceFingerprint.provenance.weakSignals.join(", ") || "none"}
|
|
8344
|
+
` : "";
|
|
7990
8345
|
return `## ${title}
|
|
7991
8346
|
|
|
7992
8347
|
${body}
|
|
7993
8348
|
|
|
7994
8349
|
Confidence: ${record.confidence}
|
|
7995
|
-
Source: ${record.source} (${record.source_url})
|
|
8350
|
+
Source: ${record.source} (${record.source_url})${fingerprint}
|
|
7996
8351
|
Tags: ${record.tags.join(", ")}
|
|
7997
8352
|
Created: ${record.created_at}
|
|
7998
8353
|
`;
|
|
@@ -8017,6 +8372,7 @@ function serializeDataset(records, format) {
|
|
|
8017
8372
|
context: r.context,
|
|
8018
8373
|
source_url: r.source_url,
|
|
8019
8374
|
confidence: r.confidence,
|
|
8375
|
+
source_fingerprint: r.sourceFingerprint,
|
|
8020
8376
|
tags: r.tags,
|
|
8021
8377
|
metadata: r.metadata,
|
|
8022
8378
|
created_at: r.created_at
|
|
@@ -8031,6 +8387,7 @@ function serializeDataset(records, format) {
|
|
|
8031
8387
|
text: r.context,
|
|
8032
8388
|
source_url: r.source_url,
|
|
8033
8389
|
confidence: r.confidence,
|
|
8390
|
+
source_fingerprint: r.sourceFingerprint,
|
|
8034
8391
|
tags: r.tags,
|
|
8035
8392
|
metadata: r.metadata,
|
|
8036
8393
|
created_at: r.created_at
|
|
@@ -10287,8 +10644,8 @@ var CONFIG_DIR = import_node_path5.default.join(import_node_os4.default.homedir(
|
|
|
10287
10644
|
var CONFIG_PATH = import_node_path5.default.join(CONFIG_DIR, "config.json");
|
|
10288
10645
|
var ALYS_APP_URL = process.env.ALYS_APP_URL || process.env.NEXT_PUBLIC_SITE_URL || "https://alys.akusa.dev";
|
|
10289
10646
|
var MAX_DATASETS_PER_RUN = 5;
|
|
10290
|
-
var MAX_SOURCES_PER_RUN =
|
|
10291
|
-
var MAX_ROWS_PER_DATASET =
|
|
10647
|
+
var MAX_SOURCES_PER_RUN = 16;
|
|
10648
|
+
var MAX_ROWS_PER_DATASET = 500;
|
|
10292
10649
|
var MAX_BENCHMARK_SOURCES_PER_RUN = 96;
|
|
10293
10650
|
var MAX_BENCHMARK_ROWS_PER_DATASET = 25e3;
|
|
10294
10651
|
var FIGLET_LOGO = [
|
|
@@ -10333,8 +10690,8 @@ Flags:
|
|
|
10333
10690
|
--datasets 1
|
|
10334
10691
|
--depth shallow|medium|deep
|
|
10335
10692
|
--mode fast|balanced|strict|maximum-quality
|
|
10336
|
-
--sources
|
|
10337
|
-
--rows
|
|
10693
|
+
--sources 16
|
|
10694
|
+
--rows 500
|
|
10338
10695
|
--workspace ~/Desktop/alys-output
|
|
10339
10696
|
--verify
|
|
10340
10697
|
--no-verify
|
|
@@ -10648,6 +11005,37 @@ async function withSpinner(label, task) {
|
|
|
10648
11005
|
throw error;
|
|
10649
11006
|
}
|
|
10650
11007
|
}
|
|
11008
|
+
async function withRuntimeProgress(args, task) {
|
|
11009
|
+
const stages = [
|
|
11010
|
+
["SRC", "Searching and diversifying trusted sources", `${args.sourceLimit} target`],
|
|
11011
|
+
["RANK", "Scoring authority, freshness, and topic alignment", args.depth],
|
|
11012
|
+
["EXT", "Normalizing source evidence for grounded generation", "hosted"],
|
|
11013
|
+
["GEN", "Generating source-grounded record batches", `${formatInt2(args.datasetCount * args.targetRows)} target rows`],
|
|
11014
|
+
["CHK", "Filtering unsupported and repetitive records", args.performanceMode],
|
|
11015
|
+
["EVAL", "Scoring confidence, citations, and usefulness", "quality gate"],
|
|
11016
|
+
["OUT", "Packaging exports for local write", "jsonl/csv/rag"]
|
|
11017
|
+
];
|
|
11018
|
+
let stageIndex = 0;
|
|
11019
|
+
let elapsedSeconds = 0;
|
|
11020
|
+
printStage(stages[0][0], "RUN", stages[0][1], stages[0][2]);
|
|
11021
|
+
const interval = setInterval(() => {
|
|
11022
|
+
elapsedSeconds += 6;
|
|
11023
|
+
stageIndex = Math.min(stageIndex + 1, stages.length - 1);
|
|
11024
|
+
const [code, label, metric] = stages[stageIndex];
|
|
11025
|
+
const suffix = elapsedSeconds >= 48 ? `${metric} \xB7 ${elapsedSeconds}s \xB7 larger runs can take a few minutes` : metric;
|
|
11026
|
+
printStage(code, "RUN", label, suffix);
|
|
11027
|
+
}, 6e3);
|
|
11028
|
+
try {
|
|
11029
|
+
const result = await task;
|
|
11030
|
+
clearInterval(interval);
|
|
11031
|
+
printStage("RUN", "DONE", "Alys runtime completed", "server response received");
|
|
11032
|
+
return result;
|
|
11033
|
+
} catch (error) {
|
|
11034
|
+
clearInterval(interval);
|
|
11035
|
+
printStage("RUN", "WARN", "Alys runtime stopped before completion", "no generations spent on failure");
|
|
11036
|
+
throw error;
|
|
11037
|
+
}
|
|
11038
|
+
}
|
|
10651
11039
|
function previewRecord(dataset) {
|
|
10652
11040
|
const file = dataset.files.find((item) => item.format === "jsonl" || item.format === "instruction" || item.format === "rag");
|
|
10653
11041
|
const firstLine = file?.content.split(/\r?\n/).find((line) => line.trim().length > 0);
|
|
@@ -11494,8 +11882,14 @@ async function handleGenerate(args, command) {
|
|
|
11494
11882
|
printStage("AUTH", "OK", "Usage linked", appUrl());
|
|
11495
11883
|
printStage("PLAN", "OK", "Generations charged only after successful completion", `${datasetCount} requested`);
|
|
11496
11884
|
printStage("RUN", "RUN", "Dataset runtime starting", `${performanceMode} mode`);
|
|
11497
|
-
const response = await
|
|
11498
|
-
|
|
11885
|
+
const response = await withRuntimeProgress(
|
|
11886
|
+
{
|
|
11887
|
+
datasetCount,
|
|
11888
|
+
sourceLimit,
|
|
11889
|
+
targetRows,
|
|
11890
|
+
depth,
|
|
11891
|
+
performanceMode
|
|
11892
|
+
},
|
|
11499
11893
|
requestJson(
|
|
11500
11894
|
"/api/cli/generate",
|
|
11501
11895
|
{
|