llmbic 1.7.0 → 1.8.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 +15 -0
- package/README.md +34 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/merge.d.ts +43 -2
- package/dist/merge.d.ts.map +1 -1
- package/dist/merge.js +194 -71
- package/dist/merge.js.map +1 -1
- package/dist/types/reconcile.types.d.ts +131 -0
- package/dist/types/reconcile.types.d.ts.map +1 -0
- package/dist/types/reconcile.types.js +2 -0
- package/dist/types/reconcile.types.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.8.0] - 2026-05-27
|
|
9
|
+
|
|
10
|
+
Non-breaking. New `merge.reconcile` primitive: the N-ary generalization of `merge.field`. Where `merge.field` fuses a fixed (rule, llm) pair, `merge.reconcile` fuses any number of candidate sources - several rules, an LLM, external services, manual overrides - under a single policy. Agreement detection becomes cardinal (two or more concurring candidates raise confidence), and a `priority` field replaces the hard-coded rule/llm asymmetry. `merge.field` is now a thin binary adapter over `merge.reconcile`, with identical behavior.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `merge.reconcile<T>(field, candidates, policy?)` - reconciles N `Candidate<T>` (`{ value, confidence, source, priority? }`) into a `ReconcileResult<T>` (`{ value, confidence, source, conflicts }`). `source` records the winning candidate, the candidates that agreed, and those that dissented.
|
|
15
|
+
- `ReconcileStrategy`: `'highest-priority'`, `'highest-confidence'`, `'cascade'`, `'flag-on-conflict'`, `'prefer-when-confident'`. The legacy binary strategies map onto these (e.g. `'prefer-llm'` = `'highest-priority'` with the LLM ranked first; `'flag'` = `'flag-on-conflict'`).
|
|
16
|
+
- `merge.defaultReconcilePolicy` - library defaults for `merge.reconcile` (strategy `'flag-on-conflict'`, `agreementConfidence` `1`, `conflictConfidence` `0.3`, `confidentThreshold` `1`, case-insensitive `compare`).
|
|
17
|
+
- New exported types: `Candidate`, `ReconcilePolicy`, `ReconcileStrategy`, `ReconcileSource`, `ReconcileSourceKind`, `ReconcileConflict`, `ReconcileResult`.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- `merge.field` is re-implemented as a binary adapter over `merge.reconcile`. Behavior, return shape, and `FieldSource` resolution are unchanged (full parity covered by the existing field tests).
|
|
22
|
+
|
|
8
23
|
## [1.7.0] - 2026-05-18
|
|
9
24
|
|
|
10
25
|
Non-breaking. New conflict strategy `'prefer-rule-when-confident'` lets a rule win over the LLM only when its confidence clears a configurable threshold (default `1`), otherwise the LLM wins. Designed for fields where a perfectly-canonical regex outranks a noisy LLM extraction, while weaker rule hints still defer to the LLM. Closes the gap between `'prefer-rule'` (always trust the rule) and `'prefer-llm'` (always trust the LLM).
|
package/README.md
CHANGED
|
@@ -246,6 +246,40 @@ const extractor = createExtractor({
|
|
|
246
246
|
|
|
247
247
|
You can override any subset of `FieldMergePolicy` per field - strategy, confidences, even the `compare` callback (e.g. fuzzy equality for free-form strings). TypeScript validates field names against your schema, so typos surface at compile time.
|
|
248
248
|
|
|
249
|
+
### Reconciling N sources
|
|
250
|
+
|
|
251
|
+
`merge.field` fuses exactly two candidates (a rule and the LLM). When a field is fed by **more than two** sources - several rules, the LLM, an external service, a manual override - reach for `merge.reconcile`, the N-ary generalization. `merge.field` is itself a thin binary adapter over it.
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
import { merge } from 'llmbic';
|
|
255
|
+
|
|
256
|
+
const result = merge.reconcile<number>('total', [
|
|
257
|
+
{ value: 1250, confidence: 1, source: 'rule:invoice-line' },
|
|
258
|
+
{ value: 1250, confidence: 0.8, source: 'llm' },
|
|
259
|
+
{ value: 1300, confidence: 0.6, source: 'ocr' },
|
|
260
|
+
], { strategy: 'highest-priority' });
|
|
261
|
+
|
|
262
|
+
// result.value -> 1250
|
|
263
|
+
// result.confidence -> 1 (agreementConfidence: two sources agree)
|
|
264
|
+
// result.source -> { kind: 'agreement', winner: 'rule:invoice-line',
|
|
265
|
+
// agreedBy: ['rule:invoice-line', 'llm'], dissentedBy: ['ocr'] }
|
|
266
|
+
// result.conflicts -> [{ field: 'total', winner: {...}, dissenter: { source: 'ocr', value: 1300, ... } }]
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Each `Candidate<T>` carries a `value`, a `confidence`, a `source` id, and an optional `priority` (higher wins; defaults to array order, earlier ranks higher). Agreement is **cardinal**: two or more candidates sharing the kept value (per `compare`) raise the confidence to `agreementConfidence`, whatever the strategy, and every dissenter is reported in `conflicts`.
|
|
270
|
+
|
|
271
|
+
Five strategies decide which single candidate wins:
|
|
272
|
+
|
|
273
|
+
| Strategy | Keeps |
|
|
274
|
+
|---|---|
|
|
275
|
+
| `'highest-priority'` | the most authoritative candidate (ties broken by confidence) |
|
|
276
|
+
| `'highest-confidence'` | the most confident candidate (ties broken by priority) |
|
|
277
|
+
| `'cascade'` | the first candidate, in array order, whose confidence clears `confidentThreshold`; `null` if none do |
|
|
278
|
+
| `'flag-on-conflict'` | the most authoritative candidate, lowering confidence to `conflictConfidence` and marking `source.kind: 'conflict'` when any candidate disagrees |
|
|
279
|
+
| `'prefer-when-confident'` | the highest-priority candidate clearing `confidentThreshold`, else the lowest-priority fallback |
|
|
280
|
+
|
|
281
|
+
Omitted policy fields fall back to `merge.defaultReconcilePolicy`.
|
|
282
|
+
|
|
249
283
|
### Cross-check mode
|
|
250
284
|
|
|
251
285
|
Switch the LLM call from fill-gaps (ask only about missing fields) to cross-check (ask about every schema field, whether the rules resolved it or not):
|
package/dist/index.d.ts
CHANGED
|
@@ -21,4 +21,5 @@ export type { LlmProvider } from './types/provider.types.js';
|
|
|
21
21
|
export type { Logger } from './types/logger.types.js';
|
|
22
22
|
export type { Severity, Violation, Validator, } from './types/validate.types.js';
|
|
23
23
|
export type { Conflict, ConflictStrategy, ExtractedData, ExtractionMeta, ExtractionResult, FieldCompare, FieldMergePolicy, FieldMergeResult, FieldSource, LlmResult, MergeApplyOptions, Normalizer, NormalizerMutation, ValidationResult, } from './types/merge.types.js';
|
|
24
|
+
export type { Candidate, ReconcilePolicy, ReconcileStrategy, ReconcileSource, ReconcileSourceKind, ReconcileConflict, ReconcileResult, } from './types/reconcile.types.js';
|
|
24
25
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,YAAY,EACV,cAAc,EACd,SAAS,EACT,WAAW,GACZ,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,SAAS,EACT,eAAe,EACf,kBAAkB,GACnB,MAAM,4BAA4B,CAAC;AAEpC,YAAY,EACV,eAAe,EACf,UAAU,EACV,eAAe,EACf,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,YAAY,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,YAAY,EACV,QAAQ,EACR,SAAS,EACT,SAAS,GACV,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EACV,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,YAAY,EACV,cAAc,EACd,SAAS,EACT,WAAW,GACZ,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,SAAS,EACT,eAAe,EACf,kBAAkB,GACnB,MAAM,4BAA4B,CAAC;AAEpC,YAAY,EACV,eAAe,EACf,UAAU,EACV,eAAe,EACf,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,YAAY,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,YAAY,EACV,QAAQ,EACR,SAAS,EACT,SAAS,GACV,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EACV,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EACV,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,GAChB,MAAM,4BAA4B,CAAC"}
|
package/dist/merge.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { z } from 'zod';
|
|
|
2
2
|
import type { Logger } from './types/logger.types.js';
|
|
3
3
|
import type { RuleMatch, RulesResult } from './types/rule.types.js';
|
|
4
4
|
import type { ExtractionResult, FieldMergePolicy, FieldMergeResult, LlmResult, MergeApplyOptions, Normalizer } from './types/merge.types.js';
|
|
5
|
+
import type { Candidate, ReconcilePolicy, ReconcileResult } from './types/reconcile.types.js';
|
|
5
6
|
/**
|
|
6
7
|
* Field-level and object-level merge primitives.
|
|
7
8
|
*
|
|
@@ -30,6 +31,44 @@ export declare const merge: {
|
|
|
30
31
|
/** See {@link FieldMergePolicy.ruleConfidenceThreshold}. */
|
|
31
32
|
ruleConfidenceThreshold: number;
|
|
32
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* Library defaults applied by {@link merge.reconcile} when the caller omits
|
|
36
|
+
* one or more policy fields. Mirrors {@link merge.defaultFieldPolicy}: the
|
|
37
|
+
* default `'flag-on-conflict'` strategy keeps the most authoritative
|
|
38
|
+
* candidate while surfacing disagreements, and agreement boosts confidence
|
|
39
|
+
* to `1`.
|
|
40
|
+
*
|
|
41
|
+
* See {@link ReconcilePolicy} for the meaning of each field.
|
|
42
|
+
*/
|
|
43
|
+
defaultReconcilePolicy: {
|
|
44
|
+
strategy: "flag-on-conflict";
|
|
45
|
+
compare: (a: unknown, b: unknown) => boolean;
|
|
46
|
+
agreementConfidence: number;
|
|
47
|
+
conflictConfidence: number;
|
|
48
|
+
confidentThreshold: number;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Reconcile N candidate values for a single field into one kept value, its
|
|
52
|
+
* confidence, and its provenance. The N-ary generalization of
|
|
53
|
+
* {@link merge.field}: instead of a fixed (rule, llm) pair, any number of
|
|
54
|
+
* sources - rules, an LLM, external services, human overrides - compete
|
|
55
|
+
* under a {@link ReconcilePolicy}.
|
|
56
|
+
*
|
|
57
|
+
* Agreement is cardinal: two or more candidates sharing the kept value (per
|
|
58
|
+
* `compare`) raise the confidence to `agreementConfidence`, whatever the
|
|
59
|
+
* strategy. Every dissenting candidate is reported in `conflicts` for
|
|
60
|
+
* observability; `source.kind` records whether the value stands alone, on an
|
|
61
|
+
* agreement, despite a conflict, or after a cascade fall-through.
|
|
62
|
+
*
|
|
63
|
+
* Any policy field omitted from `policy` falls back to
|
|
64
|
+
* {@link merge.defaultReconcilePolicy}.
|
|
65
|
+
*
|
|
66
|
+
* @typeParam T - Type of the candidate values.
|
|
67
|
+
* @param field - Name of the field being reconciled (echoed into conflicts).
|
|
68
|
+
* @param candidates - One entry per source; `null`/`undefined` values are absent.
|
|
69
|
+
* @param policy - Optional strategy and confidence overrides.
|
|
70
|
+
*/
|
|
71
|
+
reconcile<T>(field: string, candidates: Candidate<T>[], policy?: Partial<ReconcilePolicy>): ReconcileResult<T>;
|
|
33
72
|
/**
|
|
34
73
|
* Fuse a rule match and an LLM value for a single field, following the
|
|
35
74
|
* provided policy. Returns the kept value, its confidence, and a conflict
|
|
@@ -38,8 +77,10 @@ export declare const merge: {
|
|
|
38
77
|
* Any policy field omitted from `policy` falls back to
|
|
39
78
|
* {@link merge.defaultFieldPolicy}.
|
|
40
79
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
80
|
+
* Thin binary adapter over {@link merge.reconcile}: the rule and the LLM
|
|
81
|
+
* become two candidates, the conflict strategy maps to a reconcile strategy
|
|
82
|
+
* plus a priority order, and the result is projected back onto the binary
|
|
83
|
+
* contract (rule value kept on agreement, conflict recorded only on flag).
|
|
43
84
|
*
|
|
44
85
|
* @typeParam T - Type of the rule value.
|
|
45
86
|
* @param field - Name of the field being merged.
|
package/dist/merge.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpE,OAAO,KAAK,EAGV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAEhB,SAAS,EACT,iBAAiB,EACjB,UAAU,EAEX,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpE,OAAO,KAAK,EAGV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAEhB,SAAS,EACT,iBAAiB,EACjB,UAAU,EAEX,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EACV,SAAS,EAET,eAAe,EACf,eAAe,EAIhB,MAAM,4BAA4B,CAAC;AA6QpC;;;;;GAKG;AACH,eAAO,MAAM,KAAK;IAChB;;;;;;OAMG;;QAED,6CAA6C;;QAE7C,yDAAyD;;QAEzD,sDAAsD;;QAEtD,wDAAwD;;QAExD,qGAAqG;qBA3R9E,OAAO,KAAK,OAAO,KAAG,OAAO;QA6RpD,4DAA4D;;;IAI9D;;;;;;;;OAQG;;;qBAzSsB,OAAO,KAAK,OAAO,KAAG,OAAO;;;;;IAkTtD;;;;;;;;;;;;;;;;;;;;OAoBG;cACO,CAAC,SACF,MAAM,cACD,SAAS,CAAC,CAAC,CAAC,EAAE,WACjB,OAAO,CAAC,eAAe,CAAC,GAChC,eAAe,CAAC,CAAC,CAAC;IAmErB;;;;;;;;;;;;;;;;;;;;;;OAsBG;UACG,CAAC,SACE,MAAM,aACF,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,YACpB,OAAO,WACR,OAAO,CAAC,gBAAgB,CAAC,WACzB,MAAM,GACd,gBAAgB,CAAC,CAAC,CAAC;IA0EtB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;UACG,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,QAAQ,oBAC1C,CAAC,eACI,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,aACzB,SAAS,GAAG,IAAI,WAClB,MAAM,YACL,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,YACvC,QAAQ,GACjB,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;CA2ChC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO,EACpD,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,QAAQ,CAAC,GAC7B,UAAU,CAAC,CAAC,EAAE,QAAQ,CAAC,CAIzB"}
|
package/dist/merge.js
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
import { valueEquals } from './utils/value-equals.js';
|
|
2
2
|
import { resolveNormalizerId } from './utils/normalizer-id.js';
|
|
3
|
+
/**
|
|
4
|
+
* Default equality: case-insensitive for strings, strict otherwise. Shared by
|
|
5
|
+
* {@link merge.defaultFieldPolicy} and {@link merge.defaultReconcilePolicy} so
|
|
6
|
+
* the binary and N-ary merges agree on what "the same value" means.
|
|
7
|
+
*/
|
|
8
|
+
const defaultCompare = (a, b) => {
|
|
9
|
+
if (typeof a === 'string' && typeof b === 'string') {
|
|
10
|
+
return a.toLowerCase() === b.toLowerCase();
|
|
11
|
+
}
|
|
12
|
+
return a === b;
|
|
13
|
+
};
|
|
14
|
+
/** Order by priority desc, then confidence desc, then original position asc. */
|
|
15
|
+
function byAuthority(a, b) {
|
|
16
|
+
return (b.priority - a.priority ||
|
|
17
|
+
b.candidate.confidence - a.candidate.confidence ||
|
|
18
|
+
a.index - b.index);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Pick the winning candidate per strategy. Returns `null` only for `'cascade'`
|
|
22
|
+
* when no tier clears the threshold. `present` is non-empty and in input order.
|
|
23
|
+
*/
|
|
24
|
+
function selectWinner(present, policy) {
|
|
25
|
+
switch (policy.strategy) {
|
|
26
|
+
case 'highest-confidence':
|
|
27
|
+
return [...present].sort((a, b) => b.candidate.confidence - a.candidate.confidence ||
|
|
28
|
+
b.priority - a.priority ||
|
|
29
|
+
a.index - b.index)[0];
|
|
30
|
+
case 'cascade':
|
|
31
|
+
return present.find((e) => e.candidate.confidence >= policy.confidentThreshold) ?? null;
|
|
32
|
+
case 'prefer-when-confident': {
|
|
33
|
+
const ranked = [...present].sort(byAuthority);
|
|
34
|
+
return (ranked.find((e) => e.candidate.confidence >= policy.confidentThreshold) ??
|
|
35
|
+
ranked[ranked.length - 1]);
|
|
36
|
+
}
|
|
37
|
+
case 'highest-priority':
|
|
38
|
+
case 'flag-on-conflict':
|
|
39
|
+
default:
|
|
40
|
+
return [...present].sort(byAuthority)[0];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
3
43
|
/**
|
|
4
44
|
* Walk every schema field, build the {@link RuleMatch} if rules produced a
|
|
5
45
|
* value, fuse it with the LLM candidate via {@link merge.field}, and collect
|
|
@@ -181,15 +221,105 @@ export const merge = {
|
|
|
181
221
|
/** See {@link FieldMergePolicy.agreementConfidence}. */
|
|
182
222
|
agreementConfidence: 1.0,
|
|
183
223
|
/** See {@link FieldMergePolicy.compare}. Case-insensitive for strings, strict equality otherwise. */
|
|
184
|
-
compare:
|
|
185
|
-
if (typeof a === 'string' && typeof b === 'string') {
|
|
186
|
-
return a.toLowerCase() === b.toLowerCase();
|
|
187
|
-
}
|
|
188
|
-
return a === b;
|
|
189
|
-
},
|
|
224
|
+
compare: defaultCompare,
|
|
190
225
|
/** See {@link FieldMergePolicy.ruleConfidenceThreshold}. */
|
|
191
226
|
ruleConfidenceThreshold: 1,
|
|
192
227
|
},
|
|
228
|
+
/**
|
|
229
|
+
* Library defaults applied by {@link merge.reconcile} when the caller omits
|
|
230
|
+
* one or more policy fields. Mirrors {@link merge.defaultFieldPolicy}: the
|
|
231
|
+
* default `'flag-on-conflict'` strategy keeps the most authoritative
|
|
232
|
+
* candidate while surfacing disagreements, and agreement boosts confidence
|
|
233
|
+
* to `1`.
|
|
234
|
+
*
|
|
235
|
+
* See {@link ReconcilePolicy} for the meaning of each field.
|
|
236
|
+
*/
|
|
237
|
+
defaultReconcilePolicy: {
|
|
238
|
+
strategy: 'flag-on-conflict',
|
|
239
|
+
compare: defaultCompare,
|
|
240
|
+
agreementConfidence: 1.0,
|
|
241
|
+
conflictConfidence: 0.3,
|
|
242
|
+
confidentThreshold: 1,
|
|
243
|
+
},
|
|
244
|
+
/**
|
|
245
|
+
* Reconcile N candidate values for a single field into one kept value, its
|
|
246
|
+
* confidence, and its provenance. The N-ary generalization of
|
|
247
|
+
* {@link merge.field}: instead of a fixed (rule, llm) pair, any number of
|
|
248
|
+
* sources - rules, an LLM, external services, human overrides - compete
|
|
249
|
+
* under a {@link ReconcilePolicy}.
|
|
250
|
+
*
|
|
251
|
+
* Agreement is cardinal: two or more candidates sharing the kept value (per
|
|
252
|
+
* `compare`) raise the confidence to `agreementConfidence`, whatever the
|
|
253
|
+
* strategy. Every dissenting candidate is reported in `conflicts` for
|
|
254
|
+
* observability; `source.kind` records whether the value stands alone, on an
|
|
255
|
+
* agreement, despite a conflict, or after a cascade fall-through.
|
|
256
|
+
*
|
|
257
|
+
* Any policy field omitted from `policy` falls back to
|
|
258
|
+
* {@link merge.defaultReconcilePolicy}.
|
|
259
|
+
*
|
|
260
|
+
* @typeParam T - Type of the candidate values.
|
|
261
|
+
* @param field - Name of the field being reconciled (echoed into conflicts).
|
|
262
|
+
* @param candidates - One entry per source; `null`/`undefined` values are absent.
|
|
263
|
+
* @param policy - Optional strategy and confidence overrides.
|
|
264
|
+
*/
|
|
265
|
+
reconcile(field, candidates, policy) {
|
|
266
|
+
const fullPolicy = { ...merge.defaultReconcilePolicy, ...policy };
|
|
267
|
+
const total = candidates.length;
|
|
268
|
+
const present = candidates
|
|
269
|
+
.map((candidate, index) => ({
|
|
270
|
+
candidate,
|
|
271
|
+
index,
|
|
272
|
+
priority: candidate.priority ?? total - index,
|
|
273
|
+
}))
|
|
274
|
+
.filter((e) => e.candidate.value !== null && e.candidate.value !== undefined);
|
|
275
|
+
if (present.length === 0) {
|
|
276
|
+
return { value: null, confidence: null, source: null, conflicts: [] };
|
|
277
|
+
}
|
|
278
|
+
const winner = selectWinner(present, fullPolicy);
|
|
279
|
+
if (winner === null) {
|
|
280
|
+
return { value: null, confidence: null, source: null, conflicts: [] };
|
|
281
|
+
}
|
|
282
|
+
const agreed = present.filter((e) => fullPolicy.compare(e.candidate.value, winner.candidate.value));
|
|
283
|
+
const dissenters = present.filter((e) => !fullPolicy.compare(e.candidate.value, winner.candidate.value));
|
|
284
|
+
let kind;
|
|
285
|
+
let confidence;
|
|
286
|
+
if (agreed.length >= 2) {
|
|
287
|
+
kind = 'agreement';
|
|
288
|
+
confidence = fullPolicy.agreementConfidence;
|
|
289
|
+
}
|
|
290
|
+
else if (fullPolicy.strategy === 'flag-on-conflict' && dissenters.length > 0) {
|
|
291
|
+
kind = 'conflict';
|
|
292
|
+
confidence = fullPolicy.conflictConfidence;
|
|
293
|
+
}
|
|
294
|
+
else if (fullPolicy.strategy === 'cascade' && winner.index !== present[0].index) {
|
|
295
|
+
kind = 'cascade';
|
|
296
|
+
confidence = winner.candidate.confidence;
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
kind = 'single';
|
|
300
|
+
confidence = winner.candidate.confidence;
|
|
301
|
+
}
|
|
302
|
+
const conflicts = dissenters.map((d) => ({
|
|
303
|
+
field,
|
|
304
|
+
winner: {
|
|
305
|
+
source: winner.candidate.source,
|
|
306
|
+
value: winner.candidate.value,
|
|
307
|
+
confidence: winner.candidate.confidence,
|
|
308
|
+
},
|
|
309
|
+
dissenter: {
|
|
310
|
+
source: d.candidate.source,
|
|
311
|
+
value: d.candidate.value,
|
|
312
|
+
confidence: d.candidate.confidence,
|
|
313
|
+
},
|
|
314
|
+
}));
|
|
315
|
+
const source = {
|
|
316
|
+
kind,
|
|
317
|
+
winner: winner.candidate.source,
|
|
318
|
+
agreedBy: agreed.map((e) => e.candidate.source),
|
|
319
|
+
dissentedBy: dissenters.map((e) => e.candidate.source),
|
|
320
|
+
};
|
|
321
|
+
return { value: winner.candidate.value, confidence, source, conflicts };
|
|
322
|
+
},
|
|
193
323
|
/**
|
|
194
324
|
* Fuse a rule match and an LLM value for a single field, following the
|
|
195
325
|
* provided policy. Returns the kept value, its confidence, and a conflict
|
|
@@ -198,8 +328,10 @@ export const merge = {
|
|
|
198
328
|
* Any policy field omitted from `policy` falls back to
|
|
199
329
|
* {@link merge.defaultFieldPolicy}.
|
|
200
330
|
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
331
|
+
* Thin binary adapter over {@link merge.reconcile}: the rule and the LLM
|
|
332
|
+
* become two candidates, the conflict strategy maps to a reconcile strategy
|
|
333
|
+
* plus a priority order, and the result is projected back onto the binary
|
|
334
|
+
* contract (rule value kept on agreement, conflict recorded only on flag).
|
|
203
335
|
*
|
|
204
336
|
* @typeParam T - Type of the rule value.
|
|
205
337
|
* @param field - Name of the field being merged.
|
|
@@ -214,74 +346,65 @@ export const merge = {
|
|
|
214
346
|
field(field, ruleMatch, llmValue, policy, logger) {
|
|
215
347
|
const fullPolicy = { ...merge.defaultFieldPolicy, ...policy };
|
|
216
348
|
const normalizedLlm = llmValue ?? null;
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
return {
|
|
243
|
-
value: ruleMatch.value,
|
|
244
|
-
confidence: ruleMatch.confidence,
|
|
245
|
-
conflict: undefined,
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
if (fullPolicy.strategy === 'prefer-llm') {
|
|
249
|
-
return {
|
|
250
|
-
value: normalizedLlm,
|
|
251
|
-
confidence: fullPolicy.defaultLlmConfidence,
|
|
252
|
-
conflict: undefined,
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
if (fullPolicy.strategy === 'prefer-rule-when-confident') {
|
|
256
|
-
if (ruleMatch.confidence >= fullPolicy.ruleConfidenceThreshold) {
|
|
257
|
-
return {
|
|
258
|
-
value: ruleMatch.value,
|
|
259
|
-
confidence: ruleMatch.confidence,
|
|
260
|
-
conflict: undefined,
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
return {
|
|
264
|
-
value: normalizedLlm,
|
|
265
|
-
confidence: fullPolicy.defaultLlmConfidence,
|
|
266
|
-
conflict: undefined,
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
if (fullPolicy.strategy !== 'flag') {
|
|
270
|
-
logger?.warn('unknown conflict strategy, falling back to flag', {
|
|
271
|
-
strategy: fullPolicy.strategy,
|
|
272
|
-
field,
|
|
273
|
-
});
|
|
349
|
+
// Map the binary (rule, llm) policy onto the N-ary reconcile engine: the
|
|
350
|
+
// two roles become two candidates, and the conflict strategy becomes a
|
|
351
|
+
// reconcile strategy plus a priority order (which side outranks the other).
|
|
352
|
+
let strategy;
|
|
353
|
+
let ruleOutranksLlm = true;
|
|
354
|
+
switch (fullPolicy.strategy) {
|
|
355
|
+
case 'prefer-rule':
|
|
356
|
+
strategy = 'highest-priority';
|
|
357
|
+
break;
|
|
358
|
+
case 'prefer-llm':
|
|
359
|
+
strategy = 'highest-priority';
|
|
360
|
+
ruleOutranksLlm = false;
|
|
361
|
+
break;
|
|
362
|
+
case 'prefer-rule-when-confident':
|
|
363
|
+
strategy = 'prefer-when-confident';
|
|
364
|
+
break;
|
|
365
|
+
case 'flag':
|
|
366
|
+
strategy = 'flag-on-conflict';
|
|
367
|
+
break;
|
|
368
|
+
default:
|
|
369
|
+
logger?.warn('unknown conflict strategy, falling back to flag', {
|
|
370
|
+
strategy: fullPolicy.strategy,
|
|
371
|
+
field,
|
|
372
|
+
});
|
|
373
|
+
strategy = 'flag-on-conflict';
|
|
274
374
|
}
|
|
275
|
-
|
|
276
|
-
value: ruleMatch.value,
|
|
277
|
-
|
|
278
|
-
|
|
375
|
+
const ruleCandidate = ruleMatch !== null
|
|
376
|
+
? { value: ruleMatch.value, confidence: ruleMatch.confidence, source: 'rule' }
|
|
377
|
+
: null;
|
|
378
|
+
const llmCandidate = normalizedLlm !== null
|
|
379
|
+
? { value: normalizedLlm, confidence: fullPolicy.defaultLlmConfidence, source: 'llm' }
|
|
380
|
+
: null;
|
|
381
|
+
// Array order sets the default priority (earlier ranks higher), so the
|
|
382
|
+
// outranking side goes first.
|
|
383
|
+
const ordered = ruleOutranksLlm
|
|
384
|
+
? [ruleCandidate, llmCandidate]
|
|
385
|
+
: [llmCandidate, ruleCandidate];
|
|
386
|
+
const candidates = ordered.filter((c) => c !== null);
|
|
387
|
+
const result = merge.reconcile(field, candidates, {
|
|
388
|
+
strategy,
|
|
389
|
+
compare: fullPolicy.compare,
|
|
390
|
+
agreementConfidence: fullPolicy.agreementConfidence,
|
|
391
|
+
conflictConfidence: fullPolicy.flaggedConfidence,
|
|
392
|
+
confidentThreshold: fullPolicy.ruleConfidenceThreshold,
|
|
393
|
+
});
|
|
394
|
+
// Preserve the binary contract: on agreement the rule value is the kept
|
|
395
|
+
// representation (the reconcile winner may be the LLM candidate but carries
|
|
396
|
+
// the same value per `compare`), and a conflict record is produced only
|
|
397
|
+
// when a disagreement was flagged.
|
|
398
|
+
const value = result.source?.kind === 'agreement' && ruleMatch !== null ? ruleMatch.value : result.value;
|
|
399
|
+
const conflict = result.source?.kind === 'conflict' && ruleMatch !== null
|
|
400
|
+
? {
|
|
279
401
|
field,
|
|
280
402
|
ruleValue: ruleMatch.value,
|
|
281
403
|
ruleConfidence: ruleMatch.confidence,
|
|
282
404
|
llmValue: normalizedLlm,
|
|
283
|
-
}
|
|
284
|
-
|
|
405
|
+
}
|
|
406
|
+
: undefined;
|
|
407
|
+
return { value, confidence: result.confidence, conflict };
|
|
285
408
|
},
|
|
286
409
|
/**
|
|
287
410
|
* Walk every field of `schema`, fuse the rules pass result with the LLM
|
package/dist/merge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAW/D;;;;GAIG;AACH,SAAS,aAAa,CACpB,UAAuB,EACvB,WAA2B,EAC3B,SAA2B,EAC3B,MAA6C,EAC7C,aAAyE,EACzE,MAA0B;IAE1B,MAAM,IAAI,GAAG,EAAsB,CAAC;IACpC,MAAM,UAAU,GAAG,EAAuC,CAAC;IAC3D,MAAM,OAAO,GAAG,EAA4C,CAAC;IAC7D,MAAM,SAAS,GAAe,EAAE,CAAC;IACjC,MAAM,OAAO,GAAgB,EAAE,CAAC;IAChC,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,MAAM,YAAY,GAAG,KAAK,IAAI,WAAW,CAAC,MAAM,CAAC;QACjD,6EAA6E;QAC7E,mDAAmD;QACnD,MAAM,SAAS,GAA8B,YAAY;YACvD,CAAC,CAAC;gBACE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC;gBAChC,UAAU,EAAE,WAAW,CAAC,UAAU,CAAC,KAAK,CAAW;aACpD;YACH,CAAC,CAAC,IAAI,CAAC;QACT,IAAI,YAAY,EAAE,CAAC;YACjB,YAAY,IAAI,CAAC,CAAC;QACpB,CAAC;QAED,MAAM,QAAQ,GAAG,SAAS,EAAE,MAAM,CAAC,KAAe,CAAC,IAAI,IAAI,CAAC;QAE5D,MAAM,aAAa,GAAG,aAAa,EAAE,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,cAAc,GAClB,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,GAAG,aAAa,EAAE,CAAC;QACzE,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC;QAE9C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAe,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;QAExF,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,KAA0B,CAAC;QAC/C,UAAU,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC;QACrC,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;QAClF,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACjC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;AACzE,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAS,YAAY,CACnB,KAAgC,EAChC,SAAoC,EACpC,QAAiB,EACjB,MAA6C,EAC7C,MAA0B;IAE1B,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,EAAE,GAAG,MAAM,IAAI,EAAE,CAAC;IACxB,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAChD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACtC,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACtC,CAAC;IACD,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,KAAK,EAAE,CAAC;QACpC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,EAAE,OAAO,IAAI,KAAK,CAAC,kBAAkB,CAAC,OAAO,CAAC;IACpE,OAAO,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC;QACvC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE;QACnC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AACnC,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAS,cAAc,CACrB,IAAsB,EACtB,WAAkD,EAClD,OAAe,EACf,OAA6B;IAE7B,MAAM,SAAS,GAA4B,EAAE,CAAC;IAC9C,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,MAAM,IAAI,GAAG,WAAW,IAAI,EAAE,CAAC;IAE/B,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;QAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAE,CAAC;QAC/B,MAAM,cAAc,GAAG,EAAE,GAAI,OAAmC,EAAE,CAAC;QACnE,OAAO,GAAG,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,YAAY,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAErD,MAAM,WAAW,GAAG,OAAkC,CAAC;QACvD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS;YAC9B,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC;YAC9B,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;SAC5B,CAAC,CAAC;QAEH,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;YACnC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;gBAChC,SAAS,CAAC,IAAI,CAAC;oBACb,YAAY;oBACZ,KAAK,EAAE,GAAuB;oBAC9B,MAAM;oBACN,KAAK;oBACL,IAAI;iBACL,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AACtC,CAAC;AAED;;;;GAIG;AACH,SAAS,iBAAiB,CACxB,MAAkC,EAClC,UAA4B,EAC5B,OAAoB,EACpB,UAA8C;IAE9C,MAAM,UAAU,GAAgB,EAAE,CAAC;IACnC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,OAAmB,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACxC,MAAM,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;YAC/B,MAAM,KAAK,GAAG,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;YACpE,IAAI,KAAK,KAAK,SAAS,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjD,SAAS;YACX,CAAC;YACD,UAAU,CAAC,IAAI,CAAC;gBACd,KAAK;gBACL,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,KAAK,MAAM,SAAS,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;QACzC,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB;;;;;;OAMG;IACH,kBAAkB,EAAE;QAClB,6CAA6C;QAC7C,QAAQ,EAAE,MAAM;QAChB,yDAAyD;QACzD,oBAAoB,EAAE,GAAG;QACzB,sDAAsD;QACtD,iBAAiB,EAAE,GAAG;QACtB,wDAAwD;QACxD,mBAAmB,EAAE,GAAG;QACxB,qGAAqG;QACrG,OAAO,EAAE,CAAC,CAAU,EAAE,CAAU,EAAW,EAAE;YAC3C,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBACnD,OAAO,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;YAC7C,CAAC;YACD,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC;QACD,4DAA4D;QAC5D,uBAAuB,EAAE,CAAC;KACA;IAE5B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,KAAK,CACH,KAAa,EACb,SAA8B,EAC9B,QAAiB,EACjB,MAAkC,EAClC,MAAe;QAEf,MAAM,UAAU,GAAqB,EAAE,GAAG,KAAK,CAAC,kBAAkB,EAAE,GAAG,MAAM,EAAE,CAAC;QAChF,MAAM,aAAa,GAAG,QAAQ,IAAI,IAAI,CAAC;QAEvC,IAAI,SAAS,KAAK,IAAI,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;YACjD,OAAO;gBACL,KAAK,EAAE,SAAS,CAAC,KAAK;gBACtB,UAAU,EAAE,SAAS,CAAC,UAAU;gBAChC,QAAQ,EAAE,SAAS;aACpB,CAAC;QACJ,CAAC;QAED,IAAI,SAAS,KAAK,IAAI,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;YACjD,OAAO;gBACL,KAAK,EAAE,aAAkB;gBACzB,UAAU,EAAE,UAAU,CAAC,oBAAoB;gBAC3C,QAAQ,EAAE,SAAS;aACpB,CAAC;QACJ,CAAC;QAED,IAAI,SAAS,KAAK,IAAI,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;YACjD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;QAChE,CAAC;QAED,IAAI,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,EAAE,CAAC;YACvD,OAAO;gBACL,KAAK,EAAE,SAAS,CAAC,KAAK;gBACtB,UAAU,EAAE,UAAU,CAAC,mBAAmB;gBAC1C,QAAQ,EAAE,SAAS;aACpB,CAAC;QACJ,CAAC;QAED,IAAI,UAAU,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;YAC1C,OAAO;gBACL,KAAK,EAAE,SAAS,CAAC,KAAK;gBACtB,UAAU,EAAE,SAAS,CAAC,UAAU;gBAChC,QAAQ,EAAE,SAAS;aACpB,CAAC;QACJ,CAAC;QACD,IAAI,UAAU,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;YACzC,OAAO;gBACL,KAAK,EAAE,aAAkB;gBACzB,UAAU,EAAE,UAAU,CAAC,oBAAoB;gBAC3C,QAAQ,EAAE,SAAS;aACpB,CAAC;QACJ,CAAC;QACD,IAAI,UAAU,CAAC,QAAQ,KAAK,4BAA4B,EAAE,CAAC;YACzD,IAAI,SAAS,CAAC,UAAU,IAAI,UAAU,CAAC,uBAAuB,EAAE,CAAC;gBAC/D,OAAO;oBACL,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,UAAU,EAAE,SAAS,CAAC,UAAU;oBAChC,QAAQ,EAAE,SAAS;iBACpB,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,KAAK,EAAE,aAAkB;gBACzB,UAAU,EAAE,UAAU,CAAC,oBAAoB;gBAC3C,QAAQ,EAAE,SAAS;aACpB,CAAC;QACJ,CAAC;QACD,IAAI,UAAU,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;YACnC,MAAM,EAAE,IAAI,CAAC,iDAAiD,EAAE;gBAC9D,QAAQ,EAAE,UAAU,CAAC,QAAQ;gBAC7B,KAAK;aACN,CAAC,CAAC;QACL,CAAC;QACD,OAAO;YACL,KAAK,EAAE,SAAS,CAAC,KAAK;YACtB,UAAU,EAAE,UAAU,CAAC,iBAAiB;YACxC,QAAQ,EAAE;gBACR,KAAK;gBACL,SAAS,EAAE,SAAS,CAAC,KAAK;gBAC1B,cAAc,EAAE,SAAS,CAAC,UAAU;gBACpC,QAAQ,EAAE,aAAa;aACxB;SACF,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,KAAK,CACH,MAAS,EACT,WAAoC,EACpC,SAA2B,EAC3B,OAAe,EACf,OAAiD,EACjD,OAAkB;QAGlB,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAmB,CAAC;QAE/D,MAAM,MAAM,GAAG,aAAa,CAC1B,UAAU,EACV,WAAW,EACX,SAAS,EACT,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,CAChB,CAAC;QAEF,MAAM,UAAU,GAAG,cAAc,CAC/B,MAAM,CAAC,IAAI,EACX,OAAO,EAAE,WAAW,EACpB,OAAO,EACP,OAAO,CACR,CAAC;QAEF,MAAM,UAAU,GAAG,iBAAiB,CAClC,MAAM,EACN,UAAU,CAAC,IAAI,EACf,MAAM,CAAC,OAAO,EACd,OAAO,EAAE,UAAU,CACpB,CAAC;QACF,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;QAE9D,OAAO;YACL,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,mBAAmB,EAAE,UAAU,CAAC,SAAS;YACzC,UAAU,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE;YACjC,IAAI,EAAE;gBACJ,YAAY,EAAE,MAAM,CAAC,YAAY;gBACjC,SAAS,EAAE,SAAS,KAAK,IAAI;gBAC7B,UAAU,EAAE,CAAC;aACd;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,gBAAgB,CAC9B,EAAU,EACV,KAA8B;IAE9B,MAAM,OAAO,GAA4B,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CAClE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;AACxC,CAAC"}
|
|
1
|
+
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { FieldCompare } from './merge.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* One proposed value for a field, coming from a single source, with the
|
|
4
|
+
* confidence that source has in it. The N-ary generalization of the
|
|
5
|
+
* (rule, llm) pair consumed by {@link merge.field}: any number of sources -
|
|
6
|
+
* deterministic rules, an LLM, external services, manual overrides - can be
|
|
7
|
+
* reconciled through {@link merge.reconcile}.
|
|
8
|
+
*
|
|
9
|
+
* @typeParam T - Type of the proposed value.
|
|
10
|
+
*/
|
|
11
|
+
export type Candidate<T> = {
|
|
12
|
+
/** The proposed value, or `null`/`undefined` when this source had nothing. */
|
|
13
|
+
value: T | null | undefined;
|
|
14
|
+
/** Confidence this source has in `value`, in `[0, 1]`. */
|
|
15
|
+
confidence: number;
|
|
16
|
+
/**
|
|
17
|
+
* Stable source identifier surfaced in {@link ReconcileSource}
|
|
18
|
+
* (e.g. `'rule:price'`, `'llm'`, `'service'`).
|
|
19
|
+
*/
|
|
20
|
+
source: string;
|
|
21
|
+
/**
|
|
22
|
+
* Authority of the source: a higher number wins ties and conflicts. When
|
|
23
|
+
* omitted, the candidate's position in the array decides - earlier entries
|
|
24
|
+
* rank higher - so `[authoritative, fallback]` works without explicit
|
|
25
|
+
* priorities.
|
|
26
|
+
*/
|
|
27
|
+
priority?: number;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* How {@link merge.reconcile} picks the kept value among the present
|
|
31
|
+
* candidates. Agreement detection and conflict reporting run on top of every
|
|
32
|
+
* strategy; the strategy only decides which single candidate wins.
|
|
33
|
+
*
|
|
34
|
+
* - `'highest-priority'` - keep the highest-priority candidate. The legacy
|
|
35
|
+
* `'prefer-rule'`/`'prefer-llm'` strategies are this strategy with the
|
|
36
|
+
* winning source ranked first.
|
|
37
|
+
* - `'highest-confidence'` - keep the most-confident candidate, priority
|
|
38
|
+
* breaking ties.
|
|
39
|
+
* - `'cascade'` - walk candidates in array order and keep the first whose
|
|
40
|
+
* confidence is at or above {@link ReconcilePolicy.confidentThreshold};
|
|
41
|
+
* an ordered list of fallback sources. Yields `null` when none clear the bar.
|
|
42
|
+
* - `'flag-on-conflict'` - keep the highest-priority candidate but, when any
|
|
43
|
+
* present candidate disagrees, lower the confidence to
|
|
44
|
+
* {@link ReconcilePolicy.conflictConfidence} and mark the source
|
|
45
|
+
* `'conflict'`. The N-ary form of the legacy `'flag'` strategy.
|
|
46
|
+
* - `'prefer-when-confident'` - walk candidates by priority and keep the first
|
|
47
|
+
* whose confidence is at or above the threshold; if none qualify, the
|
|
48
|
+
* lowest-priority candidate is the final fallback. The N-ary form of
|
|
49
|
+
* `'prefer-rule-when-confident'`.
|
|
50
|
+
*/
|
|
51
|
+
export type ReconcileStrategy = 'highest-priority' | 'highest-confidence' | 'cascade' | 'flag-on-conflict' | 'prefer-when-confident';
|
|
52
|
+
/**
|
|
53
|
+
* Behaviour overrides for {@link merge.reconcile}. Every field is optional and
|
|
54
|
+
* falls back to {@link merge.defaultReconcilePolicy}.
|
|
55
|
+
*/
|
|
56
|
+
export type ReconcilePolicy = {
|
|
57
|
+
/** How to pick the kept value among present candidates. */
|
|
58
|
+
strategy: ReconcileStrategy;
|
|
59
|
+
/** Equality (or tolerance) check used to detect agreement between candidates. */
|
|
60
|
+
compare: FieldCompare;
|
|
61
|
+
/** Confidence assigned when two or more candidates agree on the kept value. */
|
|
62
|
+
agreementConfidence: number;
|
|
63
|
+
/**
|
|
64
|
+
* Confidence assigned when `'flag-on-conflict'` keeps a value despite a
|
|
65
|
+
* disagreement.
|
|
66
|
+
*/
|
|
67
|
+
conflictConfidence: number;
|
|
68
|
+
/**
|
|
69
|
+
* Threshold consulted by `'cascade'` (minimum acceptable confidence) and by
|
|
70
|
+
* `'prefer-when-confident'`. Default `1`.
|
|
71
|
+
*/
|
|
72
|
+
confidentThreshold: number;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Why {@link merge.reconcile} kept the value it kept.
|
|
76
|
+
*
|
|
77
|
+
* - `'single'` - one candidate carried the day with no peer agreeing.
|
|
78
|
+
* - `'agreement'` - two or more candidates agreed on the kept value.
|
|
79
|
+
* - `'conflict'` - the value was kept despite a disagreement (`'flag-on-conflict'`).
|
|
80
|
+
* - `'cascade'` - a later tier won after earlier tiers fell through.
|
|
81
|
+
*/
|
|
82
|
+
export type ReconcileSourceKind = 'single' | 'agreement' | 'conflict' | 'cascade';
|
|
83
|
+
/**
|
|
84
|
+
* Provenance of a reconciled value: the winning source, the sources that
|
|
85
|
+
* agreed with it (including the winner), and the sources that dissented.
|
|
86
|
+
*/
|
|
87
|
+
export type ReconcileSource = {
|
|
88
|
+
kind: ReconcileSourceKind;
|
|
89
|
+
/** Source id of the winning candidate. */
|
|
90
|
+
winner: string;
|
|
91
|
+
/** Source ids whose value agreed with the winner (winner included). */
|
|
92
|
+
agreedBy: string[];
|
|
93
|
+
/** Source ids whose value disagreed with the winner. */
|
|
94
|
+
dissentedBy: string[];
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* A disagreement between the kept value and one dissenting candidate, surfaced
|
|
98
|
+
* by {@link merge.reconcile} for observability regardless of the strategy.
|
|
99
|
+
*/
|
|
100
|
+
export type ReconcileConflict = {
|
|
101
|
+
/** Name of the field being reconciled. */
|
|
102
|
+
field: string;
|
|
103
|
+
/** The candidate that won. */
|
|
104
|
+
winner: {
|
|
105
|
+
source: string;
|
|
106
|
+
value: unknown;
|
|
107
|
+
confidence: number;
|
|
108
|
+
};
|
|
109
|
+
/** A candidate whose value disagreed with the winner. */
|
|
110
|
+
dissenter: {
|
|
111
|
+
source: string;
|
|
112
|
+
value: unknown;
|
|
113
|
+
confidence: number;
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Outcome of reconciling N candidates for a single field.
|
|
118
|
+
*
|
|
119
|
+
* @typeParam T - Type of the reconciled value.
|
|
120
|
+
*/
|
|
121
|
+
export type ReconcileResult<T> = {
|
|
122
|
+
/** The value kept, or `null` if no candidate provided one. */
|
|
123
|
+
value: T | null;
|
|
124
|
+
/** Confidence associated with `value`, in `[0, 1]`, or `null` if absent. */
|
|
125
|
+
confidence: number | null;
|
|
126
|
+
/** Provenance of the kept value, or `null` when no candidate had a value. */
|
|
127
|
+
source: ReconcileSource | null;
|
|
128
|
+
/** One entry per dissenting candidate; empty when all present candidates agree. */
|
|
129
|
+
conflicts: ReconcileConflict[];
|
|
130
|
+
};
|
|
131
|
+
//# sourceMappingURL=reconcile.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile.types.d.ts","sourceRoot":"","sources":["../../src/types/reconcile.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI;IACzB,8EAA8E;IAC9E,KAAK,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5B,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,iBAAiB,GACzB,kBAAkB,GAClB,oBAAoB,GACpB,SAAS,GACT,kBAAkB,GAClB,uBAAuB,CAAC;AAE5B;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,2DAA2D;IAC3D,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,iFAAiF;IACjF,OAAO,EAAE,YAAY,CAAC;IACtB,+EAA+E;IAC/E,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,CAAC;AAElF;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,wDAAwD;IACxD,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/D,yDAAyD;IACzD,SAAS,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CACnE,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI;IAC/B,8DAA8D;IAC9D,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAChB,4EAA4E;IAC5E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,6EAA6E;IAC7E,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,mFAAmF;IACnF,SAAS,EAAE,iBAAiB,EAAE,CAAC;CAChC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile.types.js","sourceRoot":"","sources":["../../src/types/reconcile.types.ts"],"names":[],"mappings":""}
|