Update source code and remove runtime data from tracking
Add gitignore rules for browser session data, SQLite databases, media downloads, and build artifacts. Remove previously tracked runtime files from the repository. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
e90213d1ff
commit
dfa0580859
23 files changed
+5324
-347
No files matched your search
@@ -0,0 +1,101 @@
|
||||
import type { Config } from '../config/index.js';
|
||||
import type { MessagesRepository, StrategyStats } from '../database/repositories.js';
|
||||
import type { Logger } from '../utils/logger.js';
|
||||
|
||||
export interface SelectedStrategy {
|
||||
id: string;
|
||||
promptOverride: string;
|
||||
reason: 'exploit' | 'explore';
|
||||
}
|
||||
|
||||
export class StrategySelector {
|
||||
private variants: Config['strategies']['variants'];
|
||||
private explorationRate: number;
|
||||
private minSamples: number;
|
||||
|
||||
constructor(
|
||||
private config: Config,
|
||||
private messagesRepo: MessagesRepository,
|
||||
private logger: Logger
|
||||
) {
|
||||
this.variants = config.strategies.variants;
|
||||
this.explorationRate = config.strategies.explorationRate;
|
||||
this.minSamples = config.strategies.minSamples;
|
||||
}
|
||||
|
||||
selectStrategy(): SelectedStrategy | null {
|
||||
if (this.variants.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Exploration: random strategy
|
||||
if (Math.random() < this.explorationRate) {
|
||||
const variant = this.variants[Math.floor(Math.random() * this.variants.length)];
|
||||
this.logger.debug(`Strategy selected (explore): ${variant.id}`);
|
||||
return { id: variant.id, promptOverride: variant.promptOverride, reason: 'explore' };
|
||||
}
|
||||
|
||||
// Exploitation: pick the best-performing strategy
|
||||
const stats = this.messagesRepo.getStrategyStats();
|
||||
const statsMap = new Map(stats.map(s => [s.strategyId, s]));
|
||||
|
||||
// Find strategies with insufficient samples - prioritize exploring them
|
||||
const unexplored = this.variants.filter(v => {
|
||||
const s = statsMap.get(v.id);
|
||||
return !s || s.totalSent < this.minSamples;
|
||||
});
|
||||
|
||||
if (unexplored.length > 0) {
|
||||
const variant = unexplored[Math.floor(Math.random() * unexplored.length)];
|
||||
this.logger.debug(`Strategy selected (under-sampled): ${variant.id}`);
|
||||
return { id: variant.id, promptOverride: variant.promptOverride, reason: 'explore' };
|
||||
}
|
||||
|
||||
// All strategies have enough samples - pick the best response rate
|
||||
let bestVariant = this.variants[0];
|
||||
let bestRate = -1;
|
||||
|
||||
for (const variant of this.variants) {
|
||||
const s = statsMap.get(variant.id);
|
||||
if (s && s.responseRate > bestRate) {
|
||||
bestRate = s.responseRate;
|
||||
bestVariant = variant;
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.debug(`Strategy selected (exploit, ${bestRate}% response rate): ${bestVariant.id}`);
|
||||
return { id: bestVariant.id, promptOverride: bestVariant.promptOverride, reason: 'exploit' };
|
||||
}
|
||||
|
||||
getStats(): (StrategyStats & { configured: boolean })[] {
|
||||
const dbStats = this.messagesRepo.getStrategyStats();
|
||||
const statsMap = new Map(dbStats.map(s => [s.strategyId, s]));
|
||||
|
||||
// Include all configured variants, even if they have no data yet
|
||||
const results: (StrategyStats & { configured: boolean })[] = [];
|
||||
|
||||
for (const variant of this.variants) {
|
||||
const s = statsMap.get(variant.id);
|
||||
results.push({
|
||||
strategyId: variant.id,
|
||||
totalSent: s?.totalSent || 0,
|
||||
totalResponses: s?.totalResponses || 0,
|
||||
responseRate: s?.responseRate || 0,
|
||||
configured: true,
|
||||
});
|
||||
}
|
||||
|
||||
// Include any historical strategies no longer in config
|
||||
for (const s of dbStats) {
|
||||
if (!this.variants.some(v => v.id === s.strategyId)) {
|
||||
results.push({ ...s, configured: false });
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
hasStrategies(): boolean {
|
||||
return this.variants.length > 0;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user