agenr 2.0.0 → 2.1.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.
- package/CHANGELOG.md +44 -0
- package/dist/adapters/openclaw/index.d.ts +1 -1
- package/dist/adapters/openclaw/index.js +1466 -124
- package/dist/{chunk-MEHOGUZE.js → chunk-6T5RXGIR.js} +989 -70
- package/dist/{chunk-Y2BC7RCE.js → chunk-7TDALVPY.js} +1434 -305
- package/dist/{chunk-XD3446YW.js → chunk-DGV6D6Q3.js} +2 -21
- package/dist/chunk-IMQIJPIP.js +886 -0
- package/dist/chunk-MJIB6J5S.js +3059 -0
- package/dist/cli.js +278 -601
- package/dist/core/recall/index.d.ts +535 -107
- package/dist/core/recall/index.js +37 -3
- package/dist/internal-eval-server.d.ts +1 -0
- package/dist/internal-eval-server.js +6 -0
- package/dist/internal-recall-eval-server.js +5 -1816
- package/dist/ports-Nj5nd2Ri.d.ts +719 -0
- package/package.json +3 -2
- package/dist/ports-D2NOK2gR.d.ts +0 -256
|
@@ -1,109 +1,5 @@
|
|
|
1
|
-
import { E as
|
|
2
|
-
export { d as EntryFilters, F as FtsCandidate,
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Backend-agnostic lexical search tier used to plan adapter queries.
|
|
6
|
-
*/
|
|
7
|
-
type LexicalSearchTier = {
|
|
8
|
-
tier: "exact";
|
|
9
|
-
text: string;
|
|
10
|
-
} | {
|
|
11
|
-
tier: "all_tokens" | "any_tokens";
|
|
12
|
-
tokens: string[];
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* Tokenize free-form text into normalized lexical terms.
|
|
16
|
-
*
|
|
17
|
-
* @param text - Source text to tokenize.
|
|
18
|
-
* @returns Lowercased non-stopword tokens.
|
|
19
|
-
*/
|
|
20
|
-
declare function tokenize(text: string): string[];
|
|
21
|
-
/**
|
|
22
|
-
* Build a lexical search plan from raw user text.
|
|
23
|
-
*
|
|
24
|
-
* @param text - Raw query text.
|
|
25
|
-
* @returns Exact, all-token, and any-token tiers in cascade order.
|
|
26
|
-
*/
|
|
27
|
-
declare function buildLexicalPlan(text: string): LexicalSearchTier[];
|
|
28
|
-
/**
|
|
29
|
-
* Compute the lexical overlap score between a query and an entry.
|
|
30
|
-
*
|
|
31
|
-
* @param query - Raw recall query text.
|
|
32
|
-
* @param subject - Entry subject text.
|
|
33
|
-
* @param content - Entry content text.
|
|
34
|
-
* @returns Normalized lexical overlap signal in the 0-1 range.
|
|
35
|
-
*/
|
|
36
|
-
declare function computeLexicalScore(query: string, subject: string, content: string): number;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Score breakdown returned for a ranked recall candidate.
|
|
40
|
-
*/
|
|
41
|
-
interface CandidateScore {
|
|
42
|
-
score: number;
|
|
43
|
-
scores: {
|
|
44
|
-
relevance: number;
|
|
45
|
-
vector: number;
|
|
46
|
-
lexical: number;
|
|
47
|
-
recency: number;
|
|
48
|
-
importance: number;
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Compute the tier-aware half-life recency score for an entry.
|
|
53
|
-
*
|
|
54
|
-
* @param createdAt - Entry creation timestamp.
|
|
55
|
-
* @param expiry - Entry durability tier.
|
|
56
|
-
* @param now - Reference time for the age calculation.
|
|
57
|
-
* @returns Normalized recency score in the 0-1 range.
|
|
58
|
-
*/
|
|
59
|
-
declare function recencyScore(createdAt: Date | string, expiry: Expiry, now?: Date): number;
|
|
60
|
-
/**
|
|
61
|
-
* Compute a gaussian recency score centered on an around-date query anchor.
|
|
62
|
-
*
|
|
63
|
-
* @param createdAt - Entry creation timestamp.
|
|
64
|
-
* @param aroundDate - Temporal anchor inferred or provided by the user.
|
|
65
|
-
* @param radiusDays - Standard deviation-like radius in days.
|
|
66
|
-
* @returns Normalized temporal proximity score in the 0-1 range.
|
|
67
|
-
*/
|
|
68
|
-
declare function gaussianRecency(createdAt: Date | string, aroundDate: Date, radiusDays: number): number;
|
|
69
|
-
/**
|
|
70
|
-
* Normalize an importance value from the 1-10 domain into the 0.4-1.0 score range.
|
|
71
|
-
*
|
|
72
|
-
* @param importance - Raw entry importance.
|
|
73
|
-
* @returns Normalized importance score in the 0-1 range.
|
|
74
|
-
*/
|
|
75
|
-
declare function importanceScore(importance: number): number;
|
|
76
|
-
/**
|
|
77
|
-
* Combine vector and lexical relevance signals into a single query-relevance score.
|
|
78
|
-
*
|
|
79
|
-
* @param vectorSim - Vector similarity score.
|
|
80
|
-
* @param lexical - Lexical overlap score.
|
|
81
|
-
* @returns Combined relevance score in the 0-1 range.
|
|
82
|
-
*/
|
|
83
|
-
declare function combinedRelevance(vectorSim: number, lexical: number): number;
|
|
84
|
-
/**
|
|
85
|
-
* Compute the final recall score and its component breakdown for a candidate.
|
|
86
|
-
*
|
|
87
|
-
* @param params - Candidate signal inputs.
|
|
88
|
-
* @returns Final score plus signal breakdown.
|
|
89
|
-
*/
|
|
90
|
-
declare function scoreCandidate(params: {
|
|
91
|
-
vectorSim: number;
|
|
92
|
-
lexical: number;
|
|
93
|
-
recency: number;
|
|
94
|
-
importance: number;
|
|
95
|
-
}): CandidateScore;
|
|
96
|
-
/**
|
|
97
|
-
* Compute cosine similarity between two numeric vectors.
|
|
98
|
-
*
|
|
99
|
-
* Non-finite coordinates are treated as zero and negative similarities are clamped
|
|
100
|
-
* to zero because recall scoring only consumes a 0-1 signal.
|
|
101
|
-
*
|
|
102
|
-
* @param left - Left-hand vector.
|
|
103
|
-
* @param right - Right-hand vector.
|
|
104
|
-
* @returns Cosine similarity in the 0-1 range.
|
|
105
|
-
*/
|
|
106
|
-
declare function cosineSimilarity(left: number[], right: number[]): number;
|
|
1
|
+
import { E as EntryType, C as CrossEncoderPort, a as Expiry, R as RecallInput, b as RecallPorts, c as RecallOutput } from '../../ports-Nj5nd2Ri.js';
|
|
2
|
+
export { D as DEFAULT_NEIGHBORHOOD_BUDGET, d as DEFAULT_SEEDED_RERANK_WEIGHT, e as DEFAULT_STRONG_SEED_SCORE_GAP, f as DEFAULT_STRONG_SEED_TOP_N, g as EntityAttributeKind, h as EntityAttributeQueryShape, i as EntryFilters, j as EntryNeighborhoodRequest, F as FtsCandidate, N as NeighborhoodFamily, k as RecallCandidateEntry, l as RecallRankingProfile, S as SeededRerankCandidate, m as SeededRerankOptions, V as VectorCandidate, s as seededRerank, n as selectStrongSeeds, o as sharesEntryLineage, p as sharesEpisodeLineage, q as sharesProcedureLineage } from '../../ports-Nj5nd2Ri.js';
|
|
107
3
|
|
|
108
4
|
/**
|
|
109
5
|
* Runtime slot-policy classes used by claim-centric read surfaces.
|
|
@@ -221,6 +117,84 @@ interface RecallClaimKeyTrace {
|
|
|
221
117
|
/** Current-state trusted same-slot duplicates down-ranked for diversity. */
|
|
222
118
|
redundancyPenalized: number;
|
|
223
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Reciprocal rank fusion facts observed during one recall execution.
|
|
122
|
+
*/
|
|
123
|
+
interface RecallRrfTrace {
|
|
124
|
+
/** Whether RRF actually fused at least one non-empty channel. */
|
|
125
|
+
applied: boolean;
|
|
126
|
+
/** Number of non-empty channels supplied to the fusion helper. */
|
|
127
|
+
channelCount: number;
|
|
128
|
+
/** Effective rank constant `k` used for the fusion. */
|
|
129
|
+
rankConstant: number;
|
|
130
|
+
/** Number of unique candidates that received a fused RRF score. */
|
|
131
|
+
fusedCandidateCount: number;
|
|
132
|
+
/** Maximum normalized RRF score observed across fused candidates. */
|
|
133
|
+
maxFusedScore: number;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* MMR diversification facts observed during one recall execution.
|
|
137
|
+
*/
|
|
138
|
+
interface RecallMmrTrace {
|
|
139
|
+
/** Whether MMR actually reordered the shortlist for this execution. */
|
|
140
|
+
applied: boolean;
|
|
141
|
+
/** Effective lambda used when MMR ran, or the configured default when skipped. */
|
|
142
|
+
lambda: number;
|
|
143
|
+
/**
|
|
144
|
+
* Candidates that MMR identified as near duplicates and demoted below
|
|
145
|
+
* their input position. A zero count means no redundancy was observed.
|
|
146
|
+
*/
|
|
147
|
+
droppedDuplicateCount: number;
|
|
148
|
+
/** Candidate IDs whose position shifted relative to the input order. */
|
|
149
|
+
reorderedIds: string[];
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Cross-encoder rerank facts observed during one recall execution.
|
|
153
|
+
*/
|
|
154
|
+
interface RecallCrossEncoderTrace {
|
|
155
|
+
/** Whether the cross-encoder rerank stage actually ran. */
|
|
156
|
+
applied: boolean;
|
|
157
|
+
/** Effective top-K size handed to the cross-encoder. */
|
|
158
|
+
k: number;
|
|
159
|
+
/** Blend weight between `crossEncoderScore` and the prior composite score. */
|
|
160
|
+
alpha: number;
|
|
161
|
+
/** Wall-clock latency of the cross-encoder rerank stage in milliseconds. */
|
|
162
|
+
latencyMs: number;
|
|
163
|
+
/** Stable degraded-mode reason when the rerank was skipped or failed. */
|
|
164
|
+
degradedReason?: RecallCrossEncoderDegradedReason;
|
|
165
|
+
/** Candidate IDs whose composite score was reshaped by the rerank. */
|
|
166
|
+
rescoredIds: string[];
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Stable reasons a cross-encoder rerank may skip or degrade.
|
|
170
|
+
*
|
|
171
|
+
* - `not_configured`: no `CrossEncoderPort` was wired on the ports bundle.
|
|
172
|
+
* - `disabled`: the caller's `rankingPolicy.crossEncoder` is `"disabled"`.
|
|
173
|
+
* - `no_candidates`: the input shortlist was empty after earlier stages.
|
|
174
|
+
* - `provider_error`: the port threw or returned malformed data.
|
|
175
|
+
*/
|
|
176
|
+
type RecallCrossEncoderDegradedReason = "not_configured" | "disabled" | "no_candidates" | "provider_error";
|
|
177
|
+
/**
|
|
178
|
+
* Neighborhood expansion and seeded rerank facts observed during one recall execution.
|
|
179
|
+
*/
|
|
180
|
+
interface RecallNeighborhoodTrace {
|
|
181
|
+
/** Whether the adapter was asked to expand a lineage neighborhood. */
|
|
182
|
+
expansionRequested: boolean;
|
|
183
|
+
/** Whether the adapter exposes the expandNeighborhood port at all. */
|
|
184
|
+
expansionAvailable: boolean;
|
|
185
|
+
/** Family kinds requested from the adapter for this execution. */
|
|
186
|
+
familiesRequested: string[];
|
|
187
|
+
/** Whether retired rows were allowed into the expansion. */
|
|
188
|
+
includeRetired: boolean;
|
|
189
|
+
/** Seed entry IDs chosen before the adapter expansion. */
|
|
190
|
+
seedIds: string[];
|
|
191
|
+
/** Unique candidates returned by the adapter expansion. */
|
|
192
|
+
expansionCandidates: number;
|
|
193
|
+
/** Strong seed IDs chosen for seededRerank. */
|
|
194
|
+
strongSeedIds: string[];
|
|
195
|
+
/** Candidate IDs that received a seededRerank boost. */
|
|
196
|
+
rerankBoostedIds: string[];
|
|
197
|
+
}
|
|
224
198
|
/**
|
|
225
199
|
* Small typed execution summary emitted by the recall core.
|
|
226
200
|
*/
|
|
@@ -233,6 +207,14 @@ interface RecallExecutionTraceSummary {
|
|
|
233
207
|
candidateCounts: RecallCoreCandidateCountsTrace;
|
|
234
208
|
/** Claim-key lineage and diversity shaping facts observed during ranking. */
|
|
235
209
|
claimKey: RecallClaimKeyTrace;
|
|
210
|
+
/** Reciprocal rank fusion facts observed during ranking. */
|
|
211
|
+
rrf: RecallRrfTrace;
|
|
212
|
+
/** Neighborhood expansion and seeded rerank facts observed during ranking. */
|
|
213
|
+
neighborhood: RecallNeighborhoodTrace;
|
|
214
|
+
/** MMR diversification facts observed during ranking. */
|
|
215
|
+
mmr: RecallMmrTrace;
|
|
216
|
+
/** Cross-encoder rerank facts observed during ranking. */
|
|
217
|
+
crossEncoder: RecallCrossEncoderTrace;
|
|
236
218
|
/** Whether recall had to degrade into lexical-only ranking. */
|
|
237
219
|
degraded: RecallDegradedTrace;
|
|
238
220
|
/** Core-only timings observed inside the ranking flow. */
|
|
@@ -249,6 +231,81 @@ interface RecallTraceSink {
|
|
|
249
231
|
*/
|
|
250
232
|
reportSummary(summary: RecallExecutionTraceSummary): void;
|
|
251
233
|
}
|
|
234
|
+
/**
|
|
235
|
+
* Tunable ranking policy applied to one recall execution.
|
|
236
|
+
*
|
|
237
|
+
* Every field is optional so callers can opt into individual stages
|
|
238
|
+
* without having to restate the full policy. Evals that A/B one stage
|
|
239
|
+
* at a time rely on the per-stage kill switches here.
|
|
240
|
+
*/
|
|
241
|
+
interface RecallRankingPolicy {
|
|
242
|
+
/**
|
|
243
|
+
* Whether to apply reciprocal rank fusion across retrieval channels.
|
|
244
|
+
* Defaults to `"enabled"`. When set to `"disabled"`, the recall
|
|
245
|
+
* pipeline falls back to single-channel vector ordering (with a
|
|
246
|
+
* lexical fallback when vectors are unavailable) so evals can A/B
|
|
247
|
+
* the fusion stage without stripping channels from the pipeline.
|
|
248
|
+
*/
|
|
249
|
+
rrf?: "enabled" | "disabled";
|
|
250
|
+
/**
|
|
251
|
+
* Optional override for the RRF rank constant `k`. Higher values
|
|
252
|
+
* flatten the contribution of the top ranks across channels; lower
|
|
253
|
+
* values sharpen them. Defaults to the canonical Cormack et al.
|
|
254
|
+
* constant `60`.
|
|
255
|
+
*/
|
|
256
|
+
rrfRankConstant?: number;
|
|
257
|
+
/**
|
|
258
|
+
* Optional override for the small-pool RRF rank constant `k` that is
|
|
259
|
+
* used when the fused candidate pool is at or below
|
|
260
|
+
* `SMALL_POOL_RRF_POOL_SIZE`. Defaults to
|
|
261
|
+
* `DEFAULT_RRF_SMALL_POOL_RANK_CONSTANT` (`8`), which sharpens the
|
|
262
|
+
* rank-1 versus rank-2 gap enough to keep small-magnitude recency and
|
|
263
|
+
* importance differences from flipping a clear vector leader. Set to
|
|
264
|
+
* the same value as `rrfRankConstant` to disable the sharpening.
|
|
265
|
+
*/
|
|
266
|
+
rrfSmallPoolRankConstant?: number;
|
|
267
|
+
/**
|
|
268
|
+
* Whether to apply the neighborhood expansion plus seeded rerank
|
|
269
|
+
* stage. Defaults to `"enabled"`. When set to `"disabled"`, the
|
|
270
|
+
* pipeline skips both the adapter-scoped `expandNeighborhood()` call
|
|
271
|
+
* and the `seededRerank()` pass so evals can isolate fusion from
|
|
272
|
+
* lineage-aware rerank effects.
|
|
273
|
+
*/
|
|
274
|
+
neighborhood?: "enabled" | "disabled";
|
|
275
|
+
/**
|
|
276
|
+
* Whether to apply the MMR diversification stage. Defaults to
|
|
277
|
+
* `"enabled"` so the default pipeline gets diversity out of the box.
|
|
278
|
+
*/
|
|
279
|
+
mmr?: "enabled" | "disabled";
|
|
280
|
+
/** Effective MMR lambda in the inclusive 0-1 range. */
|
|
281
|
+
mmrLambda?: number;
|
|
282
|
+
/**
|
|
283
|
+
* Minimum candidate-pool size required for MMR to run. Defaults to
|
|
284
|
+
* the core `DEFAULT_MMR_MIN_POOL_SIZE`. Set to `0` to disable the
|
|
285
|
+
* small-pool gate entirely so MMR runs on every non-empty shortlist
|
|
286
|
+
* (the pre-phase-4 behavior).
|
|
287
|
+
*/
|
|
288
|
+
mmrMinPoolSize?: number;
|
|
289
|
+
/**
|
|
290
|
+
* Whether to apply the cross-encoder rerank stage when a
|
|
291
|
+
* `CrossEncoderPort` is wired. Defaults to `"enabled"`; evals can pass
|
|
292
|
+
* `"disabled"` to A/B the stage without unwiring the port.
|
|
293
|
+
*/
|
|
294
|
+
crossEncoder?: "enabled" | "disabled";
|
|
295
|
+
/**
|
|
296
|
+
* Optional top-K override for the cross-encoder shortlist. The stage
|
|
297
|
+
* reranks only the first K candidates after claim-key shaping and MMR
|
|
298
|
+
* diversification, so smaller values keep provider cost predictable.
|
|
299
|
+
*/
|
|
300
|
+
crossEncoderTopK?: number;
|
|
301
|
+
/**
|
|
302
|
+
* Blend weight for the cross-encoder score against the prior composite
|
|
303
|
+
* score. Final relevance becomes
|
|
304
|
+
* `alpha * crossEncoderScore + (1 - alpha) * compositeScore`.
|
|
305
|
+
* Clamped into the inclusive 0-1 range; defaults to `0.6`.
|
|
306
|
+
*/
|
|
307
|
+
crossEncoderAlpha?: number;
|
|
308
|
+
}
|
|
252
309
|
/**
|
|
253
310
|
* Optional execution controls for one recall call.
|
|
254
311
|
*/
|
|
@@ -257,6 +314,8 @@ interface RecallExecutionOptions {
|
|
|
257
314
|
trace?: RecallTraceSink;
|
|
258
315
|
/** Optional runtime slot-policy overrides used during claim-aware ranking. */
|
|
259
316
|
slotPolicyConfig?: ClaimSlotPolicyConfig;
|
|
317
|
+
/** Optional ranking policy overrides, including MMR toggles. */
|
|
318
|
+
rankingPolicy?: RecallRankingPolicy;
|
|
260
319
|
}
|
|
261
320
|
/**
|
|
262
321
|
* Returns the shared null-object recall trace sink used when no observation is requested.
|
|
@@ -265,6 +324,375 @@ interface RecallExecutionOptions {
|
|
|
265
324
|
*/
|
|
266
325
|
declare function createNoopRecallTraceSink(): RecallTraceSink;
|
|
267
326
|
|
|
327
|
+
/**
|
|
328
|
+
* Cross-encoder rerank orchestration helper.
|
|
329
|
+
*
|
|
330
|
+
* - Keeps core recall free of adapter concerns: the helper only needs a
|
|
331
|
+
* `CrossEncoderPort` contract defined in `src/core/ports.ts`.
|
|
332
|
+
* - Reranks only the top-K shortlist supplied by the caller. Candidates
|
|
333
|
+
* past the shortlist keep their input order and composite score.
|
|
334
|
+
* - Combines the provider score with the prior composite score through a
|
|
335
|
+
* linear blend: `alpha * crossEncoderScore + (1 - alpha) * prior`, so
|
|
336
|
+
* MMR, claim-key shaping, and seeded rerank still participate in the
|
|
337
|
+
* final ordering.
|
|
338
|
+
* - Fails closed: any thrown or malformed adapter response short-circuits
|
|
339
|
+
* into a pass-through result with a trace-visible degraded reason.
|
|
340
|
+
*
|
|
341
|
+
* The helper is pure and deterministic given a deterministic port: it
|
|
342
|
+
* does not mutate callers' inputs, does not read ambient state, and does
|
|
343
|
+
* not log.
|
|
344
|
+
*/
|
|
345
|
+
/**
|
|
346
|
+
* Default top-K shortlist size. Bounded small so cross-encoder latency
|
|
347
|
+
* and provider cost stay predictable even at full recall fan-out.
|
|
348
|
+
*/
|
|
349
|
+
declare const DEFAULT_CROSS_ENCODER_TOP_K = 10;
|
|
350
|
+
/**
|
|
351
|
+
* Default blend weight between the cross-encoder score and the prior
|
|
352
|
+
* composite score. Chosen to let the cross-encoder dominate while still
|
|
353
|
+
* letting prior shaping stages shape the final order.
|
|
354
|
+
*/
|
|
355
|
+
declare const DEFAULT_CROSS_ENCODER_ALPHA = 0.6;
|
|
356
|
+
/**
|
|
357
|
+
* One input candidate for the cross-encoder rerank helper.
|
|
358
|
+
*
|
|
359
|
+
* @template TCandidate - Caller-provided candidate shape passed through untouched.
|
|
360
|
+
*/
|
|
361
|
+
interface CrossEncoderRerankCandidate<TCandidate> {
|
|
362
|
+
/** Stable identifier used to correlate provider scores back to the candidate. */
|
|
363
|
+
id: string;
|
|
364
|
+
/** Caller-provided free-form text fed into the cross-encoder. */
|
|
365
|
+
text: string;
|
|
366
|
+
/** Prior composite score retained for the linear blend. */
|
|
367
|
+
score: number;
|
|
368
|
+
/** Original candidate reference returned to the caller. */
|
|
369
|
+
candidate: TCandidate;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Call options for `applyCrossEncoderRerank`.
|
|
373
|
+
*/
|
|
374
|
+
interface CrossEncoderRerankOptions<TCandidate> {
|
|
375
|
+
/** Natural-language recall query text. */
|
|
376
|
+
query: string;
|
|
377
|
+
/** Candidates in their caller-preferred order. */
|
|
378
|
+
candidates: readonly CrossEncoderRerankCandidate<TCandidate>[];
|
|
379
|
+
/** Cross-encoder port when available. When undefined, the stage skips. */
|
|
380
|
+
port: CrossEncoderPort | undefined;
|
|
381
|
+
/** Whether the caller explicitly disabled the stage. */
|
|
382
|
+
disabled?: boolean;
|
|
383
|
+
/** Optional top-K override. Clamped into `[1, candidates.length]`. */
|
|
384
|
+
topK?: number;
|
|
385
|
+
/** Optional blend weight override. Clamped into `[0, 1]`. */
|
|
386
|
+
alpha?: number;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Result returned by the cross-encoder rerank helper.
|
|
390
|
+
*
|
|
391
|
+
* @template TCandidate - Caller-provided candidate shape passed through untouched.
|
|
392
|
+
*/
|
|
393
|
+
interface CrossEncoderRerankResult<TCandidate> {
|
|
394
|
+
/** Whether the stage actually invoked the cross-encoder port. */
|
|
395
|
+
applied: boolean;
|
|
396
|
+
/** Effective top-K size used by the stage. */
|
|
397
|
+
k: number;
|
|
398
|
+
/** Effective blend weight used by the stage. */
|
|
399
|
+
alpha: number;
|
|
400
|
+
/** Wall-clock latency of the stage in milliseconds. */
|
|
401
|
+
latencyMs: number;
|
|
402
|
+
/** Stable degraded-mode reason when the stage did not rerank. */
|
|
403
|
+
degradedReason?: RecallCrossEncoderDegradedReason;
|
|
404
|
+
/**
|
|
405
|
+
* Candidates in their reranked order. Candidates past the shortlist
|
|
406
|
+
* keep their input order and their prior score.
|
|
407
|
+
*/
|
|
408
|
+
candidates: ReadonlyArray<{
|
|
409
|
+
/** Original candidate reference. */
|
|
410
|
+
candidate: TCandidate;
|
|
411
|
+
/** Final composite score after blending. */
|
|
412
|
+
score: number;
|
|
413
|
+
/** Raw cross-encoder score when the candidate was reranked. */
|
|
414
|
+
crossEncoderScore?: number;
|
|
415
|
+
}>;
|
|
416
|
+
/** Candidate IDs whose composite score was actually reshaped. */
|
|
417
|
+
rescoredIds: string[];
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Apply a cross-encoder rerank over the top-K shortlist of candidates.
|
|
421
|
+
*
|
|
422
|
+
* The helper is pure: no IO happens outside the provided
|
|
423
|
+
* `CrossEncoderPort`. The caller owns reading the resulting candidate
|
|
424
|
+
* order and merging the returned scores back into its ranking model.
|
|
425
|
+
*
|
|
426
|
+
* @template TCandidate - Candidate payload shape returned by the caller.
|
|
427
|
+
* @param options - Orchestration options including the port and limits.
|
|
428
|
+
* @returns Reranked candidates with trace-visible facts for diagnostics.
|
|
429
|
+
*/
|
|
430
|
+
declare function applyCrossEncoderRerank<TCandidate>(options: CrossEncoderRerankOptions<TCandidate>): Promise<CrossEncoderRerankResult<TCandidate>>;
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Reciprocal rank fusion (RRF) helpers used by entry, episode, and procedure
|
|
434
|
+
* recall to combine multiple retrieval channels into a single relevance signal.
|
|
435
|
+
*
|
|
436
|
+
* - A larger default constant (`k = 60`) matching the canonical Cormack et al.
|
|
437
|
+
* RRF paper so early ranks do not dominate the fused score.
|
|
438
|
+
* - A post-pass that normalizes scores into the `0-1` range so downstream
|
|
439
|
+
* composite scoring can mix fused relevance with recency and importance.
|
|
440
|
+
*/
|
|
441
|
+
/**
|
|
442
|
+
* Default RRF rank constant. The Cormack et al. RRF paper uses `k = 60` as a
|
|
443
|
+
* conservative anchor that flattens the contribution of the top handful of
|
|
444
|
+
* ranks without letting any single channel dominate.
|
|
445
|
+
*/
|
|
446
|
+
declare const DEFAULT_RRF_RANK_CONSTANT = 60;
|
|
447
|
+
/**
|
|
448
|
+
* One input channel of ranked identifiers.
|
|
449
|
+
*
|
|
450
|
+
* Each channel should be an ordered list from most-relevant to least-relevant,
|
|
451
|
+
* as produced by vector search, FTS, temporal match, or any other retrieval
|
|
452
|
+
* path. Channels may overlap or be disjoint and ties inside a channel are
|
|
453
|
+
* resolved by the caller before passing them in.
|
|
454
|
+
*/
|
|
455
|
+
type RrfChannel = readonly string[];
|
|
456
|
+
/**
|
|
457
|
+
* Fuse one or more ranked channels into a single normalized score map.
|
|
458
|
+
*
|
|
459
|
+
* An identifier's unnormalized RRF score is the sum across channels of
|
|
460
|
+
* `1 / (rankIndex + k)`, where `rankIndex` is the candidate's zero-based
|
|
461
|
+
* position inside that channel. Candidates missing from a channel contribute
|
|
462
|
+
* nothing from that channel.
|
|
463
|
+
*
|
|
464
|
+
* The result is then normalized by the theoretical maximum for the supplied
|
|
465
|
+
* channel count so that an identifier appearing at the top of every supplied
|
|
466
|
+
* channel maps to `1.0` and a single appearance in one of `N` channels maps
|
|
467
|
+
* to roughly `1/N` at the very top rank. Empty channels are ignored and do
|
|
468
|
+
* not count toward the normalization denominator.
|
|
469
|
+
*
|
|
470
|
+
* The helper is deliberately pure and side-effect free so the composite
|
|
471
|
+
* recall pipeline can invoke it for entries, episodes, and procedures
|
|
472
|
+
* without depending on any adapter.
|
|
473
|
+
*
|
|
474
|
+
* @param channels - Ordered rank lists from each retrieval channel.
|
|
475
|
+
* @param rankConstant - Optional override for the RRF rank constant `k`.
|
|
476
|
+
* @returns Map from identifier to normalized RRF score in the `0-1` range.
|
|
477
|
+
*/
|
|
478
|
+
declare function rrfFuse(channels: readonly RrfChannel[], rankConstant?: number): Map<string, number>;
|
|
479
|
+
/**
|
|
480
|
+
* Convenience wrapper for the common two-channel case used by entry and
|
|
481
|
+
* procedure recall.
|
|
482
|
+
*
|
|
483
|
+
* @param vectorRanks - Vector retrieval channel, most-relevant first.
|
|
484
|
+
* @param lexicalRanks - Lexical retrieval channel, most-relevant first.
|
|
485
|
+
* @param rankConstant - Optional override for the RRF rank constant `k`.
|
|
486
|
+
* @returns Map from identifier to normalized RRF score.
|
|
487
|
+
*/
|
|
488
|
+
declare function rrfFuseVectorLexical(vectorRanks: readonly string[], lexicalRanks: readonly string[], rankConstant?: number): Map<string, number>;
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Backend-agnostic lexical search tier used to plan adapter queries.
|
|
492
|
+
*/
|
|
493
|
+
type LexicalSearchTier = {
|
|
494
|
+
tier: "exact";
|
|
495
|
+
text: string;
|
|
496
|
+
} | {
|
|
497
|
+
tier: "all_tokens" | "any_tokens";
|
|
498
|
+
tokens: string[];
|
|
499
|
+
};
|
|
500
|
+
/**
|
|
501
|
+
* Tokenize free-form text into normalized lexical terms.
|
|
502
|
+
*
|
|
503
|
+
* @param text - Source text to tokenize.
|
|
504
|
+
* @returns Lowercased non-stopword tokens.
|
|
505
|
+
*/
|
|
506
|
+
declare function tokenize(text: string): string[];
|
|
507
|
+
/**
|
|
508
|
+
* Build a lexical search plan from raw user text.
|
|
509
|
+
*
|
|
510
|
+
* @param text - Raw query text.
|
|
511
|
+
* @returns Exact, all-token, and any-token tiers in cascade order.
|
|
512
|
+
*/
|
|
513
|
+
declare function buildLexicalPlan(text: string): LexicalSearchTier[];
|
|
514
|
+
/**
|
|
515
|
+
* Compute the lexical overlap score between a query and an entry.
|
|
516
|
+
*
|
|
517
|
+
* @param query - Raw recall query text.
|
|
518
|
+
* @param subject - Entry subject text.
|
|
519
|
+
* @param content - Entry content text.
|
|
520
|
+
* @returns Normalized lexical overlap signal in the 0-1 range.
|
|
521
|
+
*/
|
|
522
|
+
declare function computeLexicalScore(query: string, subject: string, content: string): number;
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Maximal Marginal Relevance (MMR) diversification helper used by entry,
|
|
526
|
+
* episode, and procedure recall.
|
|
527
|
+
*
|
|
528
|
+
* - Compute pairwise cosine similarity between every candidate embedding.
|
|
529
|
+
* - For each candidate, combine relevance (cosine similarity to the query)
|
|
530
|
+
* with a diversity penalty equal to the maximum pairwise similarity to
|
|
531
|
+
* any other candidate.
|
|
532
|
+
* - Sort candidates by the combined MMR score.
|
|
533
|
+
*
|
|
534
|
+
* Unlike the classical iterative MMR, the one-shot variant does not need
|
|
535
|
+
* the caller to track an already-selected set and produces a stable
|
|
536
|
+
* re-ranking directly from the candidate list. It is a good fit for the
|
|
537
|
+
* small shortlists that arrive after RRF, claim-key shaping, and seeded
|
|
538
|
+
* lineage rerank.
|
|
539
|
+
*/
|
|
540
|
+
/**
|
|
541
|
+
* Default MMR lambda chosen to favor relevance while still giving the
|
|
542
|
+
* diversity penalty room to demote near-duplicate candidates. Matches the
|
|
543
|
+
* value called out in the phase 3 plan.
|
|
544
|
+
*/
|
|
545
|
+
declare const DEFAULT_MMR_LAMBDA = 0.7;
|
|
546
|
+
/**
|
|
547
|
+
* Threshold above which two candidate embeddings are treated as near
|
|
548
|
+
* duplicates for trace accounting. Only influences the
|
|
549
|
+
* `droppedDuplicateCount` counter; it does not affect the MMR ordering.
|
|
550
|
+
*/
|
|
551
|
+
declare const NEAR_DUPLICATE_SIMILARITY = 0.95;
|
|
552
|
+
/**
|
|
553
|
+
* Input candidate consumed by the MMR helper.
|
|
554
|
+
*/
|
|
555
|
+
interface MmrCandidate {
|
|
556
|
+
/** Stable identifier used to match candidates back to the caller's list. */
|
|
557
|
+
id: string;
|
|
558
|
+
/** Optional embedding vector. Candidates without embeddings skip MMR. */
|
|
559
|
+
embedding?: number[];
|
|
560
|
+
/**
|
|
561
|
+
* Optional caller-provided relevance signal in the 0-1 range. When
|
|
562
|
+
* supplied, MMR uses this value as the relevance term instead of the
|
|
563
|
+
* default `cos(queryVector, embedding)` fallback.
|
|
564
|
+
*
|
|
565
|
+
* Pipelines that have already performed shaping (historical lineage
|
|
566
|
+
* boosts, claim-key trust and redundancy penalties) should pass their
|
|
567
|
+
* shaped composite score so MMR respects that prior work instead of
|
|
568
|
+
* silently undoing it.
|
|
569
|
+
*/
|
|
570
|
+
relevance?: number;
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* MMR reorder outcome returned to the caller.
|
|
574
|
+
*/
|
|
575
|
+
interface MmrReorderResult {
|
|
576
|
+
/** Whether MMR actually ran instead of passing through the input order. */
|
|
577
|
+
applied: boolean;
|
|
578
|
+
/** Effective lambda that was used during ranking. */
|
|
579
|
+
lambda: number;
|
|
580
|
+
/** Reordered candidate IDs. Includes every input candidate exactly once. */
|
|
581
|
+
orderedIds: string[];
|
|
582
|
+
/**
|
|
583
|
+
* Number of candidates that MMR identified as near duplicates (max
|
|
584
|
+
* pairwise similarity with another candidate at or above
|
|
585
|
+
* `NEAR_DUPLICATE_SIMILARITY`) and pushed down in the final order.
|
|
586
|
+
*/
|
|
587
|
+
droppedDuplicateCount: number;
|
|
588
|
+
/**
|
|
589
|
+
* IDs whose position changed from the input order as a result of MMR
|
|
590
|
+
* re-ranking. Empty when MMR was skipped.
|
|
591
|
+
*/
|
|
592
|
+
reorderedIds: string[];
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* MMR call signature.
|
|
596
|
+
*/
|
|
597
|
+
interface MmrOptions {
|
|
598
|
+
/** Query embedding used as the relevance signal. */
|
|
599
|
+
queryVector: number[];
|
|
600
|
+
/** Candidates in their caller-preferred order. */
|
|
601
|
+
candidates: readonly MmrCandidate[];
|
|
602
|
+
/** Optional lambda override. Clamped into `[0, 1]`. */
|
|
603
|
+
lambda?: number;
|
|
604
|
+
/** Optional final result limit applied after MMR ordering. */
|
|
605
|
+
limit?: number;
|
|
606
|
+
/**
|
|
607
|
+
* Optional minimum pool size required for MMR to run. Defaults to
|
|
608
|
+
* `DEFAULT_MMR_MIN_POOL_SIZE`. When `candidates.length` is at or below
|
|
609
|
+
* this size, MMR returns `applied: false` with the input order
|
|
610
|
+
* preserved. Set to `0` to disable the gate entirely.
|
|
611
|
+
*/
|
|
612
|
+
minPoolSize?: number;
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Reorder candidates by maximal marginal relevance.
|
|
616
|
+
*
|
|
617
|
+
* The helper is pure and does not mutate any input. Candidates without a
|
|
618
|
+
* usable embedding keep their input order after the embedded candidates,
|
|
619
|
+
* so missing-embedding fallbacks degrade to pass-through rather than
|
|
620
|
+
* crashing. When the query vector is empty or at most one candidate has
|
|
621
|
+
* an embedding, MMR is skipped and the input order is returned as-is.
|
|
622
|
+
*
|
|
623
|
+
* @param options - Query embedding plus candidate list and tuning knobs.
|
|
624
|
+
* @returns Reorder result with ordered IDs, MMR scores, and trace facts.
|
|
625
|
+
*/
|
|
626
|
+
declare function maximalMarginalRelevance(options: MmrOptions): MmrReorderResult;
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Score breakdown returned for a ranked recall candidate.
|
|
630
|
+
*/
|
|
631
|
+
interface CandidateScore {
|
|
632
|
+
score: number;
|
|
633
|
+
scores: {
|
|
634
|
+
relevance: number;
|
|
635
|
+
vector: number;
|
|
636
|
+
lexical: number;
|
|
637
|
+
recency: number;
|
|
638
|
+
importance: number;
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
/**
|
|
642
|
+
* Compute the tier-aware half-life recency score for an entry.
|
|
643
|
+
*
|
|
644
|
+
* @param createdAt - Entry creation timestamp.
|
|
645
|
+
* @param expiry - Entry durability tier.
|
|
646
|
+
* @param now - Reference time for the age calculation.
|
|
647
|
+
* @returns Normalized recency score in the 0-1 range.
|
|
648
|
+
*/
|
|
649
|
+
declare function recencyScore(createdAt: Date | string, expiry: Expiry, now?: Date): number;
|
|
650
|
+
/**
|
|
651
|
+
* Compute a gaussian recency score centered on an around-date query anchor.
|
|
652
|
+
*
|
|
653
|
+
* @param createdAt - Entry creation timestamp.
|
|
654
|
+
* @param aroundDate - Temporal anchor inferred or provided by the user.
|
|
655
|
+
* @param radiusDays - Standard deviation-like radius in days.
|
|
656
|
+
* @returns Normalized temporal proximity score in the 0-1 range.
|
|
657
|
+
*/
|
|
658
|
+
declare function gaussianRecency(createdAt: Date | string, aroundDate: Date, radiusDays: number): number;
|
|
659
|
+
/**
|
|
660
|
+
* Normalize an importance value from the 1-10 domain into the 0.4-1.0 score range.
|
|
661
|
+
*
|
|
662
|
+
* @param importance - Raw entry importance.
|
|
663
|
+
* @returns Normalized importance score in the 0-1 range.
|
|
664
|
+
*/
|
|
665
|
+
declare function importanceScore(importance: number): number;
|
|
666
|
+
/**
|
|
667
|
+
* Compute the final recall score and its component breakdown for a candidate.
|
|
668
|
+
*
|
|
669
|
+
* Callers are expected to supply the fused `relevance` signal through
|
|
670
|
+
* reciprocal rank fusion. `vectorSim` and `lexical` are kept on the score
|
|
671
|
+
* breakdown as evidence-only diagnostics so trace summaries can still
|
|
672
|
+
* display the raw retrieval signals without influencing the composite.
|
|
673
|
+
*
|
|
674
|
+
* @param params - Candidate signal inputs.
|
|
675
|
+
* @returns Final score plus signal breakdown.
|
|
676
|
+
*/
|
|
677
|
+
declare function scoreCandidate(params: {
|
|
678
|
+
relevance: number;
|
|
679
|
+
vectorSim: number;
|
|
680
|
+
lexical: number;
|
|
681
|
+
recency: number;
|
|
682
|
+
importance: number;
|
|
683
|
+
}): CandidateScore;
|
|
684
|
+
/**
|
|
685
|
+
* Compute cosine similarity between two numeric vectors.
|
|
686
|
+
*
|
|
687
|
+
* Non-finite coordinates are treated as zero and negative similarities are clamped
|
|
688
|
+
* to zero because recall scoring only consumes a 0-1 signal.
|
|
689
|
+
*
|
|
690
|
+
* @param left - Left-hand vector.
|
|
691
|
+
* @param right - Right-hand vector.
|
|
692
|
+
* @returns Cosine similarity in the 0-1 range.
|
|
693
|
+
*/
|
|
694
|
+
declare function cosineSimilarity(left: number[], right: number[]): number;
|
|
695
|
+
|
|
268
696
|
/**
|
|
269
697
|
* Execute the v1 recall pipeline against the provided adapter ports.
|
|
270
698
|
*
|
|
@@ -292,4 +720,4 @@ declare function inferAroundDate(text: string, now?: Date): Date | null;
|
|
|
292
720
|
*/
|
|
293
721
|
declare function parseRelativeDate(input: string, now?: Date): Date | null;
|
|
294
722
|
|
|
295
|
-
export { type RecallClaimKeyTrace, type RecallCoreCandidateCountsTrace, type RecallCoreTimingTrace, type RecallDegradedReason, type RecallDegradedTrace, type RecallExecutionOptions, type RecallExecutionTraceSummary, type RecallFilterTrace, RecallInput, type RecallNoResultReason, RecallOutput, type RecallRankingTrace, type RecallTraceSink,
|
|
723
|
+
export { type CrossEncoderRerankCandidate, type CrossEncoderRerankOptions, type CrossEncoderRerankResult, DEFAULT_CROSS_ENCODER_ALPHA, DEFAULT_CROSS_ENCODER_TOP_K, DEFAULT_MMR_LAMBDA, DEFAULT_RRF_RANK_CONSTANT, type MmrCandidate, type MmrOptions, type MmrReorderResult, NEAR_DUPLICATE_SIMILARITY, type RecallClaimKeyTrace, type RecallCoreCandidateCountsTrace, type RecallCoreTimingTrace, type RecallCrossEncoderDegradedReason, type RecallCrossEncoderTrace, type RecallDegradedReason, type RecallDegradedTrace, type RecallExecutionOptions, type RecallExecutionTraceSummary, type RecallFilterTrace, RecallInput, type RecallMmrTrace, type RecallNeighborhoodTrace, type RecallNoResultReason, RecallOutput, type RecallRankingPolicy, type RecallRankingTrace, type RecallRrfTrace, type RecallTraceSink, type RrfChannel, applyCrossEncoderRerank, buildLexicalPlan, computeLexicalScore, cosineSimilarity, createNoopRecallTraceSink, gaussianRecency, importanceScore, inferAroundDate, maximalMarginalRelevance, parseRelativeDate, recall, recencyScore, rrfFuse, rrfFuseVectorLexical, scoreCandidate, tokenize };
|