@michaelborck/honeyguide-core 0.6.0 → 0.7.0

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.
Files changed (134) hide show
  1. package/README.md +4 -0
  2. package/dist/align/outcomes.d.ts +75 -0
  3. package/dist/align/outcomes.js +266 -0
  4. package/dist/align/outcomes.js.map +1 -0
  5. package/dist/align/reasons.d.ts +11 -0
  6. package/dist/align/reasons.js +84 -0
  7. package/dist/align/reasons.js.map +1 -0
  8. package/dist/annotate/ladder.d.ts +1 -1
  9. package/dist/annotate/ladder.js +2 -2
  10. package/dist/annotate/ladder.js.map +1 -1
  11. package/dist/annotate/ollama.d.ts +3 -1
  12. package/dist/annotate/ollama.js +17 -11
  13. package/dist/annotate/ollama.js.map +1 -1
  14. package/dist/batch.d.ts +0 -0
  15. package/dist/batch.js +0 -0
  16. package/dist/batch.js.map +0 -0
  17. package/dist/brief.d.ts +30 -0
  18. package/dist/brief.js +70 -0
  19. package/dist/brief.js.map +1 -0
  20. package/dist/collection.d.ts +27 -0
  21. package/dist/collection.js +98 -0
  22. package/dist/collection.js.map +1 -0
  23. package/dist/config.d.ts +31 -1
  24. package/dist/config.js +10 -0
  25. package/dist/config.js.map +1 -1
  26. package/dist/enrich/page.d.ts +0 -0
  27. package/dist/enrich/page.js +0 -0
  28. package/dist/enrich/page.js.map +0 -0
  29. package/dist/enrich/sourceType.d.ts +0 -0
  30. package/dist/enrich/sourceType.js +0 -0
  31. package/dist/enrich/sourceType.js.map +0 -0
  32. package/dist/enrich/unpaywall.d.ts +28 -0
  33. package/dist/enrich/unpaywall.js +36 -0
  34. package/dist/enrich/unpaywall.js.map +1 -0
  35. package/dist/export/citations.d.ts +0 -0
  36. package/dist/export/citations.js +0 -0
  37. package/dist/export/citations.js.map +0 -0
  38. package/dist/export/lmsHtml.d.ts +0 -0
  39. package/dist/export/lmsHtml.js +16 -2
  40. package/dist/export/lmsHtml.js.map +1 -1
  41. package/dist/export/markdown.d.ts +0 -0
  42. package/dist/export/markdown.js +11 -3
  43. package/dist/export/markdown.js.map +1 -1
  44. package/dist/index.d.ts +18 -1
  45. package/dist/index.js +17 -1
  46. package/dist/index.js.map +1 -1
  47. package/dist/pipeline.d.ts +2 -2
  48. package/dist/pipeline.js +117 -12
  49. package/dist/pipeline.js.map +1 -1
  50. package/dist/rank/decision.d.ts +59 -0
  51. package/dist/rank/decision.js +124 -0
  52. package/dist/rank/decision.js.map +1 -0
  53. package/dist/rank/diversity.d.ts +0 -0
  54. package/dist/rank/diversity.js +0 -0
  55. package/dist/rank/diversity.js.map +0 -0
  56. package/dist/rank/embeddings.d.ts +41 -0
  57. package/dist/rank/embeddings.js +98 -0
  58. package/dist/rank/embeddings.js.map +1 -0
  59. package/dist/rank/reranker.d.ts +21 -0
  60. package/dist/rank/reranker.js +30 -0
  61. package/dist/rank/reranker.js.map +1 -0
  62. package/dist/rank/semantic.d.ts +14 -0
  63. package/dist/rank/semantic.js +58 -0
  64. package/dist/rank/semantic.js.map +1 -0
  65. package/dist/recheck.d.ts +0 -0
  66. package/dist/recheck.js +0 -0
  67. package/dist/recheck.js.map +0 -0
  68. package/dist/retrieval/arxiv.d.ts +24 -0
  69. package/dist/retrieval/arxiv.js +94 -0
  70. package/dist/retrieval/arxiv.js.map +1 -0
  71. package/dist/retrieval/books.d.ts +0 -0
  72. package/dist/retrieval/books.js +0 -0
  73. package/dist/retrieval/books.js.map +0 -0
  74. package/dist/retrieval/breaker.d.ts +16 -0
  75. package/dist/retrieval/breaker.js +42 -0
  76. package/dist/retrieval/breaker.js.map +1 -0
  77. package/dist/retrieval/cache.d.ts +8 -0
  78. package/dist/retrieval/cache.js +33 -0
  79. package/dist/retrieval/cache.js.map +1 -0
  80. package/dist/retrieval/candidates.d.ts +1 -1
  81. package/dist/retrieval/candidates.js +31 -7
  82. package/dist/retrieval/candidates.js.map +1 -1
  83. package/dist/retrieval/counterpoint.d.ts +0 -0
  84. package/dist/retrieval/counterpoint.js +1 -0
  85. package/dist/retrieval/counterpoint.js.map +1 -1
  86. package/dist/retrieval/europePmc.d.ts +32 -0
  87. package/dist/retrieval/europePmc.js +62 -0
  88. package/dist/retrieval/europePmc.js.map +1 -0
  89. package/dist/retrieval/openalexTopical.d.ts +0 -0
  90. package/dist/retrieval/openalexTopical.js +0 -0
  91. package/dist/retrieval/openalexTopical.js.map +0 -0
  92. package/dist/retrieval/paperMerge.d.ts +16 -0
  93. package/dist/retrieval/paperMerge.js +77 -0
  94. package/dist/retrieval/paperMerge.js.map +1 -0
  95. package/dist/retrieval/papers.d.ts +10 -5
  96. package/dist/retrieval/papers.js +51 -32
  97. package/dist/retrieval/papers.js.map +1 -1
  98. package/dist/retrieval/podcasts.d.ts +0 -0
  99. package/dist/retrieval/podcasts.js +0 -0
  100. package/dist/retrieval/podcasts.js.map +0 -0
  101. package/dist/retrieval/query.d.ts +0 -0
  102. package/dist/retrieval/query.js +1 -0
  103. package/dist/retrieval/query.js.map +1 -1
  104. package/dist/retrieval/rateLimit.d.ts +6 -0
  105. package/dist/retrieval/rateLimit.js +15 -0
  106. package/dist/retrieval/rateLimit.js.map +1 -0
  107. package/dist/retrieval/search/brave.d.ts +13 -0
  108. package/dist/retrieval/search/brave.js +32 -0
  109. package/dist/retrieval/search/brave.js.map +1 -0
  110. package/dist/retrieval/search/index.d.ts +13 -0
  111. package/dist/retrieval/search/index.js +22 -0
  112. package/dist/retrieval/search/index.js.map +1 -0
  113. package/dist/retrieval/search/searxng.d.ts +14 -0
  114. package/dist/retrieval/search/searxng.js +24 -0
  115. package/dist/retrieval/search/searxng.js.map +1 -0
  116. package/dist/retrieval/search/serper.d.ts +14 -0
  117. package/dist/retrieval/search/serper.js +38 -0
  118. package/dist/retrieval/search/serper.js.map +1 -0
  119. package/dist/retrieval/search/types.d.ts +17 -0
  120. package/dist/retrieval/search/types.js +2 -0
  121. package/dist/retrieval/search/types.js.map +1 -0
  122. package/dist/retrieval/videos.d.ts +0 -0
  123. package/dist/retrieval/videos.js +0 -0
  124. package/dist/retrieval/videos.js.map +0 -0
  125. package/dist/retrieval/web.d.ts +5 -6
  126. package/dist/retrieval/web.js +14 -27
  127. package/dist/retrieval/web.js.map +1 -1
  128. package/dist/types.d.ts +62 -0
  129. package/dist/types.js +0 -0
  130. package/dist/types.js.map +0 -0
  131. package/dist/verify/verify.d.ts +11 -2
  132. package/dist/verify/verify.js +13 -4
  133. package/dist/verify/verify.js.map +1 -1
  134. package/package.json +1 -1
