adaptive-memory-multi-model-router 2.14.17 → 2.14.18

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.
Files changed (34) hide show
  1. package/AGENT_COUNCIL_FINDINGS.md +142 -0
  2. package/LAUNCH_CHECKLIST.md +141 -0
  3. package/README.md.bak +836 -0
  4. package/articles/CHINESE_SUBMISSIONS_READY.md +322 -0
  5. package/articles/DEVTO_READY.md +255 -0
  6. package/articles/HN_POST_READY.md +137 -0
  7. package/articles/INDIEHACKERS_READY.md +120 -0
  8. package/articles/NEWSLETTER_SEND_NOW.md +259 -0
  9. package/articles/PRODUCTHUNT_READY.md +106 -0
  10. package/articles/REDDIT_SUBMISSION_READY.md +348 -0
  11. package/articles/TWEET_STORM_READY.md +165 -0
  12. package/council-votes/architecture-vote.md +121 -0
  13. package/council-votes/coverage-vote.md +93 -0
  14. package/dist/cost/costTracker.d.ts +109 -44
  15. package/dist/cost/costTracker.js +321 -98
  16. package/dist/cost/costTracker.js.map +1 -1
  17. package/dist/index.d.ts +6 -4
  18. package/dist/routing/advancedRouter.d.ts +38 -43
  19. package/dist/routing/advancedRouter.js +394 -408
  20. package/dist/routing/advancedRouter.js.map +1 -1
  21. package/dist/routing/providers/providerConfig.d.ts +49 -0
  22. package/dist/routing/providers/providerConfig.js +883 -0
  23. package/dist/routing/routing/advancedRouter.d.ts +62 -0
  24. package/dist/routing/routing/advancedRouter.js +447 -0
  25. package/dist/routing/utils/tokenUtils.d.ts +52 -0
  26. package/dist/routing/utils/tokenUtils.js +129 -0
  27. package/dist/server/proxyServer.d.ts +1 -1
  28. package/package.json +1 -1
  29. package/research-log.md +49 -0
  30. package/src/cost/costTracker.ts +576 -0
  31. package/src/routing/advancedRouter.ts +536 -0
  32. package/test-council/AGENT_COUNCIL_ARCHITECTURE.md +349 -0
  33. package/tests/security/guardrailEngine.test.ts +700 -0
  34. package/research/PUBLISH_LOG.md +0 -3
