@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,683 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simulation A2A Interface
|
|
3
|
+
*
|
|
4
|
+
* Provides A2A-compatible interface for agents to interact with simulation.
|
|
5
|
+
* Wraps SimulationEngine to make it behave like a real game server.
|
|
6
|
+
*
|
|
7
|
+
* Agents can use standard A2A methods like:
|
|
8
|
+
* - a2a.getPredictions
|
|
9
|
+
* - a2a.buyShares
|
|
10
|
+
* - a2a.openPosition
|
|
11
|
+
* - a2a.getFeed
|
|
12
|
+
* etc.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const interface = new SimulationA2AInterface(engine, 'agent-123');
|
|
17
|
+
* const predictions = await interface.sendRequest('a2a.getPredictions');
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
import { logger } from "../utils/logger";
|
|
21
|
+
export class SimulationA2AInterface {
|
|
22
|
+
engine;
|
|
23
|
+
agentId;
|
|
24
|
+
/**
|
|
25
|
+
* Create a new SimulationA2AInterface instance
|
|
26
|
+
*
|
|
27
|
+
* @param engine - Simulation engine to wrap
|
|
28
|
+
* @param agentId - Agent identifier for this interface instance
|
|
29
|
+
*/
|
|
30
|
+
constructor(engine, agentId) {
|
|
31
|
+
this.engine = engine;
|
|
32
|
+
this.agentId = agentId;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Send A2A request (JSON-RPC style)
|
|
36
|
+
*
|
|
37
|
+
* Routes requests to appropriate handler methods based on method name.
|
|
38
|
+
* All methods are logged and timed.
|
|
39
|
+
*
|
|
40
|
+
* @param method - A2A method name (e.g., 'a2a.getPredictions')
|
|
41
|
+
* @param params - Optional parameters for the method
|
|
42
|
+
* @returns Method-specific result (type depends on method)
|
|
43
|
+
* @throws Error if method is unknown or handler fails
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* const result = await interface.sendRequest('a2a.getPredictions');
|
|
48
|
+
* const buyResult = await interface.sendRequest('a2a.buyShares', {
|
|
49
|
+
* marketId: 'market-1',
|
|
50
|
+
* outcome: 'YES',
|
|
51
|
+
* amount: 100
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
async sendRequest(method, params) {
|
|
56
|
+
logger.debug("Simulation A2A request", { method, params });
|
|
57
|
+
const actionStart = Date.now();
|
|
58
|
+
try {
|
|
59
|
+
let result;
|
|
60
|
+
// Route to appropriate handler
|
|
61
|
+
switch (method) {
|
|
62
|
+
case "a2a.getPredictions":
|
|
63
|
+
result = this.handleGetPredictions(params);
|
|
64
|
+
break;
|
|
65
|
+
case "a2a.buyShares":
|
|
66
|
+
result = await this.handleBuyShares(params);
|
|
67
|
+
break;
|
|
68
|
+
case "a2a.sellShares":
|
|
69
|
+
result = await this.handleSellShares(params);
|
|
70
|
+
break;
|
|
71
|
+
case "a2a.getPerpetuals":
|
|
72
|
+
result = this.handleGetPerpetuals(params);
|
|
73
|
+
break;
|
|
74
|
+
case "a2a.openPosition":
|
|
75
|
+
result = await this.handleOpenPosition(params);
|
|
76
|
+
break;
|
|
77
|
+
case "a2a.closePosition":
|
|
78
|
+
result = await this.handleClosePosition(params);
|
|
79
|
+
break;
|
|
80
|
+
case "a2a.getFeed":
|
|
81
|
+
result = this.handleGetFeed(params);
|
|
82
|
+
break;
|
|
83
|
+
case "a2a.createPost":
|
|
84
|
+
result = await this.handleCreatePost(params);
|
|
85
|
+
break;
|
|
86
|
+
case "a2a.getChats":
|
|
87
|
+
result = this.handleGetChats(params);
|
|
88
|
+
break;
|
|
89
|
+
case "a2a.joinGroup":
|
|
90
|
+
result = await this.handleJoinGroup(params);
|
|
91
|
+
break;
|
|
92
|
+
case "a2a.getBalance":
|
|
93
|
+
result = this.handleGetBalance(params);
|
|
94
|
+
break;
|
|
95
|
+
case "a2a.getPortfolio":
|
|
96
|
+
result = this.handleGetPortfolio(params);
|
|
97
|
+
break;
|
|
98
|
+
case "a2a.getPositions":
|
|
99
|
+
result = this.handleGetPositions(params);
|
|
100
|
+
break;
|
|
101
|
+
case "a2a.getDashboard":
|
|
102
|
+
result = this.handleGetDashboard(params);
|
|
103
|
+
break;
|
|
104
|
+
case "a2a.getTrendingTags":
|
|
105
|
+
result = this.handleGetTrendingTags(params);
|
|
106
|
+
break;
|
|
107
|
+
default:
|
|
108
|
+
throw new Error(`Unknown A2A method: ${method}`);
|
|
109
|
+
}
|
|
110
|
+
// This allows the agent to make multiple A2A calls within a single tick
|
|
111
|
+
const duration = Date.now() - actionStart;
|
|
112
|
+
logger.debug("Simulation A2A response", { method, duration });
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
logger.error("Simulation A2A error", { method, error });
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get prediction markets
|
|
122
|
+
*
|
|
123
|
+
* Returns all unresolved prediction markets from the simulation state.
|
|
124
|
+
*
|
|
125
|
+
* @param _params - Unused (kept for interface consistency)
|
|
126
|
+
* @returns Object containing array of prediction markets
|
|
127
|
+
*/
|
|
128
|
+
handleGetPredictions(_params) {
|
|
129
|
+
const state = this.engine.getGameState();
|
|
130
|
+
const predictions = state.predictionMarkets
|
|
131
|
+
.filter((m) => !m.resolved)
|
|
132
|
+
.map((m) => ({
|
|
133
|
+
id: m.id,
|
|
134
|
+
question: m.question,
|
|
135
|
+
yesShares: m.yesShares,
|
|
136
|
+
noShares: m.noShares,
|
|
137
|
+
yesPrice: m.yesPrice,
|
|
138
|
+
noPrice: m.noPrice,
|
|
139
|
+
liquidity: m.liquidity,
|
|
140
|
+
totalVolume: m.totalVolume,
|
|
141
|
+
createdAt: m.createdAt,
|
|
142
|
+
resolveAt: m.resolveAt,
|
|
143
|
+
}));
|
|
144
|
+
return { predictions };
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Type guard for BuySharesParams
|
|
148
|
+
*/
|
|
149
|
+
isBuySharesParams(params) {
|
|
150
|
+
return (typeof params === "object" &&
|
|
151
|
+
params !== null &&
|
|
152
|
+
"marketId" in params &&
|
|
153
|
+
"outcome" in params &&
|
|
154
|
+
"amount" in params &&
|
|
155
|
+
typeof params.marketId === "string" &&
|
|
156
|
+
(params.outcome === "YES" || params.outcome === "NO") &&
|
|
157
|
+
typeof params.amount === "number" &&
|
|
158
|
+
params.amount > 0);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Buy prediction market shares
|
|
162
|
+
*
|
|
163
|
+
* Executes a buy action through the simulation engine and returns the result.
|
|
164
|
+
*
|
|
165
|
+
* @param params - Buy shares parameters
|
|
166
|
+
* @returns Object with shares purchased, average price, and position ID
|
|
167
|
+
* @throws Error if buy action fails
|
|
168
|
+
*/
|
|
169
|
+
async handleBuyShares(params) {
|
|
170
|
+
if (!params || !this.isBuySharesParams(params)) {
|
|
171
|
+
throw new Error('Invalid params: must be an object with marketId (string), outcome ("YES" | "NO"), and amount (positive number)');
|
|
172
|
+
}
|
|
173
|
+
const { marketId, outcome, amount } = params;
|
|
174
|
+
const result = await this.engine.performAction("buy_prediction", {
|
|
175
|
+
marketId,
|
|
176
|
+
outcome,
|
|
177
|
+
amount,
|
|
178
|
+
});
|
|
179
|
+
if (!result.success) {
|
|
180
|
+
throw new Error(result.error || "Failed to buy shares");
|
|
181
|
+
}
|
|
182
|
+
const { positionId, shares } = result.result;
|
|
183
|
+
const state = this.engine.getGameState();
|
|
184
|
+
const market = state.predictionMarkets.find((m) => m.id === marketId);
|
|
185
|
+
const avgPrice = market
|
|
186
|
+
? outcome === "YES"
|
|
187
|
+
? market.yesPrice
|
|
188
|
+
: market.noPrice
|
|
189
|
+
: 0.5;
|
|
190
|
+
return { shares, avgPrice, positionId };
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Type guard for SellSharesParams
|
|
194
|
+
*/
|
|
195
|
+
isSellSharesParams(params) {
|
|
196
|
+
return (typeof params === "object" &&
|
|
197
|
+
params !== null &&
|
|
198
|
+
"marketId" in params &&
|
|
199
|
+
"shares" in params &&
|
|
200
|
+
typeof params.marketId === "string" &&
|
|
201
|
+
typeof params.shares === "number" &&
|
|
202
|
+
params.shares > 0);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Sell prediction market shares
|
|
206
|
+
*
|
|
207
|
+
* Calculates proceeds from selling shares based on current market prices.
|
|
208
|
+
*
|
|
209
|
+
* @param params - Sell shares parameters
|
|
210
|
+
* @returns Object with proceeds from sale
|
|
211
|
+
* @throws Error if market not found
|
|
212
|
+
*/
|
|
213
|
+
async handleSellShares(params) {
|
|
214
|
+
if (!params || !this.isSellSharesParams(params)) {
|
|
215
|
+
throw new Error("Invalid params: must be an object with marketId (string) and shares (positive number)");
|
|
216
|
+
}
|
|
217
|
+
const { marketId, shares } = params;
|
|
218
|
+
// Simplified: calculate proceeds based on current market price
|
|
219
|
+
const state = this.engine.getGameState();
|
|
220
|
+
const market = state.predictionMarkets.find((m) => m.id === marketId);
|
|
221
|
+
if (!market) {
|
|
222
|
+
throw new Error(`Market ${marketId} not found`);
|
|
223
|
+
}
|
|
224
|
+
// Use average of yes and no prices as sell price
|
|
225
|
+
const avgPrice = (market.yesPrice + market.noPrice) / 2;
|
|
226
|
+
const proceeds = shares * avgPrice;
|
|
227
|
+
return { proceeds };
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Get perpetual markets
|
|
231
|
+
*
|
|
232
|
+
* Returns all perpetual markets from the simulation state.
|
|
233
|
+
*
|
|
234
|
+
* @param _params - Unused (kept for interface consistency)
|
|
235
|
+
* @returns Object containing array of perpetual markets
|
|
236
|
+
*/
|
|
237
|
+
handleGetPerpetuals(_params) {
|
|
238
|
+
const state = this.engine.getGameState();
|
|
239
|
+
const perpetuals = state.perpetualMarkets.map((m) => ({
|
|
240
|
+
ticker: m.ticker,
|
|
241
|
+
price: m.price,
|
|
242
|
+
priceChange24h: m.priceChange24h,
|
|
243
|
+
volume24h: m.volume24h,
|
|
244
|
+
openInterest: m.openInterest,
|
|
245
|
+
fundingRate: m.fundingRate,
|
|
246
|
+
nextFundingTime: m.nextFundingTime,
|
|
247
|
+
}));
|
|
248
|
+
return { perpetuals };
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Type guard for OpenPositionParams
|
|
252
|
+
*/
|
|
253
|
+
isOpenPositionParams(params) {
|
|
254
|
+
return (typeof params === "object" &&
|
|
255
|
+
params !== null &&
|
|
256
|
+
"ticker" in params &&
|
|
257
|
+
"side" in params &&
|
|
258
|
+
"size" in params &&
|
|
259
|
+
"leverage" in params &&
|
|
260
|
+
typeof params.ticker === "string" &&
|
|
261
|
+
(params.side === "LONG" || params.side === "SHORT") &&
|
|
262
|
+
typeof params.size === "number" &&
|
|
263
|
+
params.size > 0 &&
|
|
264
|
+
typeof params.leverage === "number" &&
|
|
265
|
+
params.leverage >= 1);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Open perpetual position
|
|
269
|
+
*
|
|
270
|
+
* Executes an open position action through the simulation engine.
|
|
271
|
+
*
|
|
272
|
+
* @param params - Open position parameters
|
|
273
|
+
* @returns Object with position ID and entry price
|
|
274
|
+
* @throws Error if open action fails
|
|
275
|
+
*/
|
|
276
|
+
async handleOpenPosition(params) {
|
|
277
|
+
if (!params || !this.isOpenPositionParams(params)) {
|
|
278
|
+
throw new Error('Invalid params: must be an object with ticker (string), side ("LONG" | "SHORT"), size (positive number), and leverage (>= 1)');
|
|
279
|
+
}
|
|
280
|
+
const { ticker, side, size, leverage } = params;
|
|
281
|
+
const result = await this.engine.performAction("open_perp", {
|
|
282
|
+
ticker,
|
|
283
|
+
side,
|
|
284
|
+
size,
|
|
285
|
+
leverage,
|
|
286
|
+
});
|
|
287
|
+
if (!result.success) {
|
|
288
|
+
throw new Error(result.error || "Failed to open position");
|
|
289
|
+
}
|
|
290
|
+
const { positionId } = result.result;
|
|
291
|
+
const state = this.engine.getGameState();
|
|
292
|
+
const market = state.perpetualMarkets.find((m) => m.ticker === ticker);
|
|
293
|
+
return {
|
|
294
|
+
positionId,
|
|
295
|
+
entryPrice: market?.price || 0,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Type guard for ClosePositionParams
|
|
300
|
+
*/
|
|
301
|
+
isClosePositionParams(params) {
|
|
302
|
+
return (typeof params === "object" &&
|
|
303
|
+
params !== null &&
|
|
304
|
+
"positionId" in params &&
|
|
305
|
+
typeof params.positionId === "string" &&
|
|
306
|
+
params.positionId.length > 0);
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Close perpetual position
|
|
310
|
+
*
|
|
311
|
+
* Executes a close position action through the simulation engine.
|
|
312
|
+
*
|
|
313
|
+
* @param params - Close position parameters
|
|
314
|
+
* @returns Object with P&L and exit price
|
|
315
|
+
* @throws Error if close action fails
|
|
316
|
+
*/
|
|
317
|
+
async handleClosePosition(params) {
|
|
318
|
+
if (!params || !this.isClosePositionParams(params)) {
|
|
319
|
+
throw new Error("Invalid params: must be an object with positionId (non-empty string)");
|
|
320
|
+
}
|
|
321
|
+
const { positionId } = params;
|
|
322
|
+
const result = await this.engine.performAction("close_perp", {
|
|
323
|
+
positionId,
|
|
324
|
+
});
|
|
325
|
+
if (!result.success) {
|
|
326
|
+
throw new Error(result.error || "Failed to close position");
|
|
327
|
+
}
|
|
328
|
+
const { pnl } = result.result;
|
|
329
|
+
return {
|
|
330
|
+
pnl,
|
|
331
|
+
exitPrice: 0, // Simplified
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Get social feed
|
|
336
|
+
*
|
|
337
|
+
* Returns the last 20 posts from the simulation state.
|
|
338
|
+
*
|
|
339
|
+
* @param _params - Unused (kept for interface consistency)
|
|
340
|
+
* @returns Object containing array of feed posts
|
|
341
|
+
*/
|
|
342
|
+
handleGetFeed(_params) {
|
|
343
|
+
const state = this.engine.getGameState();
|
|
344
|
+
const posts = (state.posts || [])
|
|
345
|
+
.slice(-20) // Last 20 posts
|
|
346
|
+
.map((p) => ({
|
|
347
|
+
id: p.id,
|
|
348
|
+
authorId: p.authorId,
|
|
349
|
+
authorName: p.authorName,
|
|
350
|
+
content: p.content,
|
|
351
|
+
createdAt: p.createdAt,
|
|
352
|
+
likes: p.likes,
|
|
353
|
+
comments: p.comments,
|
|
354
|
+
marketId: p.marketId,
|
|
355
|
+
}));
|
|
356
|
+
return { posts };
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Type guard for CreatePostParams
|
|
360
|
+
*/
|
|
361
|
+
isCreatePostParams(params) {
|
|
362
|
+
return (typeof params === "object" &&
|
|
363
|
+
params !== null &&
|
|
364
|
+
"content" in params &&
|
|
365
|
+
typeof params.content === "string" &&
|
|
366
|
+
params.content.trim().length > 0 &&
|
|
367
|
+
("marketId" in params
|
|
368
|
+
? typeof params.marketId === "string" &&
|
|
369
|
+
params.marketId.trim().length > 0
|
|
370
|
+
: true));
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Create post
|
|
374
|
+
*
|
|
375
|
+
* Executes a create post action through the simulation engine.
|
|
376
|
+
*
|
|
377
|
+
* @param params - Create post parameters
|
|
378
|
+
* @returns Object with created post ID
|
|
379
|
+
* @throws Error if create action fails
|
|
380
|
+
*/
|
|
381
|
+
async handleCreatePost(params) {
|
|
382
|
+
if (!params || !this.isCreatePostParams(params)) {
|
|
383
|
+
throw new Error("Invalid params: must be an object with content (non-empty string) and optional marketId (non-empty string)");
|
|
384
|
+
}
|
|
385
|
+
const { content, marketId } = params;
|
|
386
|
+
const result = await this.engine.performAction("create_post", {
|
|
387
|
+
content,
|
|
388
|
+
marketId: marketId ?? null,
|
|
389
|
+
});
|
|
390
|
+
if (!result.success) {
|
|
391
|
+
throw new Error(result.error || "Failed to create post");
|
|
392
|
+
}
|
|
393
|
+
const { postId } = result.result;
|
|
394
|
+
return { postId };
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Get group chats
|
|
398
|
+
*
|
|
399
|
+
* Returns all group chats from the simulation state.
|
|
400
|
+
*
|
|
401
|
+
* @param _params - Unused (kept for interface consistency)
|
|
402
|
+
* @returns Object containing array of group chats
|
|
403
|
+
*/
|
|
404
|
+
handleGetChats(_params) {
|
|
405
|
+
const state = this.engine.getGameState();
|
|
406
|
+
const chats = (state.groupChats || []).map((g) => ({
|
|
407
|
+
id: g.id,
|
|
408
|
+
name: g.name,
|
|
409
|
+
memberCount: g.memberIds.length,
|
|
410
|
+
messageCount: g.messageCount,
|
|
411
|
+
lastActivity: g.lastActivity,
|
|
412
|
+
invited: g.invitedAgent ?? false,
|
|
413
|
+
messages: g.messages ?? [],
|
|
414
|
+
}));
|
|
415
|
+
return { chats };
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Type guard for JoinGroupParams
|
|
419
|
+
*/
|
|
420
|
+
isJoinGroupParams(params) {
|
|
421
|
+
return (typeof params === "object" &&
|
|
422
|
+
params !== null &&
|
|
423
|
+
"groupId" in params &&
|
|
424
|
+
typeof params.groupId === "string" &&
|
|
425
|
+
params.groupId.length > 0);
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Join group chat
|
|
429
|
+
*
|
|
430
|
+
* Executes a join group action through the simulation engine.
|
|
431
|
+
*
|
|
432
|
+
* @param params - Join group parameters
|
|
433
|
+
* @returns Object indicating success status
|
|
434
|
+
*/
|
|
435
|
+
async handleJoinGroup(params) {
|
|
436
|
+
if (!params || !this.isJoinGroupParams(params)) {
|
|
437
|
+
throw new Error("Invalid params: must be an object with groupId (non-empty string)");
|
|
438
|
+
}
|
|
439
|
+
const { groupId } = params;
|
|
440
|
+
const result = await this.engine.performAction("join_group", {
|
|
441
|
+
groupId,
|
|
442
|
+
});
|
|
443
|
+
return { success: result.success };
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Get agent balance
|
|
447
|
+
*
|
|
448
|
+
* Returns the agent's current balance.
|
|
449
|
+
*
|
|
450
|
+
* @param _params - Unused (kept for interface consistency)
|
|
451
|
+
* @returns Object with balance amount
|
|
452
|
+
*
|
|
453
|
+
* @remarks
|
|
454
|
+
* Currently returns a fixed balance. Can be enhanced to track actual balance.
|
|
455
|
+
*/
|
|
456
|
+
handleGetBalance(_params) {
|
|
457
|
+
// Simplified: return fixed balance
|
|
458
|
+
return { balance: 10000 };
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Get portfolio (balance, positions, P&L)
|
|
462
|
+
*
|
|
463
|
+
* Returns comprehensive portfolio information including balance, positions, and P&L.
|
|
464
|
+
*
|
|
465
|
+
* @param _params - Unused (kept for interface consistency)
|
|
466
|
+
* @returns Object with balance, positions array, and total P&L
|
|
467
|
+
*/
|
|
468
|
+
handleGetPortfolio(_params) {
|
|
469
|
+
const state = this.engine.getGameState();
|
|
470
|
+
const agent = state.agents.find((a) => a.id === this.agentId);
|
|
471
|
+
// Calculate positions from agent's state
|
|
472
|
+
const positions = [];
|
|
473
|
+
// Calculate P&L from agent's totalPnl
|
|
474
|
+
const pnl = agent?.totalPnl || 0;
|
|
475
|
+
const balance = 10000 + pnl; // Starting balance + P&L
|
|
476
|
+
return {
|
|
477
|
+
balance,
|
|
478
|
+
positions,
|
|
479
|
+
pnl,
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Get positions (prediction market + perp positions)
|
|
484
|
+
*
|
|
485
|
+
* Returns all active positions for the agent.
|
|
486
|
+
*
|
|
487
|
+
* @param _params - Unused (kept for interface consistency)
|
|
488
|
+
* @returns Object with prediction and perpetual position arrays
|
|
489
|
+
*
|
|
490
|
+
* @remarks
|
|
491
|
+
* Currently returns empty arrays. Can be enhanced to track actual positions.
|
|
492
|
+
*/
|
|
493
|
+
handleGetPositions(_params) {
|
|
494
|
+
// Return empty arrays for simulation
|
|
495
|
+
// In a real benchmark, we'd track actual positions made by the agent
|
|
496
|
+
return {
|
|
497
|
+
predictionPositions: [],
|
|
498
|
+
perpPositions: [],
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Get dashboard data (balance, recent activity, etc)
|
|
503
|
+
*
|
|
504
|
+
* Returns comprehensive dashboard information for the agent.
|
|
505
|
+
*
|
|
506
|
+
* @param _params - Unused (kept for interface consistency)
|
|
507
|
+
* @returns Object with balance, reputation, total P&L, and active positions count
|
|
508
|
+
*/
|
|
509
|
+
handleGetDashboard(_params) {
|
|
510
|
+
const state = this.engine.getGameState();
|
|
511
|
+
const agent = state.agents.find((a) => a.id === this.agentId);
|
|
512
|
+
const pnl = agent?.totalPnl || 0;
|
|
513
|
+
const balance = 10000 + pnl;
|
|
514
|
+
return {
|
|
515
|
+
balance,
|
|
516
|
+
reputation: 1000,
|
|
517
|
+
totalPnl: pnl,
|
|
518
|
+
activePositions: 0,
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Get trending tags
|
|
523
|
+
*
|
|
524
|
+
* Returns trending topic tags with counts and trend directions.
|
|
525
|
+
*
|
|
526
|
+
* @param _params - Unused (kept for interface consistency)
|
|
527
|
+
* @returns Object with array of trending tags
|
|
528
|
+
*
|
|
529
|
+
* @remarks
|
|
530
|
+
* Currently returns dummy data. Can be enhanced to track actual trends.
|
|
531
|
+
*/
|
|
532
|
+
handleGetTrendingTags(_params) {
|
|
533
|
+
// Return some dummy trending tags for simulation
|
|
534
|
+
return {
|
|
535
|
+
tags: [
|
|
536
|
+
{ tag: "crypto", count: 150, trend: "up" },
|
|
537
|
+
{ tag: "ai", count: 120, trend: "up" },
|
|
538
|
+
{ tag: "markets", count: 90, trend: "stable" },
|
|
539
|
+
],
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Check if connected (always true for simulation)
|
|
544
|
+
*
|
|
545
|
+
* @returns Always true for simulation interface
|
|
546
|
+
*/
|
|
547
|
+
isConnected() {
|
|
548
|
+
return true;
|
|
549
|
+
}
|
|
550
|
+
// ===== Wrapper methods for A2A client parity =====
|
|
551
|
+
/**
|
|
552
|
+
* Buy shares in prediction market
|
|
553
|
+
*
|
|
554
|
+
* Convenience wrapper for buyShares A2A method.
|
|
555
|
+
*
|
|
556
|
+
* @param marketId - Market ID to buy shares in
|
|
557
|
+
* @param outcome - Outcome to buy (YES or NO)
|
|
558
|
+
* @param amount - Amount to invest
|
|
559
|
+
* @returns Result object with shares, avgPrice, and positionId
|
|
560
|
+
*/
|
|
561
|
+
async buyShares(marketId, outcome, amount) {
|
|
562
|
+
return (await this.sendRequest("a2a.buyShares", {
|
|
563
|
+
marketId,
|
|
564
|
+
outcome,
|
|
565
|
+
amount,
|
|
566
|
+
}));
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Sell shares from prediction market
|
|
570
|
+
*
|
|
571
|
+
* Convenience wrapper for sellShares A2A method.
|
|
572
|
+
*
|
|
573
|
+
* @param marketId - Market ID to sell shares from
|
|
574
|
+
* @param shares - Number of shares to sell
|
|
575
|
+
* @returns Result object with proceeds
|
|
576
|
+
*/
|
|
577
|
+
async sellShares(marketId, shares) {
|
|
578
|
+
return (await this.sendRequest("a2a.sellShares", {
|
|
579
|
+
marketId,
|
|
580
|
+
shares,
|
|
581
|
+
}));
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Open perp position
|
|
585
|
+
*
|
|
586
|
+
* Convenience wrapper for openPosition A2A method.
|
|
587
|
+
*
|
|
588
|
+
* @param ticker - Ticker symbol
|
|
589
|
+
* @param side - Position side (long or short)
|
|
590
|
+
* @param size - Position size
|
|
591
|
+
* @param leverage - Leverage multiplier
|
|
592
|
+
* @returns Result object with positionId and entryPrice
|
|
593
|
+
*/
|
|
594
|
+
async openPosition(ticker, side, size, leverage) {
|
|
595
|
+
return (await this.sendRequest("a2a.openPosition", {
|
|
596
|
+
ticker,
|
|
597
|
+
side: side.toUpperCase(),
|
|
598
|
+
size,
|
|
599
|
+
leverage,
|
|
600
|
+
}));
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Close perp position
|
|
604
|
+
*
|
|
605
|
+
* Convenience wrapper for closePosition A2A method.
|
|
606
|
+
*
|
|
607
|
+
* @param positionId - Position ID to close
|
|
608
|
+
* @returns Result object with pnl and exitPrice
|
|
609
|
+
*/
|
|
610
|
+
async closePosition(positionId) {
|
|
611
|
+
return (await this.sendRequest("a2a.closePosition", {
|
|
612
|
+
positionId,
|
|
613
|
+
}));
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Create post
|
|
617
|
+
*
|
|
618
|
+
* Convenience wrapper for createPost A2A method.
|
|
619
|
+
*
|
|
620
|
+
* @param content - Post content
|
|
621
|
+
* @param type - Post type (defaults to 'post')
|
|
622
|
+
* @returns Result object with postId
|
|
623
|
+
*/
|
|
624
|
+
async createPost(content, type = "post") {
|
|
625
|
+
return (await this.sendRequest("a2a.createPost", {
|
|
626
|
+
content,
|
|
627
|
+
marketId: type === "market" ? undefined : undefined,
|
|
628
|
+
}));
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Create comment
|
|
632
|
+
*
|
|
633
|
+
* Convenience wrapper for createComment A2A method.
|
|
634
|
+
*
|
|
635
|
+
* @param postId - Post ID to comment on
|
|
636
|
+
* @param content - Comment content
|
|
637
|
+
* @returns Result object with commentId
|
|
638
|
+
*/
|
|
639
|
+
async createComment(postId, content) {
|
|
640
|
+
return (await this.sendRequest("a2a.createComment", {
|
|
641
|
+
content,
|
|
642
|
+
marketId: postId,
|
|
643
|
+
}));
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Get portfolio (balance, positions, P&L)
|
|
647
|
+
*
|
|
648
|
+
* Convenience wrapper for getPortfolio A2A method.
|
|
649
|
+
*
|
|
650
|
+
* @returns Portfolio object with balance, positions, and P&L
|
|
651
|
+
*/
|
|
652
|
+
async getPortfolio() {
|
|
653
|
+
return (await this.sendRequest("a2a.getPortfolio"));
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* Get markets
|
|
657
|
+
*
|
|
658
|
+
* Returns both prediction markets and perpetual markets.
|
|
659
|
+
*
|
|
660
|
+
* @returns Object with predictions and perps arrays
|
|
661
|
+
*/
|
|
662
|
+
async getMarkets() {
|
|
663
|
+
const predictions = (await this.sendRequest("a2a.getPredictions", {
|
|
664
|
+
status: "active",
|
|
665
|
+
}));
|
|
666
|
+
const perpetuals = (await this.sendRequest("a2a.getPerpetuals", {}));
|
|
667
|
+
return {
|
|
668
|
+
predictions: predictions.predictions || [],
|
|
669
|
+
perps: perpetuals.perpetuals || [],
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Get feed
|
|
674
|
+
*
|
|
675
|
+
* Convenience wrapper for getFeed A2A method.
|
|
676
|
+
*
|
|
677
|
+
* @param limit - Maximum number of posts to return (default: 20)
|
|
678
|
+
* @returns Object with posts array
|
|
679
|
+
*/
|
|
680
|
+
async getFeed(limit = 20) {
|
|
681
|
+
return (await this.sendRequest("a2a.getFeed", { limit, offset: 0 }));
|
|
682
|
+
}
|
|
683
|
+
}
|