@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.
Files changed (94) hide show
  1. package/.turbo/turbo-lint.log +2 -0
  2. package/.turbo/turbo-typecheck.log +1 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/adapter.js +59 -0
  5. package/dist/archetypes/ArchetypeConfigService.js +510 -0
  6. package/dist/archetypes/derive-archetype.js +196 -0
  7. package/dist/archetypes/index.js +7 -0
  8. package/dist/benchmark/ArchetypeMatchupBenchmark.js +547 -0
  9. package/dist/benchmark/BenchmarkChartGenerator.js +632 -0
  10. package/dist/benchmark/BenchmarkDataGenerator.js +825 -0
  11. package/dist/benchmark/BenchmarkDataViewer.js +197 -0
  12. package/dist/benchmark/BenchmarkHistoryService.js +135 -0
  13. package/dist/benchmark/BenchmarkRunner.js +483 -0
  14. package/dist/benchmark/BenchmarkValidator.js +158 -0
  15. package/dist/benchmark/FastEvalRunner.js +133 -0
  16. package/dist/benchmark/MetricsValidator.js +104 -0
  17. package/dist/benchmark/MetricsVisualizer.js +775 -0
  18. package/dist/benchmark/ModelBenchmarkService.js +433 -0
  19. package/dist/benchmark/ModelRegistry.js +122 -0
  20. package/dist/benchmark/RulerBenchmarkIntegration.js +168 -0
  21. package/dist/benchmark/SimulationA2AInterface.js +683 -0
  22. package/dist/benchmark/SimulationEngine.js +522 -0
  23. package/dist/benchmark/TaskRunner.js +60 -0
  24. package/dist/benchmark/__tests__/BenchmarkRunner.test.js +409 -0
  25. package/dist/benchmark/__tests__/HeadToHead.test.js +105 -0
  26. package/dist/benchmark/index.js +23 -0
  27. package/dist/benchmark/parseSimulationMetrics.js +86 -0
  28. package/dist/benchmark/simulation-types.js +1 -0
  29. package/dist/dependencies.js +197 -0
  30. package/dist/generation/TrajectoryGenerator.js +244 -0
  31. package/dist/generation/index.js +6 -0
  32. package/dist/huggingface/HuggingFaceDatasetUploader.js +463 -0
  33. package/dist/huggingface/HuggingFaceIntegrationService.js +272 -0
  34. package/dist/huggingface/HuggingFaceModelUploader.js +385 -0
  35. package/dist/huggingface/index.js +9 -0
  36. package/dist/huggingface/shared/HuggingFaceUploadUtil.js +144 -0
  37. package/dist/index.js +41 -0
  38. package/dist/init-training.js +43 -0
  39. package/dist/metrics/TrajectoryMetricsExtractor.js +523 -0
  40. package/dist/metrics/__tests__/TrajectoryMetricsExtractor.test.js +628 -0
  41. package/dist/metrics/index.js +7 -0
  42. package/dist/metrics/types.js +21 -0
  43. package/dist/rubrics/__tests__/index.test.js +150 -0
  44. package/dist/rubrics/ass-kisser.js +83 -0
  45. package/dist/rubrics/degen.js +78 -0
  46. package/dist/rubrics/goody-twoshoes.js +82 -0
  47. package/dist/rubrics/index.js +184 -0
  48. package/dist/rubrics/information-trader.js +82 -0
  49. package/dist/rubrics/infosec.js +99 -0
  50. package/dist/rubrics/liar.js +102 -0
  51. package/dist/rubrics/perps-trader.js +85 -0
  52. package/dist/rubrics/researcher.js +79 -0
  53. package/dist/rubrics/scammer.js +80 -0
  54. package/dist/rubrics/social-butterfly.js +71 -0
  55. package/dist/rubrics/super-predictor.js +95 -0
  56. package/dist/rubrics/trader.js +65 -0
  57. package/dist/scoring/ArchetypeScoringService.js +301 -0
  58. package/dist/scoring/JudgePromptBuilder.js +401 -0
  59. package/dist/scoring/LLMJudgeCache.js +263 -0
  60. package/dist/scoring/index.js +8 -0
  61. package/dist/training/AutomationPipeline.js +714 -0
  62. package/dist/training/BenchmarkService.js +370 -0
  63. package/dist/training/ConfigValidator.js +153 -0
  64. package/dist/training/MarketOutcomesTracker.js +142 -0
  65. package/dist/training/ModelDeployer.js +128 -0
  66. package/dist/training/ModelFetcher.js +48 -0
  67. package/dist/training/ModelSelectionService.js +248 -0
  68. package/dist/training/ModelUsageVerifier.js +106 -0
  69. package/dist/training/MultiModelOrchestrator.js +349 -0
  70. package/dist/training/RLModelConfig.js +295 -0
  71. package/dist/training/RewardBackpropagationService.js +117 -0
  72. package/dist/training/RulerScoringService.js +450 -0
  73. package/dist/training/TrainingMonitor.js +108 -0
  74. package/dist/training/TrajectoryRecorder.js +281 -0
  75. package/dist/training/__tests__/TrajectoryRecorder.test.js +363 -0
  76. package/dist/training/index.js +30 -0
  77. package/dist/training/logRLConfig.js +29 -0
  78. package/dist/training/pipeline.js +80 -0
  79. package/dist/training/storage/ModelStorageService.js +190 -0
  80. package/dist/training/storage/TrainingDataArchiver.js +136 -0
  81. package/dist/training/storage/index.js +7 -0
  82. package/dist/training/types.js +6 -0
  83. package/dist/training/window-utils.js +100 -0
  84. package/dist/utils/index.js +73 -0
  85. package/dist/utils/logger.js +55 -0
  86. package/dist/utils/snowflake.js +15 -0
  87. package/dist/utils/synthetic-detector.js +67 -0
  88. package/package.json +2 -2
  89. package/research-output/training-runs/training-run-1773742857616.json +38 -0
  90. package/research-output/training-runs/training-run-1773742946977.json +38 -0
  91. package/research-output/training-runs/training-run-1773743278891.json +38 -0
  92. package/research-output/training-runs/training-run-1773743409754.json +38 -0
  93. package/research-output/training-runs/training-run-1773743651086.json +38 -0
  94. 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
+ }