package/dist/pipeline.js CHANGED
@@ -3,12 +3,19 @@ import { retrievePodcasts } from './retrieval/podcasts.js';
3
3
  import { retrieveBooks } from './retrieval/books.js';
4
4
  import { retrieveVideos } from './retrieval/videos.js';
5
5
  import { retrieveWeb } from './retrieval/web.js';
6
+ import { createSearchProvider } from './retrieval/search/index.js';
6
7
  import { deriveCounterQueries } from './retrieval/counterpoint.js';
7
8
  import { verifyCandidate } from './verify/verify.js';
8
9
  import { classifySource } from './enrich/sourceType.js';
9
10
  import { fetchPageMeta } from './enrich/page.js';
11
+ import { lookupUnpaywall } from './enrich/unpaywall.js';
12
+ import { createOutcomeAligner } from './align/outcomes.js';
13
+ import { applyConstraints } from './brief.js';
14
+ import { addAlignmentReasons } from './align/reasons.js';
10
15
  import { annotate } from './annotate/ladder.js';
11
16
  import { diversify } from './rank/diversity.js';
17
+ import { createReranker } from './rank/reranker.js';
18
+ import { orderByScores } from './rank/semantic.js';
12
19
  import { deriveQuery } from './retrieval/query.js';
13
20
  const DEFAULT_MAX_RESULTS = 10;
