fix(小宝预警): 等待缓存加载后再触发AI建议

This commit is contained in:
Script Generator
2026-06-30 09:56:45 +08:00
parent 4cecf2d77a
commit eb9996a987
4 changed files with 57 additions and 6 deletions

View File

@@ -8,6 +8,7 @@ import {
findLatestRiskInsightForVersion,
findPreviousRiskSnapshot,
shouldRequestRiskInsight,
shouldRequestRiskInsightWithCacheGate,
shouldRequestRiskInsightWithCooldown,
} from './xiaobao-risk-ai';
import type { XiaobaoRiskInsightCacheItem } from './xiaobao-risk-cache';
@@ -243,6 +244,41 @@ test('shouldRequestRiskInsightWithCooldown bypasses cooldown when risk level esc
assert.equal(shouldRequestRiskInsightWithCooldown(current, snapshot({ riskScore: 50 }), previousInsight, new Date('2026-06-29T11:00:00.000Z')), true);
});
test('shouldRequestRiskInsightWithCacheGate waits for cache loading before AI requests', () => {
const current = risk({ riskLevel: 'at_risk', riskScore: 82 });
assert.equal(
shouldRequestRiskInsightWithCacheGate(false, [], current, snapshot({ riskScore: 45 }), new Date('2026-06-29T11:00:00.000Z')),
false,
);
});
test('shouldRequestRiskInsightWithCacheGate reuses unchanged cached insight after cache loading', () => {
const current = risk({ riskLevel: 'at_risk', riskScore: 82 });
const cached = insight({
riskSignature: buildRiskInsightSignature(current),
generatedAt: '2026-06-29T02:00:00.000Z',
});
assert.equal(
shouldRequestRiskInsightWithCacheGate(true, [cached], current, snapshot({ riskScore: 45 }), new Date('2026-06-29T11:00:00.000Z')),
false,
);
});
test('shouldRequestRiskInsightWithCacheGate allows changed risk facts after cache loading and cooldown', () => {
const current = risk({ riskLevel: 'at_risk', riskScore: 82 });
const previousInsight = insight({
riskSignature: buildRiskInsightSignature(risk({ riskLevel: 'at_risk', riskScore: 62 })),
generatedAt: '2026-06-29T02:00:00.000Z',
});
assert.equal(
shouldRequestRiskInsightWithCacheGate(true, [previousInsight], current, snapshot({ riskScore: 45 }), new Date('2026-06-29T11:00:00.000Z')),
true,
);
});
test('buildRiskInsightSignature uses all open bugs, not only critical bugs', () => {
const base = buildRiskInsightSignature(risk({
signals: { ...risk().signals, openBugCount: 1, criticalBugCount: 0 },

View File

@@ -90,6 +90,19 @@ export function shouldRequestRiskInsightWithCooldown(
return nowTime - generatedAt >= RISK_INSIGHT_COOLDOWN_MS;
}
export function shouldRequestRiskInsightWithCacheGate(
riskCacheLoaded: boolean,
cache: XiaobaoRiskInsightCacheItem[],
current: XiaobaoVersionRisk,
previous?: RiskInsightPrevious,
now: Date = new Date(),
): boolean {
if (!riskCacheLoaded) return false;
if (getReusableInsight(cache, current)) return false;
const latestInsight = findLatestRiskInsightForVersion(cache, current.versionId);
return shouldRequestRiskInsightWithCooldown(current, previous, latestInsight, now);
}
export function buildRiskInsightSignature(risk: XiaobaoVersionRisk): string {
return JSON.stringify({
versionId: risk.versionId,