@elizaos/training 2.0.0-alpha.21 → 2.0.0-alpha.22
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/.turbo/turbo-lint.log +2 -0
- package/.turbo/turbo-typecheck.log +1 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/adapter.js +59 -0
- package/dist/archetypes/ArchetypeConfigService.js +510 -0
- package/dist/archetypes/derive-archetype.js +196 -0
- package/dist/archetypes/index.js +7 -0
- package/dist/benchmark/ArchetypeMatchupBenchmark.js +547 -0
- package/dist/benchmark/BenchmarkChartGenerator.js +632 -0
- package/dist/benchmark/BenchmarkDataGenerator.js +825 -0
- package/dist/benchmark/BenchmarkDataViewer.js +197 -0
- package/dist/benchmark/BenchmarkHistoryService.js +135 -0
- package/dist/benchmark/BenchmarkRunner.js +483 -0
- package/dist/benchmark/BenchmarkValidator.js +158 -0
- package/dist/benchmark/FastEvalRunner.js +133 -0
- package/dist/benchmark/MetricsValidator.js +104 -0
- package/dist/benchmark/MetricsVisualizer.js +775 -0
- package/dist/benchmark/ModelBenchmarkService.js +433 -0
- package/dist/benchmark/ModelRegistry.js +122 -0
- package/dist/benchmark/RulerBenchmarkIntegration.js +168 -0
- package/dist/benchmark/SimulationA2AInterface.js +683 -0
- package/dist/benchmark/SimulationEngine.js +522 -0
- package/dist/benchmark/TaskRunner.js +60 -0
- package/dist/benchmark/__tests__/BenchmarkRunner.test.js +409 -0
- package/dist/benchmark/__tests__/HeadToHead.test.js +105 -0
- package/dist/benchmark/index.js +23 -0
- package/dist/benchmark/parseSimulationMetrics.js +86 -0
- package/dist/benchmark/simulation-types.js +1 -0
- package/dist/dependencies.js +197 -0
- package/dist/generation/TrajectoryGenerator.js +244 -0
- package/dist/generation/index.js +6 -0
- package/dist/huggingface/HuggingFaceDatasetUploader.js +463 -0
- package/dist/huggingface/HuggingFaceIntegrationService.js +272 -0
- package/dist/huggingface/HuggingFaceModelUploader.js +385 -0
- package/dist/huggingface/index.js +9 -0
- package/dist/huggingface/shared/HuggingFaceUploadUtil.js +144 -0
- package/dist/index.js +41 -0
- package/dist/init-training.js +43 -0
- package/dist/metrics/TrajectoryMetricsExtractor.js +523 -0
- package/dist/metrics/__tests__/TrajectoryMetricsExtractor.test.js +628 -0
- package/dist/metrics/index.js +7 -0
- package/dist/metrics/types.js +21 -0
- package/dist/rubrics/__tests__/index.test.js +150 -0
- package/dist/rubrics/ass-kisser.js +83 -0
- package/dist/rubrics/degen.js +78 -0
- package/dist/rubrics/goody-twoshoes.js +82 -0
- package/dist/rubrics/index.js +184 -0
- package/dist/rubrics/information-trader.js +82 -0
- package/dist/rubrics/infosec.js +99 -0
- package/dist/rubrics/liar.js +102 -0
- package/dist/rubrics/perps-trader.js +85 -0
- package/dist/rubrics/researcher.js +79 -0
- package/dist/rubrics/scammer.js +80 -0
- package/dist/rubrics/social-butterfly.js +71 -0
- package/dist/rubrics/super-predictor.js +95 -0
- package/dist/rubrics/trader.js +65 -0
- package/dist/scoring/ArchetypeScoringService.js +301 -0
- package/dist/scoring/JudgePromptBuilder.js +401 -0
- package/dist/scoring/LLMJudgeCache.js +263 -0
- package/dist/scoring/index.js +8 -0
- package/dist/training/AutomationPipeline.js +714 -0
- package/dist/training/BenchmarkService.js +370 -0
- package/dist/training/ConfigValidator.js +153 -0
- package/dist/training/MarketOutcomesTracker.js +142 -0
- package/dist/training/ModelDeployer.js +128 -0
- package/dist/training/ModelFetcher.js +48 -0
- package/dist/training/ModelSelectionService.js +248 -0
- package/dist/training/ModelUsageVerifier.js +106 -0
- package/dist/training/MultiModelOrchestrator.js +349 -0
- package/dist/training/RLModelConfig.js +295 -0
- package/dist/training/RewardBackpropagationService.js +117 -0
- package/dist/training/RulerScoringService.js +450 -0
- package/dist/training/TrainingMonitor.js +108 -0
- package/dist/training/TrajectoryRecorder.js +281 -0
- package/dist/training/__tests__/TrajectoryRecorder.test.js +363 -0
- package/dist/training/index.js +30 -0
- package/dist/training/logRLConfig.js +29 -0
- package/dist/training/pipeline.js +80 -0
- package/dist/training/storage/ModelStorageService.js +190 -0
- package/dist/training/storage/TrainingDataArchiver.js +136 -0
- package/dist/training/storage/index.js +7 -0
- package/dist/training/types.js +6 -0
- package/dist/training/window-utils.js +100 -0
- package/dist/utils/index.js +73 -0
- package/dist/utils/logger.js +55 -0
- package/dist/utils/snowflake.js +15 -0
- package/dist/utils/synthetic-detector.js +67 -0
- package/package.json +2 -2
- package/research-output/training-runs/training-run-1773742857616.json +38 -0
- package/research-output/training-runs/training-run-1773742946977.json +38 -0
- package/research-output/training-runs/training-run-1773743278891.json +38 -0
- package/research-output/training-runs/training-run-1773743409754.json +38 -0
- package/research-output/training-runs/training-run-1773743651086.json +38 -0
- package/research-output/training-runs/training-run-1773743782883.json +38 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External Dependencies for Training Package
|
|
3
|
+
*
|
|
4
|
+
* Defines interfaces for external dependencies that must be provided
|
|
5
|
+
* by the consuming application (e.g., apps/web). The training package
|
|
6
|
+
* is decoupled from specific implementations to maintain clean
|
|
7
|
+
* package boundaries.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { configureTrainingDependencies } from '@elizaos/training';
|
|
12
|
+
*
|
|
13
|
+
* configureTrainingDependencies({
|
|
14
|
+
* agentService,
|
|
15
|
+
* agentRuntimeManager,
|
|
16
|
+
* autonomousCoordinator,
|
|
17
|
+
* llmCaller,
|
|
18
|
+
* });
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @packageDocumentation
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Global configuration for external dependencies
|
|
25
|
+
* This should be initialized before using the training package
|
|
26
|
+
*/
|
|
27
|
+
let _agentService = null;
|
|
28
|
+
let _agentRuntimeManager = null;
|
|
29
|
+
let _autonomousCoordinator = null;
|
|
30
|
+
let _llmCaller = null;
|
|
31
|
+
let _exportGroupedForGRPO = null;
|
|
32
|
+
let _exportToHuggingFace = null;
|
|
33
|
+
let _toTrainingMessages = null;
|
|
34
|
+
/**
|
|
35
|
+
* Validate that a dependency has the expected shape at runtime.
|
|
36
|
+
* Throws immediately on misconfiguration instead of failing at call time.
|
|
37
|
+
*/
|
|
38
|
+
function assertFn(dep, name, methods) {
|
|
39
|
+
if (dep == null)
|
|
40
|
+
return; // allow explicit null/undefined (means "skip")
|
|
41
|
+
for (const method of methods) {
|
|
42
|
+
if (typeof dep[method] !== "function") {
|
|
43
|
+
throw new TypeError(`configureTrainingDependencies: ${name}.${method} must be a function, got ${typeof dep[method]}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Configure external dependencies.
|
|
49
|
+
*
|
|
50
|
+
* Performs runtime shape validation so mismatched adapters fail early with a
|
|
51
|
+
* clear error instead of silently producing broken behavior downstream.
|
|
52
|
+
*/
|
|
53
|
+
export function configureTrainingDependencies(config) {
|
|
54
|
+
// Runtime shape checks – catch adapter mismatches early
|
|
55
|
+
assertFn(config.agentService, "agentService", ["createAgent"]);
|
|
56
|
+
assertFn(config.agentRuntimeManager, "agentRuntimeManager", [
|
|
57
|
+
"getRuntime",
|
|
58
|
+
"resetRuntime",
|
|
59
|
+
]);
|
|
60
|
+
assertFn(config.autonomousCoordinator, "autonomousCoordinator", [
|
|
61
|
+
"executeAutonomousTick",
|
|
62
|
+
]);
|
|
63
|
+
assertFn(config.llmCaller, "llmCaller", ["callGroqDirect"]);
|
|
64
|
+
if (config.exportGroupedForGRPO !== undefined &&
|
|
65
|
+
config.exportGroupedForGRPO !== null &&
|
|
66
|
+
typeof config.exportGroupedForGRPO !== "function") {
|
|
67
|
+
throw new TypeError("configureTrainingDependencies: exportGroupedForGRPO must be a function");
|
|
68
|
+
}
|
|
69
|
+
if (config.exportToHuggingFace !== undefined &&
|
|
70
|
+
config.exportToHuggingFace !== null &&
|
|
71
|
+
typeof config.exportToHuggingFace !== "function") {
|
|
72
|
+
throw new TypeError("configureTrainingDependencies: exportToHuggingFace must be a function");
|
|
73
|
+
}
|
|
74
|
+
if (config.toTrainingMessages !== undefined &&
|
|
75
|
+
config.toTrainingMessages !== null &&
|
|
76
|
+
typeof config.toTrainingMessages !== "function") {
|
|
77
|
+
throw new TypeError("configureTrainingDependencies: toTrainingMessages must be a function");
|
|
78
|
+
}
|
|
79
|
+
if (config.agentService) {
|
|
80
|
+
_agentService = config.agentService;
|
|
81
|
+
}
|
|
82
|
+
if (config.agentRuntimeManager) {
|
|
83
|
+
_agentRuntimeManager = config.agentRuntimeManager;
|
|
84
|
+
}
|
|
85
|
+
if (config.autonomousCoordinator) {
|
|
86
|
+
_autonomousCoordinator = config.autonomousCoordinator;
|
|
87
|
+
}
|
|
88
|
+
if (config.llmCaller) {
|
|
89
|
+
_llmCaller = config.llmCaller;
|
|
90
|
+
}
|
|
91
|
+
if (config.exportGroupedForGRPO) {
|
|
92
|
+
_exportGroupedForGRPO = config.exportGroupedForGRPO;
|
|
93
|
+
}
|
|
94
|
+
if (config.exportToHuggingFace) {
|
|
95
|
+
_exportToHuggingFace = config.exportToHuggingFace;
|
|
96
|
+
}
|
|
97
|
+
if (config.toTrainingMessages) {
|
|
98
|
+
_toTrainingMessages = config.toTrainingMessages;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get the agent service
|
|
103
|
+
* @throws Error if not configured
|
|
104
|
+
*/
|
|
105
|
+
export function getAgentService() {
|
|
106
|
+
if (!_agentService) {
|
|
107
|
+
throw new Error("AgentService not configured. Call configureTrainingDependencies() first.");
|
|
108
|
+
}
|
|
109
|
+
return _agentService;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Get the agent runtime manager
|
|
113
|
+
* @throws Error if not configured
|
|
114
|
+
*/
|
|
115
|
+
export function getAgentRuntimeManager() {
|
|
116
|
+
if (!_agentRuntimeManager) {
|
|
117
|
+
throw new Error("AgentRuntimeManager not configured. Call configureTrainingDependencies() first.");
|
|
118
|
+
}
|
|
119
|
+
return _agentRuntimeManager;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get the autonomous coordinator
|
|
123
|
+
* @throws Error if not configured
|
|
124
|
+
*/
|
|
125
|
+
export function getAutonomousCoordinator() {
|
|
126
|
+
if (!_autonomousCoordinator) {
|
|
127
|
+
throw new Error("AutonomousCoordinator not configured. Call configureTrainingDependencies() first.");
|
|
128
|
+
}
|
|
129
|
+
return _autonomousCoordinator;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Get the LLM caller
|
|
133
|
+
* @throws Error if not configured
|
|
134
|
+
*/
|
|
135
|
+
export function getLLMCaller() {
|
|
136
|
+
if (!_llmCaller) {
|
|
137
|
+
throw new Error("LLMCaller not configured. Call configureTrainingDependencies() first.");
|
|
138
|
+
}
|
|
139
|
+
return _llmCaller;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get the export function for GRPO
|
|
143
|
+
* @throws Error if not configured
|
|
144
|
+
*/
|
|
145
|
+
export function getExportGroupedForGRPO() {
|
|
146
|
+
if (!_exportGroupedForGRPO) {
|
|
147
|
+
throw new Error("exportGroupedForGRPO not configured. Call configureTrainingDependencies() first.");
|
|
148
|
+
}
|
|
149
|
+
return _exportGroupedForGRPO;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Get the export function for HuggingFace
|
|
153
|
+
* @throws Error if not configured
|
|
154
|
+
*/
|
|
155
|
+
export function getExportToHuggingFace() {
|
|
156
|
+
if (!_exportToHuggingFace) {
|
|
157
|
+
throw new Error("exportToHuggingFace not configured. Call configureTrainingDependencies() first.");
|
|
158
|
+
}
|
|
159
|
+
return _exportToHuggingFace;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Get the toTrainingMessages function
|
|
163
|
+
* @throws Error if not configured
|
|
164
|
+
*/
|
|
165
|
+
export function getToTrainingMessages() {
|
|
166
|
+
if (!_toTrainingMessages) {
|
|
167
|
+
throw new Error("toTrainingMessages not configured. Call configureTrainingDependencies() first.");
|
|
168
|
+
}
|
|
169
|
+
return _toTrainingMessages;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Check if dependencies are configured
|
|
173
|
+
*/
|
|
174
|
+
export function areDependenciesConfigured() {
|
|
175
|
+
return (_agentService !== null &&
|
|
176
|
+
_agentRuntimeManager !== null &&
|
|
177
|
+
_autonomousCoordinator !== null);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Check if specific agent dependencies are configured for parallel generation
|
|
181
|
+
*/
|
|
182
|
+
export function areAgentDependenciesConfigured() {
|
|
183
|
+
return (_agentService !== null &&
|
|
184
|
+
_agentRuntimeManager !== null &&
|
|
185
|
+
_autonomousCoordinator !== null);
|
|
186
|
+
}
|
|
187
|
+
let _taskInteractor = null;
|
|
188
|
+
export function configureTaskInteractor(interactor) {
|
|
189
|
+
assertFn(interactor, "taskInteractor", ["executeTask"]);
|
|
190
|
+
_taskInteractor = interactor;
|
|
191
|
+
}
|
|
192
|
+
export function getTaskInteractor() {
|
|
193
|
+
if (!_taskInteractor) {
|
|
194
|
+
throw new Error("TaskInteractor not configured. Call configureTaskInteractor() first.");
|
|
195
|
+
}
|
|
196
|
+
return _taskInteractor;
|
|
197
|
+
}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TrajectoryGenerator
|
|
3
|
+
*
|
|
4
|
+
* Generates real trajectories using real agents running in parallel.
|
|
5
|
+
* Uses AutonomousCoordinator with trajectory recording enabled.
|
|
6
|
+
*
|
|
7
|
+
* Requires dependencies via configureTrainingDependencies() before use.
|
|
8
|
+
*
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
*/
|
|
11
|
+
import { getTrainingDataAdapter } from "../adapter";
|
|
12
|
+
import { ArchetypeConfigService } from "../archetypes/ArchetypeConfigService";
|
|
13
|
+
import { areAgentDependenciesConfigured, getAgentRuntimeManager, getAgentService, getAutonomousCoordinator, } from "../dependencies";
|
|
14
|
+
import { logger } from "../utils/logger";
|
|
15
|
+
/**
|
|
16
|
+
* Ensure dependencies are configured before use
|
|
17
|
+
*/
|
|
18
|
+
function ensureDependencies() {
|
|
19
|
+
if (!areAgentDependenciesConfigured()) {
|
|
20
|
+
throw new Error("Training dependencies not configured. Call configureTrainingDependencies() with agentService, agentRuntimeManager, and autonomousCoordinator first.");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Generator that creates and runs real agents in parallel
|
|
25
|
+
*/
|
|
26
|
+
export class TrajectoryGenerator {
|
|
27
|
+
config;
|
|
28
|
+
agents = new Map();
|
|
29
|
+
constructor(config) {
|
|
30
|
+
this.config = {
|
|
31
|
+
...config,
|
|
32
|
+
recordTrajectories: true, // Always record for training
|
|
33
|
+
parallelAgents: Math.min(config.parallelAgents || 5, 10), // Cap at 10 for safety
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Create agents based on archetypes
|
|
38
|
+
*/
|
|
39
|
+
async createArchetypeAgents() {
|
|
40
|
+
ensureDependencies();
|
|
41
|
+
const agentService = getAgentService();
|
|
42
|
+
logger.info("Creating archetype-based agents...", {
|
|
43
|
+
archetypes: this.config.archetypes,
|
|
44
|
+
perArchetype: this.config.agentsPerArchetype,
|
|
45
|
+
}, "TrajectoryGenerator");
|
|
46
|
+
for (const archetype of this.config.archetypes) {
|
|
47
|
+
const archetypeConfig = ArchetypeConfigService.getConfig(archetype);
|
|
48
|
+
for (let i = 0; i < this.config.agentsPerArchetype; i++) {
|
|
49
|
+
// Create agent using the actual AgentService
|
|
50
|
+
// Use small initial deposit to avoid insufficient points errors
|
|
51
|
+
const agent = await agentService.createAgent({
|
|
52
|
+
userId: this.config.managerId,
|
|
53
|
+
name: `${archetypeConfig.name} ${i + 1}`,
|
|
54
|
+
description: archetypeConfig.description,
|
|
55
|
+
bio: archetypeConfig.bio,
|
|
56
|
+
personality: archetypeConfig.personality,
|
|
57
|
+
tradingStrategy: archetypeConfig.tradingStrategy,
|
|
58
|
+
system: archetypeConfig.system,
|
|
59
|
+
initialDeposit: 100, // Small deposit for training agents
|
|
60
|
+
});
|
|
61
|
+
// Update autonomous settings in agent config based on archetype
|
|
62
|
+
// Disable A2A to allow offline training without localhost server
|
|
63
|
+
await getTrainingDataAdapter().updateAgentConfig(agent.id, {
|
|
64
|
+
autonomousTrading: archetypeConfig.actionWeights.trade > 0.3,
|
|
65
|
+
autonomousPosting: archetypeConfig.postFrequency !== "low",
|
|
66
|
+
autonomousCommenting: archetypeConfig.engagementStyle === "helpful" ||
|
|
67
|
+
archetypeConfig.engagementStyle === "analytical",
|
|
68
|
+
autonomousDMs: archetypeConfig.dmActivity,
|
|
69
|
+
autonomousGroupChats: archetypeConfig.groupChatActivity,
|
|
70
|
+
maxActionsPerTick: 5,
|
|
71
|
+
a2aEnabled: false, // Disable A2A for training
|
|
72
|
+
updatedAt: new Date(),
|
|
73
|
+
});
|
|
74
|
+
this.agents.set(agent.id, { user: agent, archetype });
|
|
75
|
+
logger.info(`Created ${archetype} agent: ${agent.username}`, {}, "TrajectoryGenerator");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
logger.info(`Created ${this.agents.size} agents total`, {}, "TrajectoryGenerator");
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Run agents in parallel batches
|
|
82
|
+
*/
|
|
83
|
+
async runParallelBatch(agentIds) {
|
|
84
|
+
ensureDependencies();
|
|
85
|
+
const agentRuntimeManager = getAgentRuntimeManager();
|
|
86
|
+
const autonomousCoordinator = getAutonomousCoordinator();
|
|
87
|
+
const trajectoryIds = [];
|
|
88
|
+
const errors = [];
|
|
89
|
+
// Create promises for parallel execution
|
|
90
|
+
const promises = agentIds.map(async (agentId) => {
|
|
91
|
+
const agentInfo = this.agents.get(agentId);
|
|
92
|
+
if (!agentInfo)
|
|
93
|
+
return;
|
|
94
|
+
// Get agent runtime - disable A2A for training to avoid connection errors
|
|
95
|
+
let runtime;
|
|
96
|
+
const runtimeResult = await agentRuntimeManager.getRuntime(agentId);
|
|
97
|
+
// If runtime creation returns null/undefined, skip
|
|
98
|
+
if (!runtimeResult) {
|
|
99
|
+
logger.warn(`Runtime creation returned null for ${agentId}, skipping`, {}, "TrajectoryGenerator");
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
runtime = runtimeResult;
|
|
103
|
+
// Apply archetype configuration to runtime character if available
|
|
104
|
+
const archetypeConfig = ArchetypeConfigService.getConfig(agentInfo.archetype);
|
|
105
|
+
const character = runtime.character;
|
|
106
|
+
if (character) {
|
|
107
|
+
character.name = archetypeConfig.name;
|
|
108
|
+
character.bio = archetypeConfig.bio.join(" ");
|
|
109
|
+
if (!character.topics) {
|
|
110
|
+
character.topics = [];
|
|
111
|
+
}
|
|
112
|
+
// Add archetype-specific topics
|
|
113
|
+
if (archetypeConfig.preferredMarkets.includes("perpetual")) {
|
|
114
|
+
character.topics.push("perpetual_trading", "leverage");
|
|
115
|
+
}
|
|
116
|
+
if (archetypeConfig.preferredMarkets.includes("prediction")) {
|
|
117
|
+
character.topics.push("prediction_markets", "forecasting");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Run ticks for this agent
|
|
121
|
+
for (let tick = 0; tick < this.config.ticksPerAgent; tick++) {
|
|
122
|
+
logger.debug(`Agent ${agentInfo.user.username} - Tick ${tick + 1}/${this.config.ticksPerAgent}`);
|
|
123
|
+
// Execute autonomous tick with trajectory recording
|
|
124
|
+
const result = await autonomousCoordinator.executeAutonomousTick(agentId, runtime, true);
|
|
125
|
+
if (result.trajectoryId) {
|
|
126
|
+
trajectoryIds.push(result.trajectoryId);
|
|
127
|
+
logger.debug(`Recorded trajectory ${result.trajectoryId} for ${agentInfo.user.username}`);
|
|
128
|
+
}
|
|
129
|
+
// Small delay between ticks
|
|
130
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
131
|
+
}
|
|
132
|
+
logger.info(`Completed ${this.config.ticksPerAgent} ticks for ${agentInfo.user.username}`, {
|
|
133
|
+
trajectories: trajectoryIds.length,
|
|
134
|
+
archetype: agentInfo.archetype,
|
|
135
|
+
}, "TrajectoryGenerator");
|
|
136
|
+
});
|
|
137
|
+
// Wait for all agents in batch to complete
|
|
138
|
+
await Promise.allSettled(promises).then((results) => {
|
|
139
|
+
for (const result of results) {
|
|
140
|
+
if (result.status === "rejected") {
|
|
141
|
+
const errorMsg = `Agent batch error: ${result.reason instanceof Error ? result.reason.message : String(result.reason)}`;
|
|
142
|
+
logger.error(errorMsg, { error: result.reason }, "TrajectoryGenerator");
|
|
143
|
+
errors.push(errorMsg);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
return { trajectoryIds, errors };
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Generate trajectories with parallel agent execution
|
|
151
|
+
*/
|
|
152
|
+
async generate() {
|
|
153
|
+
const startTime = Date.now();
|
|
154
|
+
const result = {
|
|
155
|
+
agentsCreated: [],
|
|
156
|
+
trajectoryIds: [],
|
|
157
|
+
totalTicks: 0,
|
|
158
|
+
duration: 0,
|
|
159
|
+
errors: [],
|
|
160
|
+
archetypeStats: {},
|
|
161
|
+
};
|
|
162
|
+
// Create agents
|
|
163
|
+
await this.createArchetypeAgents();
|
|
164
|
+
result.agentsCreated = Array.from(this.agents.keys());
|
|
165
|
+
// Initialize stats
|
|
166
|
+
for (const archetype of this.config.archetypes) {
|
|
167
|
+
result.archetypeStats[archetype] = {
|
|
168
|
+
agents: 0,
|
|
169
|
+
trajectories: 0,
|
|
170
|
+
avgTicksPerAgent: 0,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
// Count agents per archetype
|
|
174
|
+
for (const [_, agentInfo] of this.agents) {
|
|
175
|
+
const stat = result.archetypeStats[agentInfo.archetype];
|
|
176
|
+
if (stat) {
|
|
177
|
+
stat.agents++;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
logger.info("Starting parallel trajectory generation", {
|
|
181
|
+
totalAgents: this.agents.size,
|
|
182
|
+
parallelBatches: Math.ceil(this.agents.size / this.config.parallelAgents),
|
|
183
|
+
ticksPerAgent: this.config.ticksPerAgent,
|
|
184
|
+
}, "TrajectoryGenerator");
|
|
185
|
+
// Process agents in parallel batches
|
|
186
|
+
const agentIds = Array.from(this.agents.keys());
|
|
187
|
+
for (let i = 0; i < agentIds.length; i += this.config.parallelAgents) {
|
|
188
|
+
const batch = agentIds.slice(i, i + this.config.parallelAgents);
|
|
189
|
+
logger.info(`Processing batch ${Math.floor(i / this.config.parallelAgents) + 1}/${Math.ceil(agentIds.length / this.config.parallelAgents)}`, {
|
|
190
|
+
agents: batch.length,
|
|
191
|
+
}, "TrajectoryGenerator");
|
|
192
|
+
const batchResult = await this.runParallelBatch(batch);
|
|
193
|
+
result.trajectoryIds.push(...batchResult.trajectoryIds);
|
|
194
|
+
result.errors.push(...batchResult.errors);
|
|
195
|
+
result.totalTicks += batch.length * this.config.ticksPerAgent;
|
|
196
|
+
}
|
|
197
|
+
// Calculate stats
|
|
198
|
+
for (const trajId of result.trajectoryIds) {
|
|
199
|
+
// Get trajectory to determine archetype
|
|
200
|
+
const trajectory = await getTrainingDataAdapter().getTrajectoryById(trajId);
|
|
201
|
+
if (trajectory) {
|
|
202
|
+
const agentInfo = this.agents.get(trajectory.agentId);
|
|
203
|
+
if (agentInfo) {
|
|
204
|
+
const stat = result.archetypeStats[agentInfo.archetype];
|
|
205
|
+
if (stat) {
|
|
206
|
+
stat.trajectories++;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
// Calculate averages
|
|
212
|
+
for (const stats of Object.values(result.archetypeStats)) {
|
|
213
|
+
if (stats.agents > 0) {
|
|
214
|
+
stats.avgTicksPerAgent = stats.trajectories / stats.agents;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
result.duration = Date.now() - startTime;
|
|
218
|
+
logger.info("Parallel generation complete", {
|
|
219
|
+
agents: result.agentsCreated.length,
|
|
220
|
+
trajectories: result.trajectoryIds.length,
|
|
221
|
+
totalTicks: result.totalTicks,
|
|
222
|
+
durationSeconds: result.duration / 1000,
|
|
223
|
+
errors: result.errors.length,
|
|
224
|
+
}, "TrajectoryGenerator");
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Cleanup created agents (for testing)
|
|
229
|
+
*/
|
|
230
|
+
async cleanup() {
|
|
231
|
+
logger.info(`Cleaning up ${this.agents.size} agents...`, {}, "TrajectoryGenerator");
|
|
232
|
+
const adapter = getTrainingDataAdapter();
|
|
233
|
+
for (const [agentId] of this.agents) {
|
|
234
|
+
await adapter.deleteUser(agentId);
|
|
235
|
+
}
|
|
236
|
+
logger.info("Cleanup complete", {}, "TrajectoryGenerator");
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Factory function for creating parallel generator
|
|
241
|
+
*/
|
|
242
|
+
export async function createParallelGenerator(config) {
|
|
243
|
+
return new TrajectoryGenerator(config);
|
|
244
|
+
}
|