14
21
  const ANNOTATE_CONCURRENCY = 3;
@@ -19,10 +26,11 @@ const ANNOTATE_CONCURRENCY = 3;
19
26
  * (ADR-0011). Counterpoint mode adds a second retrieval pass that
20
27
  * deliberately hunts disagreeing material (spec §3 point 3).
21
28
  */
22
- export async function suggestResources(request, config = {}) {
29
+ export async function suggestResources(request, config = {}, onProgress) {
23
30
  const input = request.input.trim();
24
31
  if (!input)
25
32
  return { resources: [], componentHealth: {} };
33
+ onProgress?.({ stage: 'query' });
26
34
  const maxResults = request.maxResults ?? DEFAULT_MAX_RESULTS;
27
35
  const health = {};
28
36
  const seenUrls = new Set();
@@ -31,12 +39,19 @@ export async function suggestResources(request, config = {}) {
31
39
  // term-frequency fallback). Short inputs pass through unchanged.
32
40
  const topic = await deriveQuery(input, config);
33
41
  // --- Retrieve, one component per source type -------------------------
42
+ onProgress?.({ stage: 'retrieve' });
43
+ const webProvider = createSearchProvider(config);
44
+ const reranker = createReranker(config);
45
+ const paperOptions = {
46
+ mailto: config.mailto,
47
+ semanticScholarApiKey: config.semanticScholarApiKey,
48
+ };
34
49
  const sources = [
35
- ['papers', retrievePapers(topic, config.mailto)],
50
+ ['papers', retrievePapers(topic, paperOptions)],
36
51
  ['podcasts', retrievePodcasts(topic)],
37
52
  ['books', retrieveBooks(topic)],
38
53
  ['videos', config.youtubeApiKey ? retrieveVideos(topic, config.youtubeApiKey) : null],
39
- ['web', config.searxngUrl ? retrieveWeb(topic, config.searxngUrl) : null],
54
+ ['web', webProvider ? retrieveWeb(topic, webProvider) : null],
40
55
  ];
41
56
  const settled = await Promise.allSettled(sources.map(([, p]) => p ?? Promise.reject(new Error('not configured'))));
42
57
  const candidates = [];
@@ -50,18 +65,19 @@ export async function suggestResources(request, config = {}) {
50
65
  health[name] = 'unavailable';
51
66
  }
52
67
  });
53
- const selected = await selectUsable(candidates, maxResults, 'supporting');
68
+ const selected = await selectUsable(applyConstraints(candidates, request.constraints), maxResults, 'supporting');
54
69
  await enrichAll(selected, topic, config, stats);
55
70
  const resources = selected.map(({ resource }) => resource);
56
71
  // --- Counterpoint pass (spec §3 point 3) -----------------------------
57
72
  if (request.counterpoint) {
58
73
  try {
74
+ onProgress?.({ stage: 'retrieve', detail: 'Counterpoints' });
59
75
  const queries = await deriveCounterQueries(topic, config);
60
76
  const counterSettled = await Promise.allSettled(queries.flatMap((q) => [
61
- retrievePapers(q, config.mailto),
62
- ...(config.searxngUrl ? [retrieveWeb(q, config.searxngUrl)] : []),
77
+ retrievePapers(q, paperOptions),
78
+ ...(webProvider ? [retrieveWeb(q, webProvider)] : []),
63
79
  ]));
64
- const counterCandidates = dedupeAgainst(seenUrls, counterSettled.flatMap((o) => (o.status === 'fulfilled' ? o.value : [])));
80
+ const counterCandidates = applyConstraints(dedupeAgainst(seenUrls, counterSettled.flatMap((o) => (o.status === 'fulfilled' ? o.value : []))), request.constraints);
65
81
  const counterCount = Math.max(2, Math.floor(maxResults / 3));
66
82
  const counterSelected = await selectUsable(counterCandidates, counterCount, 'counterpoint');
67
83
  await enrichAll(counterSelected, topic, config, stats);
@@ -72,6 +88,29 @@ export async function suggestResources(request, config = {}) {
72
88
  health.counterpoint = 'unavailable';
73
89
  }
74
90
  }
91
+ // --- Optional outcome alignment (ADR-0017) ---------------------------
92
+ if (request.outcomes?.length && resources.length) {
93
+ onProgress?.({ stage: 'align' });
94
+ const aligner = createOutcomeAligner(config);
95
+ if (!aligner) {
96
+ health.alignment = 'unavailable';
97
+ }
98
+ else {
99
+ try {
100
+ const alignments = await aligner.align(topic, resources, request.outcomes);
101
+ for (const resource of resources) {
102
+ resource.alignment = alignments.get(resource) ?? null;
103
+ }
104
+ await addAlignmentReasons(resources, topic, config);
105
+ health.alignment = resources.some((resource) => resource.alignment)
106
+ ? 'ok'
107
+ : 'degraded';
108
+ }
109
+ catch {
110
+ health.alignment = 'unavailable';
111
+ }
112
+ }
113
+ }
75
114
  health.thumbnails =
76
115
  stats.thumbnailFailures === 0
77
116
  ? 'ok'
@@ -85,15 +124,33 @@ export async function suggestResources(request, config = {}) {
85
124
  : stats.llmSuccesses > 0
86
125
  ? 'degraded'
87
126
  : 'unavailable';
127
+ onProgress?.({ stage: 'done' });
88
128
  return { resources, componentHealth: health };
89
129
  /** Verify, drop dead links, pick a diverse set, pair candidate+resource. */
90
130
  async function selectUsable(pool, count, stance) {
131
+ onProgress?.({ stage: 'verify' });
91
132
  const verified = new Map();
92
133
  await Promise.all(pool.map(async (c) => {
93
134
  verified.set(c, await verifyCandidate(c));
94
135
  }));
95
- const usable = pool.filter((c) => verified.get(c) !== 'dead');
96
- const preliminary = usable.map((c) => toResource(c, verified.get(c) ?? 'unverified', stance));
136
+ const usable = pool.filter((c) => verified.get(c)?.status !== 'dead');
137
+ // Optional re-ranking (ADR-0015, ADR-0016): a local System One decision
138
+ // model when configured, otherwise embeddings. Order by relevance first,
139
+ // then let diversity balancing pick the best of each format. Failure is
140
+ // non-fatal — the original retrieval order remains.
141
+ let ranked = usable;
142
+ if (reranker) {
143
+ try {
144
+ const scores = await reranker.score(topic, usable);
145
+ ranked = orderByScores(usable, scores);
146
+ health.reranker = 'ok';
147
+ }
148
+ catch {
149
+ health.reranker = 'unavailable';
150
+ }
151
+ }
152
+ onProgress?.({ stage: 'rank' });
153
+ const preliminary = ranked.map((c) => toResource(c, verified.get(c) ?? { status: 'unverified', basis: 'none' }, stance));
97
154
  const chosen = diversify(preliminary, count);
98
155
  return chosen.map((resource) => ({
99
156
  candidate: usable[preliminary.indexOf(resource)],
@@ -103,7 +160,13 @@ export async function suggestResources(request, config = {}) {
103
160
  /** Page-meta + screenshot thumbnails (ADR-0005) and annotation (ADR-0011). */
104
161
  async function enrichAll(pairs, annotateTopic, cfg, s) {
105
162
  s.enriched += pairs.length;
106
- await mapLimit(pairs, ANNOTATE_CONCURRENCY, async ({ candidate, resource }) => {
163
+ onProgress?.({
164
+ stage: 'annotate',
165
+ detail: 'Rationales',
166
+ current: 0,
167
+ total: pairs.length,
168
+ });
169
+ await mapLimit(pairs, ANNOTATE_CONCURRENCY, async ({ candidate, resource }, index) => {
107
170
  if ((!candidate.thumbnailUrl || !candidate.description) && !candidate.doi) {
108
171
  try {
109
172
  const meta = await fetchPageMeta(candidate.url);
@@ -125,11 +188,32 @@ export async function suggestResources(request, config = {}) {
125
188
  // screenshots are a bonus, never a failure
126
189
  }
127
190
  }
191
+ // Paywall truth for papers: Unpaywall is authoritative when a DOI and
192
+ // a contact email are available. Non-fatal; unknown stays unknown.
193
+ if (cfg.mailto &&
194
+ candidate.format === 'paper' &&
195
+ candidate.doi &&
196
+ resource.access === 'unknown') {
197
+ try {
198
+ const info = await lookupUnpaywall(candidate.doi, cfg.mailto);
199
+ if (info)
200
+ resource.access = info.access;
201
+ }
202
+ catch {
203
+ // enrichment is a bonus, never a failure
204
+ }
205
+ }
128
206
  if (cfg.ollamaUrl)
129
207
  s.llmAttempts += 1;
130
- resource.annotation = await annotate(annotateTopic, candidate, cfg, true, resource.stance);
208
+ resource.annotation = await annotate(annotateTopic, candidate, cfg, true, resource.stance, request.context);
131
209
  if (resource.annotation.source === 'llm')
132
210
  s.llmSuccesses += 1;
211
+ onProgress?.({
212
+ stage: 'annotate',
213
+ detail: 'Rationales',
214
+ current: index + 1,
215
+ total: pairs.length,
216
+ });
133
217
  });
134
218
  }
135
219
  }
@@ -155,14 +239,35 @@ function toResource(candidate, verification, stance) {
155
239
  authors: candidate.authors,
156
240
  year: candidate.year,
157
241
  venue: candidate.venue ?? null,
158
- verification,
242
+ verification: verification.status,
243
+ verificationBasis: verification.basis,
244
+ access: initialAccess(candidate),
159
245
  commerciallyInterested,
160
246
  licensing: candidate.licensing ?? 'unknown',
161
247
  annotation: { source: 'none', text: null },
162
248
  thumbnailUrl: candidate.thumbnailUrl ?? null,
163
249
  accessibilityNotes: candidate.accessibilityNotes ?? [],
250
+ alignment: null,
164
251
  };
165
252
  }
253
+ /**
254
+ * Seed access from the retrieval source's licensing signal. Only papers get
255
+ * a meaningful value; Unpaywall refines it later when a DOI and mailto exist.
256
+ */
257
+ function initialAccess(candidate) {
258
+ if (candidate.format !== 'paper')
259
+ return 'unknown';
260
+ switch (candidate.licensing) {
261
+ case 'oer':
262
+ case 'creative-commons':
263
+ case 'link-only':
264
+ return 'open';
265
+ case 'library-subscription':
266
+ return 'subscription';
267
+ default:
268
+ return 'unknown';
269
+ }
270
+ }
166
271
  async function mapLimit(items, limit, fn) {
167
272
  let next = 0;
168
273
  const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import type { Candidate } from '../retrieval/candidates.js';
2
+ import type { Reranker } from './reranker.js';
3
+ export declare const MAX_DECISION_CANDIDATES = 16;
4
+ export interface SystemOneCandidate {
5
+ id: string;
6
+ title: string;
7
+ venue?: string;
8
+ description?: string;
9
+ }
10
+ export interface SystemOneQuestion {
11
+ type: 'noul';
12
+ instructions: string;
13
+ criteria: {
14
+ true: string;
15
+ false: string;
16
+ };
17
+ }
18
+ export interface SystemOneRequest {
19
+ model: string;
20
+ state: {
21
+ topic: string;
22
+ candidates: SystemOneCandidate[];
23
+ };
24
+ questions: Record<string, SystemOneQuestion>;
25
+ keep_alive: string;
26
+ }
27
+ export interface BuiltSystemOneRequest {
28
+ request: SystemOneRequest;
29
+ idToCandidate: Map<string, Candidate>;
30
+ }
31
+ /**
32
+ * Pick a bounded shortlist that still represents every format. Retrieval
33
+ * returns papers first, so a naive slice would spend the whole decision-model
34
+ * budget on papers and leave the podcasts/books that diversity will also pick
35
+ * unscored. Round-robin by format instead.
36
+ */
37
+ export declare function balancedSubset(candidates: Candidate[], max: number): Candidate[];
38
+ /**
39
+ * Build one `/v1/systemone` request for a topic and its shortlist: one Noul
40
+ * per candidate, all evaluated against the same state. This is the Jev-style
41
+ * re-ranking pattern, and Ollama's decision models speak the same API.
42
+ */
43
+ export declare function buildSystemOneRequest(topic: string, candidates: Candidate[], model: string): BuiltSystemOneRequest;
44
+ /** Pull the Noul probabilities back out, keyed by the original candidates. */
45
+ export declare function parseSystemOneScores(response: unknown, idToCandidate: Map<string, Candidate>): Map<Candidate, number>;
46
+ /**
47
+ * Local System One reranker (ADR-0016). Ollama >= 0.35 exposes the
48
+ * Jev-compatible `/v1/systemone` endpoint for decision models such as
49
+ * `tev1:0.8b`, `tev1:4b`, `nimble` and `clef`. No API key, no network, no
50
+ * per-token bill.
51
+ */
52
+ export declare class OllamaDecisionReranker implements Reranker {
53
+ private readonly baseUrl;
54
+ private readonly model;
55
+ private readonly apiKey?;
56
+ readonly name = "ollama-systemone";
57
+ constructor(baseUrl: string, model?: string, apiKey?: string | undefined);
58
+ score(topic: string, candidates: Candidate[]): Promise<Map<Candidate, number>>;
59
+ }
@@ -0,0 +1,124 @@
1
+ const TIMEOUT_MS = 30_000;
2
+ // Tev1 runs with a ~2k-token context and the docs advise short inputs, so
3
+ // score a bounded shortlist with truncated metadata.
4
+ export const MAX_DECISION_CANDIDATES = 16;
5
+ const MAX_TITLE_CHARS = 180;
6
+ const MAX_DESCRIPTION_CHARS = 240;
7
+ /**
8
+ * Pick a bounded shortlist that still represents every format. Retrieval
9
+ * returns papers first, so a naive slice would spend the whole decision-model
10
+ * budget on papers and leave the podcasts/books that diversity will also pick
11
+ * unscored. Round-robin by format instead.
12
+ */
13
+ export function balancedSubset(candidates, max) {
14
+ const groups = new Map();
15
+ for (const candidate of candidates) {
16
+ const group = groups.get(candidate.format) ?? [];
17
+ group.push(candidate);
18
+ groups.set(candidate.format, group);
19
+ }
20
+ const out = [];
21
+ for (let round = 0; out.length < max; round++) {
22
+ let added = false;
23
+ for (const group of groups.values()) {
24
+ const candidate = group[round];
25
+ if (!candidate)
26
+ continue;
27
+ out.push(candidate);
28
+ added = true;
29
+ if (out.length >= max)
30
+ break;
31
+ }
32
+ if (!added)
33
+ break;
34
+ }
35
+ return out;
36
+ }
37
+ /**
38
+ * Build one `/v1/systemone` request for a topic and its shortlist: one Noul
39
+ * per candidate, all evaluated against the same state. This is the Jev-style
40
+ * re-ranking pattern, and Ollama's decision models speak the same API.
41
+ */
42
+ export function buildSystemOneRequest(topic, candidates, model) {
43
+ const idToCandidate = new Map();
44
+ const items = [];
45
+ const questions = {};
46
+ balancedSubset(candidates, MAX_DECISION_CANDIDATES).forEach((candidate, index) => {
47
+ const id = `c${index}`;
48
+ idToCandidate.set(id, candidate);
49
+ items.push({
50
+ id,
51
+ title: candidate.title.slice(0, MAX_TITLE_CHARS),
52
+ venue: candidate.venue?.slice(0, 80),
53
+ description: candidate.description?.slice(0, MAX_DESCRIPTION_CHARS),
54
+ });
55
+ questions[id] = {
56
+ type: 'noul',
57
+ instructions: `Is \`candidates[${index}]\` a resource a lecturer would plausibly ` +
58
+ `use when teaching \`topic\`?`,
59
+ criteria: {
60
+ true: 'Directly relevant to the topic; a lecturer could reasonably assign or recommend it.',
61
+ false: 'Only tangentially related, off-topic, or not useful for teaching this topic.',
62
+ },
63
+ };
64
+ });
65
+ return {
66
+ request: {
67
+ model,
68
+ state: { topic, candidates: items },
69
+ questions,
70
+ keep_alive: '5m',
71
+ },
72
+ idToCandidate,
73
+ };
74
+ }
75
+ /** Pull the Noul probabilities back out, keyed by the original candidates. */
76
+ export function parseSystemOneScores(response, idToCandidate) {
77
+ const answers = response
78
+ ?.answers ?? {};
79
+ const scores = new Map();
80
+ for (const [id, answer] of Object.entries(answers)) {
81
+ const candidate = idToCandidate.get(id);
82
+ if (candidate && typeof answer?.noul === 'number') {
83
+ scores.set(candidate, answer.noul);
84
+ }
85
+ }
86
+ return scores;
87
+ }
88
+ /**
89
+ * Local System One reranker (ADR-0016). Ollama >= 0.35 exposes the
90
+ * Jev-compatible `/v1/systemone` endpoint for decision models such as
91
+ * `tev1:0.8b`, `tev1:4b`, `nimble` and `clef`. No API key, no network, no
92
+ * per-token bill.
93
+ */
94
+ export class OllamaDecisionReranker {
95
+ baseUrl;
96
+ model;
97
+ apiKey;
98
+ name = 'ollama-systemone';
99
+ constructor(baseUrl, model = 'tev1:0.8b', apiKey) {
100
+ this.baseUrl = baseUrl;
101
+ this.model = model;
102
+ this.apiKey = apiKey;
103
+ }
104
+ async score(topic, candidates) {
105
+ if (!candidates.length)
106
+ return new Map();
107
+ const { request, idToCandidate } = buildSystemOneRequest(topic, candidates, this.model);
108
+ if (!Object.keys(request.questions).length)
109
+ return new Map();
110
+ const headers = { 'content-type': 'application/json' };
111
+ if (this.apiKey)
112
+ headers.authorization = `Bearer ${this.apiKey}`;
113
+ const res = await fetch(`${this.baseUrl.replace(/\/$/, '')}/v1/systemone`, {
114
+ method: 'POST',
115
+ headers,
116
+ body: JSON.stringify(request),
117
+ signal: AbortSignal.timeout(TIMEOUT_MS),
118
+ });
119
+ if (!res.ok)
120
+ throw new Error(`Ollama System One HTTP ${res.status}`);
121
+ return parseSystemOneScores(await res.json(), idToCandidate);
122
+ }
123
+ }
124
+ //# sourceMappingURL=decision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision.js","sourceRoot":"","sources":["../../src/rank/decision.ts"],"names":[],"mappings":"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"}
File without changes
File without changes
File without changes
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Embedding providers for semantic re-ranking (ADR-0015). The interface is
3
+ * deliberately small so an ONNX or other local runtime can be added without
4
+ * touching the pipeline.
5
+ */
6
+ export interface EmbeddingProvider {
7
+ readonly name: string;
8
+ embed(texts: string[]): Promise<number[][]>;
9
+ }
10
+ /**
11
+ * Ollama embeddings. Uses the batch `/api/embed` endpoint (current Ollama)
12
+ * and falls back to the older single-text `/api/embeddings` endpoint.
13
+ */
14
+ export declare class OllamaEmbeddingProvider implements EmbeddingProvider {
15
+ private readonly baseUrl;
16
+ private readonly model;
17
+ private readonly apiKey?;
18
+ readonly name = "ollama";
19
+ constructor(baseUrl: string, model: string, apiKey?: string | undefined);
20
+ embed(texts: string[]): Promise<number[][]>;
21
+ }
22
+ /**
23
+ * Process-local cache so repeated topics and resources do not re-embed. The
24
+ * cache is small and evicts the oldest entries; embeddings are deterministic
25
+ * for a given model, so this is safe.
26
+ */
27
+ export declare class CachedEmbeddingProvider implements EmbeddingProvider {
28
+ private readonly inner;
29
+ private readonly maxEntries;
30
+ readonly name: string;
31
+ private readonly cache;
32
+ constructor(inner: EmbeddingProvider, maxEntries?: number);
33
+ embed(texts: string[]): Promise<number[][]>;
34
+ private set;
35
+ }
36
+ /** Build the configured embedding provider, or null when re-ranking is off. */
37
+ export declare function createEmbeddingProvider(options: {
38
+ embeddingUrl?: string;
39
+ embeddingModel?: string;
40
+ embeddingApiKey?: string;
41
+ }): EmbeddingProvider | null;
@@ -0,0 +1,98 @@
1
+ const EMBED_TIMEOUT_MS = 15_000;
2
+ /**
3
+ * Ollama embeddings. Uses the batch `/api/embed` endpoint (current Ollama)
4
+ * and falls back to the older single-text `/api/embeddings` endpoint.
5
+ */
6
+ export class OllamaEmbeddingProvider {
7
+ baseUrl;
8
+ model;
9
+ apiKey;
10
+ name = 'ollama';
11
+ constructor(baseUrl, model, apiKey) {
12
+ this.baseUrl = baseUrl;
13
+ this.model = model;
14
+ this.apiKey = apiKey;
15
+ }
16
+ async embed(texts) {
17
+ if (!texts.length)
18
+ return [];
19
+ const base = this.baseUrl.replace(/\/$/, '');
20
+ const headers = { 'content-type': 'application/json' };
21
+ if (this.apiKey)
22
+ headers.authorization = `Bearer ${this.apiKey}`;
23
+ const res = await fetch(`${base}/api/embed`, {
24
+ method: 'POST',
25
+ headers,
26
+ body: JSON.stringify({ model: this.model, input: texts }),
27
+ signal: AbortSignal.timeout(EMBED_TIMEOUT_MS),
28
+ });
29
+ if (res.ok) {
30
+ const data = (await res.json());
31
+ if (Array.isArray(data.embeddings) && data.embeddings.length === texts.length) {
32
+ return data.embeddings;
33
+ }
34
+ }
35
+ // Older Ollama: one prompt at a time.
36
+ const out = [];
37
+ for (const text of texts) {
38
+ const single = await fetch(`${base}/api/embeddings`, {
39
+ method: 'POST',
40
+ headers,
41
+ body: JSON.stringify({ model: this.model, prompt: text }),
42
+ signal: AbortSignal.timeout(EMBED_TIMEOUT_MS),
43
+ });
44
+ if (!single.ok)
45
+ throw new Error(`Ollama embeddings HTTP ${single.status}`);
46
+ const data = (await single.json());
47
+ if (!data.embedding)
48
+ throw new Error('Ollama returned no embedding');
49
+ out.push(data.embedding);
50
+ }
51
+ return out;
52
+ }
53
+ }
54
+ /**
55
+ * Process-local cache so repeated topics and resources do not re-embed. The
56
+ * cache is small and evicts the oldest entries; embeddings are deterministic
57
+ * for a given model, so this is safe.
58
+ */
59
+ export class CachedEmbeddingProvider {
60
+ inner;
61
+ maxEntries;
62
+ name;
63
+ cache = new Map();
64
+ constructor(inner, maxEntries = 500) {
65
+ this.inner = inner;
66
+ this.maxEntries = maxEntries;
67
+ this.name = inner.name;
68
+ }
69
+ async embed(texts) {
70
+ const missing = [...new Set(texts.filter((t) => !this.cache.has(t)))];
71
+ if (missing.length) {
72
+ const vectors = await this.inner.embed(missing);
73
+ missing.forEach((text, i) => {
74
+ if (vectors[i])
75
+ this.set(text, vectors[i]);
76
+ });
77
+ }
78
+ const out = texts.map((text) => this.cache.get(text));
79
+ if (out.some((v) => !v))
80
+ throw new Error('embedding cache miss after fill');
81
+ return out;
82
+ }
83
+ set(text, vector) {
84
+ if (this.cache.size >= this.maxEntries) {
85
+ const oldest = this.cache.keys().next().value;
86
+ if (oldest !== undefined)
87
+ this.cache.delete(oldest);
88
+ }
89
+ this.cache.set(text, vector);
90
+ }
91
+ }
92
+ /** Build the configured embedding provider, or null when re-ranking is off. */
93
+ export function createEmbeddingProvider(options) {
94
+ if (!options.embeddingUrl)
95
+ return null;
96
+ return new CachedEmbeddingProvider(new OllamaEmbeddingProvider(options.embeddingUrl, options.embeddingModel ?? 'nomic-embed-text', options.embeddingApiKey));
97
+ }
98
+ //# sourceMappingURL=embeddings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embeddings.js","sourceRoot":"","sources":["../../src/rank/embeddings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { Candidate } from '../retrieval/candidates.js';
2
+ import type { PipelineConfig } from '../config.js';
3
+ import { type EmbeddingProvider } from './embeddings.js';
4
+ /** A re-ranker scores retrieved candidates against the topic. */
5
+ export interface Reranker {
6
+ readonly name: string;
7
+ score(topic: string, candidates: Candidate[]): Promise<Map<Candidate, number>>;
8
+ }
9
+ /** Embedding-based re-ranking (ADR-0015). */
10
+ export declare class EmbeddingReranker implements Reranker {
11
+ private readonly provider;
12
+ readonly name = "embeddings";
13
+ constructor(provider: EmbeddingProvider);
14
+ score(topic: string, candidates: Candidate[]): Promise<Map<Candidate, number>>;
15
+ }
16
+ /**
17
+ * Pick the best available local re-ranker (ADR-0015, ADR-0016). A System One
18
+ * decision model is preferred when configured because it judges relevance
19
+ * directly; embeddings are the fallback. With neither, ranking is unchanged.
20
+ */
21
+ export declare function createReranker(config: PipelineConfig): Reranker | null;