@@ -0,0 +1,93 @@
1
+ ## Test Coverage Vote
2
+
3
+ ### Finding 1: GuardrailEngine Has Zero Tests (CRITICAL)
4
+ - **Files:** `src/security/guardrails.ts` (500+ lines)
5
+ - **Problem:** Critical security module has NO tests despite handling:
6
+ - Prompt injection detection (DAN, jailbreak, ignore instructions)
7
+ - PII redaction (emails, phones, SSN, credit cards, API keys)
8
+ - Content filtering (violence, hate, self-harm)
9
+ - Output validation and hallucination detection
10
+ - **Solution:** Add comprehensive tests for:
11
+ - Each prompt injection pattern detection
12
+ - PII redaction for all types
13
+ - Content filter thresholds
14
+ - GuardrailEngine.checkInput() and checkOutput() full paths
15
+ - Custom guardrail registration
16
+ - Blocklist management
17
+ - **Tests gained:** ~25 tests covering security-critical paths
18
+
19
+ ### Finding 2: EnsembleOrchestrator Has Zero Tests (CORE P0)
20
+ - **Files:** `src/ensemble.ts`, `tests/routing/ensembleVoting.test.ts` (partial)
21
+ - **Problem:** Core P0 feature (parallel multi-LLM execution with result merging) has only partial tests in `tests/routing/`. The `EnsembleOrchestrator` class is NOT tested, and these critical paths are missing:
22
+ - Actual provider calls (mocked in ensembleVoting.test.ts)
23
+ - Majority voting strategy
24
+ - Weighted voting strategy
25
+ - Conservative strategy with uncertainty detection
26
+ - All-providers-fail error handling
27
+ - **Solution:** Add integration tests for EnsembleOrchestrator with:
28
+ - Mock providers returning different answers
29
+ - Strategy-specific voting logic
30
+ - Confidence scoring accuracy
31
+ - Reasoning generation
32
+ - **Tests gained:** ~15 tests for the unique differentiator
33
+
34
+ ### Finding 3: CostAnalytics Has Zero Tests (BUSINESS-CRITICAL)
35
+ - **Files:** `src/analytics/costAnalytics.ts`
36
+ - **Problem:** Cost tracking and savings calculation has no tests:
37
+ - No verification of savings calculation against known baselines
38
+ - No tests for BASELINE_COSTS accuracy
39
+ - No export format tests (JSON/CSV)
40
+ - No period filtering (hour/day/week/month)
41
+ - No auto-rotation when maxRecords exceeded
42
+ - **Solution:** Add tests for:
43
+ - Savings calculation accuracy (compare against known costs)
44
+ - Period filtering correctness
45
+ - Export format validation
46
+ - Provider/query type breakdown accuracy
47
+ - **Tests gained:** ~12 tests for cost accuracy
48
+
49
+ ### Finding 4: SDK Class (A3MRouter) Has Only Structure Tests
50
+ - **Files:** `src/sdk.ts`, `test-council/1-structure-tests.test.ts`
51
+ - **Problem:** SDK wrapper has basic type-checking but no behavioral tests:
52
+ - No tests for route() behavior
53
+ - No tests for analyze() feature extraction
54
+ - No tests for tier classification thresholds
55
+ - No tests for recommend() method
56
+ - **Solution:** Add behavioral tests verifying:
57
+ - Route decisions match expected patterns
58
+ - Feature extraction accuracy
59
+ - Tier classification boundaries (free/cheap/mid/premium)
60
+ - Batch routing consistency
61
+ - **Tests gained:** ~10 tests
62
+
63
+ ### Finding 5: Observability Middleware Not Tested
64
+ - **Files:** `src/observability/middleware.ts`
65
+ - **Problem:** Middleware components not tested:
66
+ - observabilityMiddleware not tested
67
+ - budgetAlertMiddleware not tested
68
+ - Integration with Express/Fastify not tested
69
+ - **Solution:** Add middleware tests verifying:
70
+ - Request/response interception
71
+ - Header injection
72
+ - Budget alert triggers
73
+ - Error propagation
74
+ - **Tests gained:** ~8 tests
75
+
76
+ ---
77
+
78
+ ## Vote
79
+
80
+ **I vote for Finding #1 (GuardrailEngine) as highest priority.**
81
+
82
+ ### Rationale:
83
+ 1. **Security-critical code without tests = production risk** - Prompt injection and PII handling bugs can leak sensitive data or bypass safety
84
+ 2. **Measurable impact** - Every user query goes through guardrails before routing
85
+ 3. **Clear scope** - 500+ lines with well-defined functions that are easy to test
86
+ 4. **Existing patterns** - The providerRetry.test.ts shows how to structure similar complex tests
87
+
88
+ ### Implementation estimate:
89
+ - **GuardrailEngine:** ~3 hours for comprehensive tests
90
+ - **EnsembleOrchestrator:** ~2 hours
91
+ - **CostAnalytics:** ~1.5 hours
92
+ - **SDK:** ~1 hour
93
+ - **Middleware:** ~1 hour
@@ -1,22 +1,109 @@
1
1
  /**
2
- * TMLPD Cost Tracker
2
+ * A3M Router - Budget Enforcer + Cost Tracker
3
3
  *
4
- * Tracks real-time spending across all providers.
5
- * Supports per-model budgets, spending alerts, and cost analysis.
4
+ * Hard budget enforcement for API key spend management:
5
+ * - Track spend per API key with monthly reset
6
+ * - Check budget before each request
7
+ * - Emit alerts at configurable thresholds (50%, 80%, 100%)
8
+ * - Support hard cap (reject requests) or soft cap (warn only)
9
+ * - In-memory storage (Redis backup can be added later)
10
+ *
11
+ * Plus legacy CostTracker for backward compatibility.
6
12
  */
