Stage 3 Wave 1: lifecycle-слой встроен в pipeline
This commit is contained in:
@@ -13,6 +13,8 @@ import {
|
||||
PROBLEM_UNIT_SCHEMA_VERSION,
|
||||
PROBLEM_UNIT_SUMMARY_SCHEMA_VERSION
|
||||
} from "../types/stage2ProblemUnits";
|
||||
import { FEATURE_ASSISTANT_LIFECYCLE_RUNTIME_V1 } from "../config";
|
||||
import { enrichProblemUnitLifecycle, rankLifecycleProblemUnits } from "./lifecycleRuntime";
|
||||
|
||||
type RetrievalResultType = "list" | "summary" | "object" | "chain" | "ranking";
|
||||
|
||||
@@ -486,6 +488,18 @@ function collapseSignature(unit: ProblemUnit): string {
|
||||
return [unit.problem_unit_type, unit.business_defect_class, unit.failed_expected_edge ?? "none", backlink].join("|");
|
||||
}
|
||||
|
||||
function preferredLifecycleSource(left: ProblemUnit, right: ProblemUnit): ProblemUnit {
|
||||
const leftRank = left.lifecycle_ranking_score ?? 0;
|
||||
const rightRank = right.lifecycle_ranking_score ?? 0;
|
||||
if (rightRank > leftRank) {
|
||||
return right;
|
||||
}
|
||||
if (leftRank > rightRank) {
|
||||
return left;
|
||||
}
|
||||
return right.confidence.score > left.confidence.score ? right : left;
|
||||
}
|
||||
|
||||
export function collapseDuplicates(units: ProblemUnit[]): {
|
||||
problem_units: ProblemUnit[];
|
||||
duplicate_collapses: number;
|
||||
@@ -502,6 +516,7 @@ export function collapseDuplicates(units: ProblemUnit[]): {
|
||||
}
|
||||
|
||||
duplicateCollapses += 1;
|
||||
const preferredLifecycle = preferredLifecycleSource(existing, unit);
|
||||
bySignature.set(signature, {
|
||||
...existing,
|
||||
evidence_pack: uniqueStrings([...existing.evidence_pack, ...unit.evidence_pack]),
|
||||
@@ -521,7 +536,72 @@ export function collapseDuplicates(units: ProblemUnit[]): {
|
||||
affected_contracts: uniqueStrings([...existing.affected_contracts, ...unit.affected_contracts]),
|
||||
snapshot_limitations: uniqueStrings([...existing.snapshot_limitations, ...unit.snapshot_limitations]),
|
||||
severity: unit.severity.score > existing.severity.score ? unit.severity : existing.severity,
|
||||
confidence: unit.confidence.score > existing.confidence.score ? unit.confidence : existing.confidence
|
||||
confidence: unit.confidence.score > existing.confidence.score ? unit.confidence : existing.confidence,
|
||||
...(preferredLifecycle.lifecycle_domain
|
||||
? {
|
||||
lifecycle_domain: preferredLifecycle.lifecycle_domain
|
||||
}
|
||||
: {}),
|
||||
...(preferredLifecycle.lifecycle_object_id
|
||||
? {
|
||||
lifecycle_object_id: preferredLifecycle.lifecycle_object_id
|
||||
}
|
||||
: {}),
|
||||
...(preferredLifecycle.current_lifecycle_state
|
||||
? {
|
||||
current_lifecycle_state: preferredLifecycle.current_lifecycle_state
|
||||
}
|
||||
: {}),
|
||||
...(preferredLifecycle.expected_lifecycle_state
|
||||
? {
|
||||
expected_lifecycle_state: preferredLifecycle.expected_lifecycle_state
|
||||
}
|
||||
: {}),
|
||||
...(preferredLifecycle.missing_transition
|
||||
? {
|
||||
missing_transition: preferredLifecycle.missing_transition
|
||||
}
|
||||
: {}),
|
||||
...(preferredLifecycle.invalid_transition
|
||||
? {
|
||||
invalid_transition: preferredLifecycle.invalid_transition
|
||||
}
|
||||
: {}),
|
||||
...(preferredLifecycle.lifecycle_defect_type
|
||||
? {
|
||||
lifecycle_defect_type: preferredLifecycle.lifecycle_defect_type
|
||||
}
|
||||
: {}),
|
||||
...(preferredLifecycle.stale_duration
|
||||
? {
|
||||
stale_duration: preferredLifecycle.stale_duration
|
||||
}
|
||||
: {}),
|
||||
...(preferredLifecycle.lifecycle_confidence
|
||||
? {
|
||||
lifecycle_confidence: preferredLifecycle.lifecycle_confidence
|
||||
}
|
||||
: {}),
|
||||
...(preferredLifecycle.business_lifecycle_interpretation
|
||||
? {
|
||||
business_lifecycle_interpretation: preferredLifecycle.business_lifecycle_interpretation
|
||||
}
|
||||
: {}),
|
||||
...(preferredLifecycle.lifecycle_resolution
|
||||
? {
|
||||
lifecycle_resolution: preferredLifecycle.lifecycle_resolution
|
||||
}
|
||||
: {}),
|
||||
...(preferredLifecycle.lifecycle_ranking_score !== undefined
|
||||
? {
|
||||
lifecycle_ranking_score: preferredLifecycle.lifecycle_ranking_score
|
||||
}
|
||||
: {}),
|
||||
...(preferredLifecycle.lifecycle_ranking_basis
|
||||
? {
|
||||
lifecycle_ranking_basis: preferredLifecycle.lifecycle_ranking_basis
|
||||
}
|
||||
: {})
|
||||
});
|
||||
}
|
||||
|
||||
@@ -544,11 +624,21 @@ function buildSummary(units: ProblemUnit[], duplicateCollapses: number): Problem
|
||||
medium: 0,
|
||||
high: 0
|
||||
};
|
||||
const lifecycleDomainDistribution: NonNullable<ProblemUnitSummary["lifecycle_domain_distribution"]> = {};
|
||||
const lifecycleDefectDistribution: NonNullable<ProblemUnitSummary["lifecycle_defect_distribution"]> = {};
|
||||
let lifecycleEnrichedUnits = 0;
|
||||
|
||||
for (const unit of units) {
|
||||
typeDistribution[unit.problem_unit_type] = (typeDistribution[unit.problem_unit_type] ?? 0) + 1;
|
||||
severityDistribution[unit.severity.grade] += 1;
|
||||
confidenceDistribution[unit.confidence.grade] += 1;
|
||||
if (unit.lifecycle_domain) {
|
||||
lifecycleEnrichedUnits += 1;
|
||||
lifecycleDomainDistribution[unit.lifecycle_domain] = (lifecycleDomainDistribution[unit.lifecycle_domain] ?? 0) + 1;
|
||||
}
|
||||
if (unit.lifecycle_defect_type) {
|
||||
lifecycleDefectDistribution[unit.lifecycle_defect_type] = (lifecycleDefectDistribution[unit.lifecycle_defect_type] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -559,7 +649,10 @@ function buildSummary(units: ProblemUnit[], duplicateCollapses: number): Problem
|
||||
type_distribution: typeDistribution,
|
||||
severity_distribution: severityDistribution,
|
||||
confidence_distribution: confidenceDistribution,
|
||||
primary_unit_type: units[0]?.problem_unit_type ?? null
|
||||
primary_unit_type: units[0]?.problem_unit_type ?? null,
|
||||
lifecycle_enriched_units: lifecycleEnrichedUnits,
|
||||
lifecycle_domain_distribution: lifecycleDomainDistribution,
|
||||
lifecycle_defect_distribution: lifecycleDefectDistribution
|
||||
};
|
||||
}
|
||||
|
||||
@@ -580,13 +673,24 @@ export function assembleProblemUnits(input: AssembleProblemUnitsInput): {
|
||||
risk_factors: uniqueStrings(input.risk_factors ?? [])
|
||||
});
|
||||
const clusters = clusterCandidateEvidence(candidates);
|
||||
const units = clusters.map((cluster, index) => buildProblemUnit(cluster, index));
|
||||
const units = clusters.map((cluster, index) => {
|
||||
const baseUnit = buildProblemUnit(cluster, index);
|
||||
if (!FEATURE_ASSISTANT_LIFECYCLE_RUNTIME_V1) {
|
||||
return baseUnit;
|
||||
}
|
||||
return enrichProblemUnitLifecycle({
|
||||
unit: baseUnit,
|
||||
candidates: cluster.candidates
|
||||
});
|
||||
});
|
||||
const collapsed = collapseDuplicates(units);
|
||||
const rankedUnits = FEATURE_ASSISTANT_LIFECYCLE_RUNTIME_V1
|
||||
? rankLifecycleProblemUnits(collapsed.problem_units)
|
||||
: collapsed.problem_units;
|
||||
|
||||
return {
|
||||
candidate_evidence: candidates,
|
||||
problem_units: collapsed.problem_units,
|
||||
problem_unit_summary: buildSummary(collapsed.problem_units, collapsed.duplicate_collapses)
|
||||
problem_units: rankedUnits,
|
||||
problem_unit_summary: buildSummary(rankedUnits, collapsed.duplicate_collapses)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user