@panguard-ai/core 0.3.1 → 0.3.3
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/dist/adapters/wazuh-adapter.d.ts +2 -2
- package/dist/adapters/wazuh-adapter.js +2 -2
- package/dist/ai/index.d.ts +6 -0
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +3 -0
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/knowledge-distiller.d.ts +85 -0
- package/dist/ai/knowledge-distiller.d.ts.map +1 -0
- package/dist/ai/knowledge-distiller.js +171 -0
- package/dist/ai/knowledge-distiller.js.map +1 -0
- package/dist/ai/openai-provider.d.ts.map +1 -1
- package/dist/ai/openai-provider.js +3 -0
- package/dist/ai/openai-provider.js.map +1 -1
- package/dist/ai/prompts/event-classifier.d.ts.map +1 -1
- package/dist/ai/prompts/event-classifier.js +19 -4
- package/dist/ai/prompts/event-classifier.js.map +1 -1
- package/dist/ai/prompts/threat-analyzer.d.ts +12 -0
- package/dist/ai/prompts/threat-analyzer.d.ts.map +1 -1
- package/dist/ai/prompts/threat-analyzer.js +68 -26
- package/dist/ai/prompts/threat-analyzer.js.map +1 -1
- package/dist/ai/quota-manager.d.ts +72 -0
- package/dist/ai/quota-manager.d.ts.map +1 -0
- package/dist/ai/quota-manager.js +139 -0
- package/dist/ai/quota-manager.js.map +1 -0
- package/dist/ai/smart-router.d.ts +96 -0
- package/dist/ai/smart-router.d.ts.map +1 -0
- package/dist/ai/smart-router.js +201 -0
- package/dist/ai/smart-router.js.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/wizard.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/monitor/threat-intel-feeds.d.ts +33 -0
- package/dist/monitor/threat-intel-feeds.d.ts.map +1 -1
- package/dist/monitor/threat-intel-feeds.js +80 -2
- package/dist/monitor/threat-intel-feeds.js.map +1 -1
- package/dist/rules/sigma-matcher.d.ts.map +1 -1
- package/dist/rules/sigma-matcher.js +32 -2
- package/dist/rules/sigma-matcher.js.map +1 -1
- package/dist/rules/sigma-parser.d.ts.map +1 -1
- package/dist/rules/sigma-parser.js +39 -3
- package/dist/rules/sigma-parser.js.map +1 -1
- package/dist/tiers/index.js +4 -4
- package/dist/tiers/index.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +19 -9
- package/LICENSE +0 -21
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Quota Manager - Per-tier rate limiting and cost control
|
|
3
|
+
* AI 配額管理器 - 各等級速率限制與費用控制
|
|
4
|
+
*
|
|
5
|
+
* Enforces hourly AI call quotas per license tier and tracks
|
|
6
|
+
* cumulative cost with hard budget caps to prevent overspending.
|
|
7
|
+
*
|
|
8
|
+
* @module @panguard-ai/core/ai/quota-manager
|
|
9
|
+
*/
|
|
10
|
+
/** License tier for quota purposes */
|
|
11
|
+
export type QuotaTier = 'free' | 'pro' | 'business' | 'enterprise';
|
|
12
|
+
/** Quota configuration per tier */
|
|
13
|
+
export interface QuotaConfig {
|
|
14
|
+
/** Max AI calls per hour (0 = blocked, -1 = unlimited) */
|
|
15
|
+
maxCallsPerHour: number;
|
|
16
|
+
/** Max monthly budget in USD (0 = no budget, -1 = unlimited) */
|
|
17
|
+
maxMonthlyBudgetUSD: number;
|
|
18
|
+
/** Whether user provides own API key (BYOK) */
|
|
19
|
+
isBYOK: boolean;
|
|
20
|
+
}
|
|
21
|
+
/** Result of a quota check */
|
|
22
|
+
export interface QuotaCheckResult {
|
|
23
|
+
allowed: boolean;
|
|
24
|
+
reason?: string;
|
|
25
|
+
remainingCalls: number;
|
|
26
|
+
remainingBudgetUSD: number;
|
|
27
|
+
}
|
|
28
|
+
/** Quota usage snapshot */
|
|
29
|
+
export interface QuotaUsage {
|
|
30
|
+
tier: QuotaTier;
|
|
31
|
+
callsThisHour: number;
|
|
32
|
+
maxCallsPerHour: number;
|
|
33
|
+
costThisMonth: number;
|
|
34
|
+
maxMonthlyBudgetUSD: number;
|
|
35
|
+
isBYOK: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* AI Quota Manager
|
|
39
|
+
*
|
|
40
|
+
* Uses a sliding window for hourly call counting and tracks
|
|
41
|
+
* cumulative monthly cost.
|
|
42
|
+
*/
|
|
43
|
+
export declare class AIQuotaManager {
|
|
44
|
+
private readonly config;
|
|
45
|
+
private readonly tier;
|
|
46
|
+
/** Timestamps of recent AI calls (sliding window) */
|
|
47
|
+
private callTimestamps;
|
|
48
|
+
/** Cumulative cost this month in USD */
|
|
49
|
+
private monthlyCost;
|
|
50
|
+
/** Month key for cost reset (e.g. "2026-03") */
|
|
51
|
+
private currentMonth;
|
|
52
|
+
constructor(tier: QuotaTier, configOverride?: Partial<QuotaConfig>);
|
|
53
|
+
/**
|
|
54
|
+
* Check if an AI call is allowed under current quota
|
|
55
|
+
*/
|
|
56
|
+
checkQuota(): QuotaCheckResult;
|
|
57
|
+
/**
|
|
58
|
+
* Record a completed AI call with its cost
|
|
59
|
+
*/
|
|
60
|
+
recordCall(costUSD: number): void;
|
|
61
|
+
/**
|
|
62
|
+
* Get current usage snapshot
|
|
63
|
+
*/
|
|
64
|
+
getUsage(): QuotaUsage;
|
|
65
|
+
/** Remove timestamps older than 1 hour */
|
|
66
|
+
private pruneOldTimestamps;
|
|
67
|
+
/** Reset monthly cost if we crossed into a new month */
|
|
68
|
+
private maybeResetMonth;
|
|
69
|
+
/** Get current month key (e.g. "2026-03") */
|
|
70
|
+
static getMonthKey(): string;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=quota-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quota-manager.d.ts","sourceRoot":"","sources":["../../src/ai/quota-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,sCAAsC;AACtC,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,UAAU,GAAG,YAAY,CAAC;AAEnE,mCAAmC;AACnC,MAAM,WAAW,WAAW;IAC1B,0DAA0D;IAC1D,eAAe,EAAE,MAAM,CAAC;IACxB,gEAAgE;IAChE,mBAAmB,EAAE,MAAM,CAAC;IAC5B,+CAA+C;IAC/C,MAAM,EAAE,OAAO,CAAC;CACjB;AAUD,8BAA8B;AAC9B,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,2BAA2B;AAC3B,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;IAEjC,qDAAqD;IACrD,OAAO,CAAC,cAAc,CAAgB;IACtC,wCAAwC;IACxC,OAAO,CAAC,WAAW,CAAK;IACxB,gDAAgD;IAChD,OAAO,CAAC,YAAY,CAAS;gBAEjB,IAAI,EAAE,SAAS,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC;IAYlE;;OAEG;IACH,UAAU,IAAI,gBAAgB;IAsD9B;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQjC;;OAEG;IACH,QAAQ,IAAI,UAAU;IActB,0CAA0C;IAC1C,OAAO,CAAC,kBAAkB;IAK1B,wDAAwD;IACxD,OAAO,CAAC,eAAe;IASvB,6CAA6C;IAC7C,MAAM,CAAC,WAAW,IAAI,MAAM;CAI7B"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Quota Manager - Per-tier rate limiting and cost control
|
|
3
|
+
* AI 配額管理器 - 各等級速率限制與費用控制
|
|
4
|
+
*
|
|
5
|
+
* Enforces hourly AI call quotas per license tier and tracks
|
|
6
|
+
* cumulative cost with hard budget caps to prevent overspending.
|
|
7
|
+
*
|
|
8
|
+
* @module @panguard-ai/core/ai/quota-manager
|
|
9
|
+
*/
|
|
10
|
+
import { createLogger } from '../utils/logger.js';
|
|
11
|
+
const logger = createLogger('ai:quota-manager');
|
|
12
|
+
/** Default quota limits per tier */
|
|
13
|
+
const DEFAULT_QUOTAS = {
|
|
14
|
+
free: { maxCallsPerHour: 0, maxMonthlyBudgetUSD: 0, isBYOK: false },
|
|
15
|
+
pro: { maxCallsPerHour: 200, maxMonthlyBudgetUSD: 10, isBYOK: false },
|
|
16
|
+
business: { maxCallsPerHour: 500, maxMonthlyBudgetUSD: 50, isBYOK: true },
|
|
17
|
+
enterprise: { maxCallsPerHour: -1, maxMonthlyBudgetUSD: -1, isBYOK: true },
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* AI Quota Manager
|
|
21
|
+
*
|
|
22
|
+
* Uses a sliding window for hourly call counting and tracks
|
|
23
|
+
* cumulative monthly cost.
|
|
24
|
+
*/
|
|
25
|
+
export class AIQuotaManager {
|
|
26
|
+
config;
|
|
27
|
+
tier;
|
|
28
|
+
/** Timestamps of recent AI calls (sliding window) */
|
|
29
|
+
callTimestamps = [];
|
|
30
|
+
/** Cumulative cost this month in USD */
|
|
31
|
+
monthlyCost = 0;
|
|
32
|
+
/** Month key for cost reset (e.g. "2026-03") */
|
|
33
|
+
currentMonth;
|
|
34
|
+
constructor(tier, configOverride) {
|
|
35
|
+
this.tier = tier;
|
|
36
|
+
this.config = { ...DEFAULT_QUOTAS[tier], ...configOverride };
|
|
37
|
+
this.currentMonth = AIQuotaManager.getMonthKey();
|
|
38
|
+
logger.info(`AIQuotaManager initialized for tier=${tier}`, {
|
|
39
|
+
maxCallsPerHour: this.config.maxCallsPerHour,
|
|
40
|
+
maxMonthlyBudgetUSD: this.config.maxMonthlyBudgetUSD,
|
|
41
|
+
isBYOK: this.config.isBYOK,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Check if an AI call is allowed under current quota
|
|
46
|
+
*/
|
|
47
|
+
checkQuota() {
|
|
48
|
+
this.maybeResetMonth();
|
|
49
|
+
this.pruneOldTimestamps();
|
|
50
|
+
const callsThisHour = this.callTimestamps.length;
|
|
51
|
+
const maxCalls = this.config.maxCallsPerHour;
|
|
52
|
+
const maxBudget = this.config.maxMonthlyBudgetUSD;
|
|
53
|
+
// BYOK users skip vendor cost checks (they pay their own API)
|
|
54
|
+
if (this.config.isBYOK) {
|
|
55
|
+
return {
|
|
56
|
+
allowed: true,
|
|
57
|
+
remainingCalls: maxCalls === -1 ? Infinity : Math.max(0, maxCalls - callsThisHour),
|
|
58
|
+
remainingBudgetUSD: Infinity,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// Free tier: no AI access
|
|
62
|
+
if (maxCalls === 0) {
|
|
63
|
+
return {
|
|
64
|
+
allowed: false,
|
|
65
|
+
reason: 'AI analysis not available on free tier. Upgrade to Pro for AI-powered detection.',
|
|
66
|
+
remainingCalls: 0,
|
|
67
|
+
remainingBudgetUSD: 0,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// Hourly rate limit check
|
|
71
|
+
if (maxCalls !== -1 && callsThisHour >= maxCalls) {
|
|
72
|
+
return {
|
|
73
|
+
allowed: false,
|
|
74
|
+
reason: `Hourly AI quota exceeded (${callsThisHour}/${maxCalls}). Resets next hour.`,
|
|
75
|
+
remainingCalls: 0,
|
|
76
|
+
remainingBudgetUSD: Math.max(0, maxBudget - this.monthlyCost),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// Monthly budget check
|
|
80
|
+
if (maxBudget !== -1 && this.monthlyCost >= maxBudget) {
|
|
81
|
+
return {
|
|
82
|
+
allowed: false,
|
|
83
|
+
reason: `Monthly AI budget exceeded ($${this.monthlyCost.toFixed(2)}/$${maxBudget.toFixed(2)}).`,
|
|
84
|
+
remainingCalls: maxCalls === -1 ? Infinity : Math.max(0, maxCalls - callsThisHour),
|
|
85
|
+
remainingBudgetUSD: 0,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
allowed: true,
|
|
90
|
+
remainingCalls: maxCalls === -1 ? Infinity : maxCalls - callsThisHour,
|
|
91
|
+
remainingBudgetUSD: maxBudget === -1 ? Infinity : maxBudget - this.monthlyCost,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Record a completed AI call with its cost
|
|
96
|
+
*/
|
|
97
|
+
recordCall(costUSD) {
|
|
98
|
+
this.maybeResetMonth();
|
|
99
|
+
this.callTimestamps.push(Date.now());
|
|
100
|
+
if (!this.config.isBYOK) {
|
|
101
|
+
this.monthlyCost += costUSD;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get current usage snapshot
|
|
106
|
+
*/
|
|
107
|
+
getUsage() {
|
|
108
|
+
this.maybeResetMonth();
|
|
109
|
+
this.pruneOldTimestamps();
|
|
110
|
+
return {
|
|
111
|
+
tier: this.tier,
|
|
112
|
+
callsThisHour: this.callTimestamps.length,
|
|
113
|
+
maxCallsPerHour: this.config.maxCallsPerHour,
|
|
114
|
+
costThisMonth: Math.round(this.monthlyCost * 1_000_000) / 1_000_000,
|
|
115
|
+
maxMonthlyBudgetUSD: this.config.maxMonthlyBudgetUSD,
|
|
116
|
+
isBYOK: this.config.isBYOK,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/** Remove timestamps older than 1 hour */
|
|
120
|
+
pruneOldTimestamps() {
|
|
121
|
+
const oneHourAgo = Date.now() - 3_600_000;
|
|
122
|
+
this.callTimestamps = this.callTimestamps.filter((t) => t > oneHourAgo);
|
|
123
|
+
}
|
|
124
|
+
/** Reset monthly cost if we crossed into a new month */
|
|
125
|
+
maybeResetMonth() {
|
|
126
|
+
const now = AIQuotaManager.getMonthKey();
|
|
127
|
+
if (now !== this.currentMonth) {
|
|
128
|
+
logger.info(`Monthly quota reset (${this.currentMonth} -> ${now})`);
|
|
129
|
+
this.monthlyCost = 0;
|
|
130
|
+
this.currentMonth = now;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/** Get current month key (e.g. "2026-03") */
|
|
134
|
+
static getMonthKey() {
|
|
135
|
+
const d = new Date();
|
|
136
|
+
return `${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, '0')}`;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=quota-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quota-manager.js","sourceRoot":"","sources":["../../src/ai/quota-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart AI Router - Cost-optimized routing with knowledge distillation
|
|
3
|
+
* 智慧 AI 路由器 - 成本最佳化路由與知識蒸餾
|
|
4
|
+
*
|
|
5
|
+
* Wraps FunnelRouter with intelligent decision-making:
|
|
6
|
+
* - Skip AI entirely for high-confidence rule matches (>=80%)
|
|
7
|
+
* - Route simple/known patterns to local Ollama (free)
|
|
8
|
+
* - Route only complex/unknown patterns to cloud Claude/OpenAI
|
|
9
|
+
* - Enforce per-tier quotas via AIQuotaManager
|
|
10
|
+
* - Distill AI analysis results into rules to avoid repeat cloud calls
|
|
11
|
+
*
|
|
12
|
+
* @module @panguard-ai/core/ai/smart-router
|
|
13
|
+
*/
|
|
14
|
+
import type { AnalysisResult } from './types.js';
|
|
15
|
+
import type { FunnelRouterConfig } from './funnel-router.js';
|
|
16
|
+
import type { QuotaTier, QuotaConfig } from './quota-manager.js';
|
|
17
|
+
/** Complexity assessment for routing decisions */
|
|
18
|
+
export type EventComplexity = 'skip' | 'simple' | 'complex';
|
|
19
|
+
/** Smart router configuration */
|
|
20
|
+
export interface SmartRouterConfig extends FunnelRouterConfig {
|
|
21
|
+
/** License tier for quota enforcement */
|
|
22
|
+
tier: QuotaTier;
|
|
23
|
+
/** Optional quota config override */
|
|
24
|
+
quotaOverride?: Partial<QuotaConfig>;
|
|
25
|
+
/** Rule confidence threshold to skip AI entirely (default: 80) */
|
|
26
|
+
skipAIThreshold?: number;
|
|
27
|
+
/** Confidence threshold to prefer local AI over cloud (default: 60) */
|
|
28
|
+
preferLocalThreshold?: number;
|
|
29
|
+
}
|
|
30
|
+
/** Routing decision metadata */
|
|
31
|
+
export interface RoutingDecision {
|
|
32
|
+
complexity: EventComplexity;
|
|
33
|
+
provider: 'rules-only' | 'local-ai' | 'cloud-ai' | 'quota-blocked';
|
|
34
|
+
reason: string;
|
|
35
|
+
quotaAllowed: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Smart Router wrapping FunnelRouter with cost optimization
|
|
39
|
+
*/
|
|
40
|
+
export declare class SmartRouter {
|
|
41
|
+
private readonly funnel;
|
|
42
|
+
private readonly quota;
|
|
43
|
+
private readonly skipAIThreshold;
|
|
44
|
+
private readonly preferLocalThreshold;
|
|
45
|
+
private readonly localProvider;
|
|
46
|
+
private readonly cloudProvider;
|
|
47
|
+
/** Knowledge cache: pattern hash -> cached result (avoids repeat AI calls) */
|
|
48
|
+
private readonly knowledgeCache;
|
|
49
|
+
private readonly cacheTTL;
|
|
50
|
+
/** Stats */
|
|
51
|
+
private stats;
|
|
52
|
+
constructor(config: SmartRouterConfig);
|
|
53
|
+
/**
|
|
54
|
+
* Assess event complexity based on rule confidence
|
|
55
|
+
*/
|
|
56
|
+
assessComplexity(ruleConfidence: number, hasAttackChain: boolean): EventComplexity;
|
|
57
|
+
/**
|
|
58
|
+
* Route an analysis request with smart cost optimization
|
|
59
|
+
*
|
|
60
|
+
* @param prompt - Analysis prompt
|
|
61
|
+
* @param ruleConfidence - Confidence from rule matches (0-100)
|
|
62
|
+
* @param hasAttackChain - Whether an attack chain was detected
|
|
63
|
+
* @param patternHash - Optional hash for knowledge cache lookup
|
|
64
|
+
* @param context - Optional analysis context
|
|
65
|
+
*/
|
|
66
|
+
analyze(prompt: string, ruleConfidence: number, hasAttackChain: boolean, patternHash?: string, context?: string): Promise<{
|
|
67
|
+
result: AnalysisResult | null;
|
|
68
|
+
decision: RoutingDecision;
|
|
69
|
+
}>;
|
|
70
|
+
/**
|
|
71
|
+
* Record a distilled rule for a pattern (so future occurrences skip AI)
|
|
72
|
+
*/
|
|
73
|
+
recordDistilledPattern(patternHash: string, result: AnalysisResult): void;
|
|
74
|
+
/** Get routing statistics */
|
|
75
|
+
getStats(): {
|
|
76
|
+
totalRequests: number;
|
|
77
|
+
skippedByRules: number;
|
|
78
|
+
routedToLocal: number;
|
|
79
|
+
routedToCloud: number;
|
|
80
|
+
servedFromCache: number;
|
|
81
|
+
blockedByQuota: number;
|
|
82
|
+
};
|
|
83
|
+
/** Get quota usage */
|
|
84
|
+
getQuotaUsage(): import("./quota-manager.js").QuotaUsage;
|
|
85
|
+
/** Get funnel status */
|
|
86
|
+
getFunnelStatus(): {
|
|
87
|
+
local: import("./funnel-router.js").FunnelLayerStatus;
|
|
88
|
+
cloud: import("./funnel-router.js").FunnelLayerStatus;
|
|
89
|
+
activeLayer: string;
|
|
90
|
+
};
|
|
91
|
+
/** Start health checks on underlying funnel */
|
|
92
|
+
startHealthChecks(intervalMs?: number): void;
|
|
93
|
+
/** Stop health checks */
|
|
94
|
+
stopHealthChecks(): void;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=smart-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-router.d.ts","sourceRoot":"","sources":["../../src/ai/smart-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,YAAY,CAAC;AAE9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAIjE,kDAAkD;AAClD,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE5D,iCAAiC;AACjC,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,yCAAyC;IACzC,IAAI,EAAE,SAAS,CAAC;IAChB,qCAAqC;IACrC,aAAa,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACrC,kEAAkE;IAClE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uEAAuE;IACvE,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,gCAAgC;AAChC,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,eAAe,CAAC;IAC5B,QAAQ,EAAE,YAAY,GAAG,UAAU,GAAG,UAAU,GAAG,eAAe,CAAC;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IAEnD,8EAA8E;IAC9E,OAAO,CAAC,QAAQ,CAAC,cAAc,CAG3B;IACJ,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAa;IAEtC,YAAY;IACZ,OAAO,CAAC,KAAK,CAOX;gBAEU,MAAM,EAAE,iBAAiB;IAerC;;OAEG;IACH,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,GAAG,eAAe;IAelF;;;;;;;;OAQG;IACG,OAAO,CACX,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,OAAO,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,eAAe,CAAA;KAAE,CAAC;IA2GxE;;OAEG;IACH,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI;IAIzE,6BAA6B;IAC7B,QAAQ;;;;;;;;IAIR,sBAAsB;IACtB,aAAa;IAIb,wBAAwB;IACxB,eAAe;;;;;IAIf,+CAA+C;IAC/C,iBAAiB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IAI5C,yBAAyB;IACzB,gBAAgB,IAAI,IAAI;CAGzB"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart AI Router - Cost-optimized routing with knowledge distillation
|
|
3
|
+
* 智慧 AI 路由器 - 成本最佳化路由與知識蒸餾
|
|
4
|
+
*
|
|
5
|
+
* Wraps FunnelRouter with intelligent decision-making:
|
|
6
|
+
* - Skip AI entirely for high-confidence rule matches (>=80%)
|
|
7
|
+
* - Route simple/known patterns to local Ollama (free)
|
|
8
|
+
* - Route only complex/unknown patterns to cloud Claude/OpenAI
|
|
9
|
+
* - Enforce per-tier quotas via AIQuotaManager
|
|
10
|
+
* - Distill AI analysis results into rules to avoid repeat cloud calls
|
|
11
|
+
*
|
|
12
|
+
* @module @panguard-ai/core/ai/smart-router
|
|
13
|
+
*/
|
|
14
|
+
import { createLogger } from '../utils/logger.js';
|
|
15
|
+
import { FunnelRouter } from './funnel-router.js';
|
|
16
|
+
import { AIQuotaManager } from './quota-manager.js';
|
|
17
|
+
const logger = createLogger('ai:smart-router');
|
|
18
|
+
/**
|
|
19
|
+
* Smart Router wrapping FunnelRouter with cost optimization
|
|
20
|
+
*/
|
|
21
|
+
export class SmartRouter {
|
|
22
|
+
funnel;
|
|
23
|
+
quota;
|
|
24
|
+
skipAIThreshold;
|
|
25
|
+
preferLocalThreshold;
|
|
26
|
+
localProvider;
|
|
27
|
+
cloudProvider;
|
|
28
|
+
/** Knowledge cache: pattern hash -> cached result (avoids repeat AI calls) */
|
|
29
|
+
knowledgeCache = new Map();
|
|
30
|
+
cacheTTL = 3_600_000; // 1 hour
|
|
31
|
+
/** Stats */
|
|
32
|
+
stats = {
|
|
33
|
+
totalRequests: 0,
|
|
34
|
+
skippedByRules: 0,
|
|
35
|
+
routedToLocal: 0,
|
|
36
|
+
routedToCloud: 0,
|
|
37
|
+
servedFromCache: 0,
|
|
38
|
+
blockedByQuota: 0,
|
|
39
|
+
};
|
|
40
|
+
constructor(config) {
|
|
41
|
+
this.funnel = new FunnelRouter(config);
|
|
42
|
+
this.quota = new AIQuotaManager(config.tier, config.quotaOverride);
|
|
43
|
+
this.skipAIThreshold = config.skipAIThreshold ?? 80;
|
|
44
|
+
this.preferLocalThreshold = config.preferLocalThreshold ?? 60;
|
|
45
|
+
this.localProvider = config.localProvider ?? null;
|
|
46
|
+
this.cloudProvider = config.cloudProvider ?? null;
|
|
47
|
+
logger.info('SmartRouter initialized', {
|
|
48
|
+
tier: config.tier,
|
|
49
|
+
skipAIThreshold: this.skipAIThreshold,
|
|
50
|
+
preferLocalThreshold: this.preferLocalThreshold,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Assess event complexity based on rule confidence
|
|
55
|
+
*/
|
|
56
|
+
assessComplexity(ruleConfidence, hasAttackChain) {
|
|
57
|
+
// High confidence rule match: AI not needed
|
|
58
|
+
if (ruleConfidence >= this.skipAIThreshold && !hasAttackChain) {
|
|
59
|
+
return 'skip';
|
|
60
|
+
}
|
|
61
|
+
// Medium confidence or attack chain: local AI can handle
|
|
62
|
+
if (ruleConfidence >= this.preferLocalThreshold) {
|
|
63
|
+
return 'simple';
|
|
64
|
+
}
|
|
65
|
+
// Low confidence or unknown: needs cloud AI
|
|
66
|
+
return 'complex';
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Route an analysis request with smart cost optimization
|
|
70
|
+
*
|
|
71
|
+
* @param prompt - Analysis prompt
|
|
72
|
+
* @param ruleConfidence - Confidence from rule matches (0-100)
|
|
73
|
+
* @param hasAttackChain - Whether an attack chain was detected
|
|
74
|
+
* @param patternHash - Optional hash for knowledge cache lookup
|
|
75
|
+
* @param context - Optional analysis context
|
|
76
|
+
*/
|
|
77
|
+
async analyze(prompt, ruleConfidence, hasAttackChain, patternHash, context) {
|
|
78
|
+
this.stats.totalRequests++;
|
|
79
|
+
const complexity = this.assessComplexity(ruleConfidence, hasAttackChain);
|
|
80
|
+
// Skip AI entirely for high-confidence rule matches
|
|
81
|
+
if (complexity === 'skip') {
|
|
82
|
+
this.stats.skippedByRules++;
|
|
83
|
+
return {
|
|
84
|
+
result: null,
|
|
85
|
+
decision: {
|
|
86
|
+
complexity: 'skip',
|
|
87
|
+
provider: 'rules-only',
|
|
88
|
+
reason: `Rule confidence ${ruleConfidence}% >= ${this.skipAIThreshold}% threshold`,
|
|
89
|
+
quotaAllowed: true,
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
// Check knowledge cache
|
|
94
|
+
if (patternHash) {
|
|
95
|
+
const cached = this.knowledgeCache.get(patternHash);
|
|
96
|
+
if (cached && Date.now() - cached.timestamp < this.cacheTTL) {
|
|
97
|
+
this.stats.servedFromCache++;
|
|
98
|
+
return {
|
|
99
|
+
result: cached.result,
|
|
100
|
+
decision: {
|
|
101
|
+
complexity,
|
|
102
|
+
provider: 'local-ai',
|
|
103
|
+
reason: 'Served from knowledge cache (previously analyzed pattern)',
|
|
104
|
+
quotaAllowed: true,
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Check quota
|
|
110
|
+
const quotaCheck = this.quota.checkQuota();
|
|
111
|
+
if (!quotaCheck.allowed) {
|
|
112
|
+
this.stats.blockedByQuota++;
|
|
113
|
+
logger.warn('AI request blocked by quota', { reason: quotaCheck.reason });
|
|
114
|
+
return {
|
|
115
|
+
result: null,
|
|
116
|
+
decision: {
|
|
117
|
+
complexity,
|
|
118
|
+
provider: 'quota-blocked',
|
|
119
|
+
reason: quotaCheck.reason ?? 'Quota exceeded',
|
|
120
|
+
quotaAllowed: false,
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
// Route based on complexity
|
|
125
|
+
let result = null;
|
|
126
|
+
let provider = 'rules-only';
|
|
127
|
+
if (complexity === 'simple' && this.localProvider) {
|
|
128
|
+
// Simple events -> local AI (free)
|
|
129
|
+
try {
|
|
130
|
+
result = await this.localProvider.analyze(prompt, context);
|
|
131
|
+
provider = 'local-ai';
|
|
132
|
+
this.stats.routedToLocal++;
|
|
133
|
+
this.quota.recordCall(0); // Local is free
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// Fall through to cloud
|
|
137
|
+
logger.debug('Local AI failed for simple event, trying cloud');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (!result) {
|
|
141
|
+
// Complex events or local failure -> use funnel (tries local first, then cloud)
|
|
142
|
+
result = await this.funnel.analyze(prompt, context);
|
|
143
|
+
if (result) {
|
|
144
|
+
const funnelStatus = this.funnel.getStatus();
|
|
145
|
+
const usedCloud = funnelStatus.activeLayer === 'cloud-ai' ||
|
|
146
|
+
(!funnelStatus.local.available && funnelStatus.cloud.available);
|
|
147
|
+
if (usedCloud) {
|
|
148
|
+
provider = 'cloud-ai';
|
|
149
|
+
this.stats.routedToCloud++;
|
|
150
|
+
// Estimate cost: ~800 input tokens + ~200 output tokens at Claude Sonnet pricing
|
|
151
|
+
this.quota.recordCall(0.0054);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
provider = 'local-ai';
|
|
155
|
+
this.stats.routedToLocal++;
|
|
156
|
+
this.quota.recordCall(0);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Cache the result for knowledge distillation
|
|
161
|
+
if (patternHash && result) {
|
|
162
|
+
this.knowledgeCache.set(patternHash, { result, timestamp: Date.now() });
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
result,
|
|
166
|
+
decision: {
|
|
167
|
+
complexity,
|
|
168
|
+
provider,
|
|
169
|
+
reason: `Routed ${complexity} event to ${provider}`,
|
|
170
|
+
quotaAllowed: true,
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Record a distilled rule for a pattern (so future occurrences skip AI)
|
|
176
|
+
*/
|
|
177
|
+
recordDistilledPattern(patternHash, result) {
|
|
178
|
+
this.knowledgeCache.set(patternHash, { result, timestamp: Date.now() });
|
|
179
|
+
}
|
|
180
|
+
/** Get routing statistics */
|
|
181
|
+
getStats() {
|
|
182
|
+
return { ...this.stats };
|
|
183
|
+
}
|
|
184
|
+
/** Get quota usage */
|
|
185
|
+
getQuotaUsage() {
|
|
186
|
+
return this.quota.getUsage();
|
|
187
|
+
}
|
|
188
|
+
/** Get funnel status */
|
|
189
|
+
getFunnelStatus() {
|
|
190
|
+
return this.funnel.getStatus();
|
|
191
|
+
}
|
|
192
|
+
/** Start health checks on underlying funnel */
|
|
193
|
+
startHealthChecks(intervalMs) {
|
|
194
|
+
this.funnel.startHealthChecks(intervalMs);
|
|
195
|
+
}
|
|
196
|
+
/** Stop health checks */
|
|
197
|
+
stopHealthChecks() {
|
|
198
|
+
this.funnel.stopHealthChecks();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=smart-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-router.js","sourceRoot":"","sources":["../../src/ai/smart-router.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA+CH,KAAK,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;AAMxC,6CAA6C;AAC7C,eAAO,MAAM,CAAC;;;;;;;;;;;;kBAiBE,MAAM;oBACJ,MAAM;oBACN,MAAM;kBACR,MAAM;iBACP,MAAM;iBACN,MAAM;;;;;;;;;;;;;;;;;;;CAsBpB,CAAC;AAMF,uDAAuD;AACvD,eAAO,MAAM,OAAO;;;;;;;;;;CAUnB,CAAC;AAMF,0CAA0C;AAC1C,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAgBtD;AAED,+BAA+B;AAC/B,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED,+BAA+B;AAC/B,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAehD;AAMD;;;GAGG;AACH,wBAAgB,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAY/C;AAED,0BAA0B;AAC1B,wBAAgB,MAAM,CAAC,QAAQ,GAAE,MAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|