13
+ import { EventEmitter } from 'events';
7
14
  export interface BudgetConfig {
8
- daily_limit?: number;
9
- monthly_limit?: number;
10
- per_model_limits?: Record<string, number>;
15
+ apiKey: string;
16
+ monthlyLimit: number;
17
+ alertThresholds?: number[];
18
+ hardCap?: boolean;
19
+ }
20
+ export interface SpendRecord {
21
+ apiKey: string;
22
+ spent: number;
23
+ budget: number;
24
+ remaining: number;
25
+ resetDate: Date;
26
+ alertEmitted: number[] | Set<number>;
27
+ }
28
+ export interface BudgetCheckResult {
29
+ allowed: boolean;
30
+ reason?: string;
31
+ remaining: number;
32
+ }
33
+ export declare class BudgetEnforcer extends EventEmitter {
34
+ budgets: Map<string, BudgetConfig>;
35
+ spend: Map<string, SpendRecord>;
36
+ static DEFAULT_THRESHOLDS: number[];
37
+ constructor();
38
+ /**
39
+ * Set budget for an API key
40
+ */
41
+ setBudget(apiKey: string, monthlyLimit: number, options?: {
42
+ alertThresholds?: number[];
43
+ hardCap?: boolean;
44
+ }): void;
45
+ /**
46
+ * Get current budget config for an API key
47
+ */
48
+ getBudgetConfig(apiKey: string): BudgetConfig | undefined;
49
+ /**
50
+ * Remove budget config (stops tracking)
51
+ */
52
+ removeBudget(apiKey: string): void;
53
+ /**
54
+ * Check if a request is allowed within budget
55
+ */
56
+ checkBudget(apiKey: string, additionalCost: number): BudgetCheckResult;
57
+ /**
58
+ * Record spend for an API key
59
+ */
60
+ recordSpend(apiKey: string, cost: number): void;
61
+ /**
62
+ * Get current spend record for an API key
63
+ */
64
+ getSpend(apiKey: string): SpendRecord | undefined;
65
+ /**
66
+ * Get all spend records
67
+ */
68
+ getAllSpend(): SpendRecord[];
69
+ /**
70
+ * Reset budget for an API key (manual reset)
71
+ */
72
+ resetBudget(apiKey: string): void;
73
+ /**
74
+ * Reset all budgets
75
+ */
76
+ resetAll(): void;
77
+ /**
78
+ * Update monthly limit for an API key
79
+ */
80
+ updateLimit(apiKey: string, monthlyLimit: number): void;
81
+ /**
82
+ * Check if reset is needed and perform it
83
+ */
84
+ checkAndReset(apiKey: string): void;
85
+ /**
86
+ * Check if monthly reset is due
87
+ */
88
+ isResetDue(resetDate: Date): boolean;
89
+ /**
90
+ * Get next monthly reset date
91
+ */
92
+ getNextResetDate(): Date;
93
+ /**
94
+ * Get days until next reset
95
+ */
96
+ getDaysUntilReset(apiKey: string): number | undefined;
11
97
  }
12
- export interface CostAlert {
13
- type: "daily" | "monthly" | "model" | "budget";
14
- threshold: number;
15
- current: number;
16
- provider?: string;
17
- model?: string;
98
+ export declare function createBudgetEnforcer(): BudgetEnforcer;
99
+ export declare class BudgetExceededError extends Error {
100
+ apiKey: string;
101
+ spent: number;
102
+ budget: number;
103
+ remaining: number;
104
+ constructor(apiKey: string, spent: number, budget: number);
18
105
  }
19
- export interface CostSnapshot {
106
+ interface CostSnapshot {
20
107
  provider: string;
21
108
  model: string;
22
109
  input_tokens: number;
@@ -26,7 +113,7 @@ export interface CostSnapshot {
26
113
  total_cost: number;
27
114
  timestamp: number;
28
115
  }
29
- export interface CostSummary {
116
+ interface CostSummary {
30
117
  total_cost: number;
31
118
  by_provider: Record<string, number>;
32
119
  by_model: Record<string, number>;
@@ -46,50 +133,28 @@ export declare class CostTracker {
46
133
  private alerts_callback;
47
134
  private daily_reset;
48
135
  private monthly_reset;
49
- constructor(budgets?: BudgetConfig);
50
- /**
51
- * Calculate cost for a model based on tokens
52
- */
136
+ constructor(budgets?: {
137
+ daily_limit?: number;
138
+ monthly_limit?: number;
139
+ per_model_limits?: Record<string, number>;
140
+ });
53
141
  calculateCost(model: string, input_tokens: number, output_tokens: number): {
54
142
  input: number;
55
143
  output: number;
56
144
  total: number;
57
145
  };
58
- /**
59
- * Record a request's cost
60
- */
61
146
  record(provider: string, model: string, input_tokens: number, output_tokens: number): CostSnapshot;
62
- /**
63
- * Check budgets and trigger alerts
64
- */
65
147
  private checkBudgets;
66
- /**
67
- * Emit an alert via callback
68
- */
69
148
  private emitAlert;
70
- /**
71
- * Register alert callback
72
- */
73
- onAlert(callback: (alert: CostAlert) => void): void;
74
- /**
75
- * Get comprehensive cost summary
76
- */
149
+ onAlert(callback: (alert: any) => void): void;
77
150
  getSummary(): CostSummary;
78
- /**
79
- * Get remaining budget
80
- */
81
151
  getRemainingBudget(): {
82
152
  daily: number | null;
83
153
  monthly: number | null;
84
154
  per_model: Record<string, number>;
85
155
  };
86
- /**
87
- * Reset cost history
88
- */
89
156
  reset(): void;
90
- /**
91
- * Export cost data for analysis
92
- */
93
157
  export(): CostSnapshot[];
158
+ getStatus(): CostSummary;
94
159
  }
95
- //# sourceMappingURL=costTracker.d.ts.map
160
+ export {};