The class factory passes no arguments, so both stages resolve through the class factory under the 'Decision' and 'Prompt' modes: an application's override of either mode applies inside the chain too.
OptionaldecisionStage: DecisionReasoningProviderthe filter stage; defaults to ResolveDecisionStage, at the pre-filter threshold (DecisionReasoningProvider.PRE_FILTER_UNCERTAIN_ABOVE), which keeps recall
OptionalpromptStage: DuplicateReasoningProviderthe reasoning stage; defaults to ResolvePromptStage
Protected ReadonlyDecisionThe filter stage. Its UncertainAbove is the survival threshold.
Protected ReadonlyPromptThe reasoning stage, which sees only the survivors.
ProtectedbuildBuilds the Nunjucks/template data context for the shared "Duplicate Resolution" instruction set. Both providers feed the prompt the exact same shape, so this lives on the base class. Keys match the seeded template's variable names verbatim.
ProtectedcoerceCoerces a JSON string or object into a plain record, else null.
ProtectedderiveDerive the set-level verdict from the per-candidate verdicts: Merge if any candidate is a Merge, else Uncertain if any is Uncertain, else NotDuplicate. Overall confidence is the max confidence among the candidates matching the winning recommendation (null if none reported).
ProtecteddisplayRender a field value for the prompt: the trimmed value, or '(empty)' for null/blank.
ProtectedfailedBuilds a failed reasoning output (logged, never thrown).
ProtectedNarrowThe input with the dropped candidates removed, from the candidate list and from the field deltas. A field whose remaining values no longer differ is dropped too, since the deltas carry differing fields only.
ProtectednormalizeNormalize the per-candidate verdicts array, dropping malformed entries. Each must carry a non-empty record id; recommendation/confidence are clamped, reasoning defaults to ''.
ProtectednormalizeClamps confidence into [0,1], returning null when absent/invalid. null (not 0) so a
missing confidence isn't mistaken for "confidently NOT a duplicate" downstream.
ProtectednormalizeNormalizes the fieldChoices array, dropping malformed entries.
ProtectednormalizeClamps the recommendation to the allowed union, defaulting to 'Uncertain'.
ProtectednormalizeReturns the survivor id string, or null when absent/empty.
ProtectedparseParses a provider's raw structured output (the {recommendation, confidence, ...}
object) into a normalized DuplicateReasoningOutput. Tolerant of either an
already-parsed object or a JSON string. Returns a failed output on any parse error.
Filter the set with the decision, then reason over the survivors with the prompt.
ProtectedResolveThe filter stage: the provider registered for the 'Decision' mode, built with the pre-filter
threshold (DecisionReasoningProvider.PRE_FILTER_UNCERTAIN_ABOVE) as its uncertainAbove
argument, since here the decision only drops implausible candidates and keeps recall. The chain
needs its probability API, so a registration that is not a DecisionReasoningProvider falls
back to the shipped one, at the same threshold.
ProtectedResolveThe reasoning stage: the provider registered for the 'Prompt' mode, else the shipped one.
Chained reasoning provider: the decision filters, then the prompt reasons over the survivors. Registered under the 'DecisionThenPrompt'
ReasoningMode.