@bike4mind/cli 0.2.80 → 0.2.81-feat-chess-agent-v2.22501

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.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { $ as RegInviteEvents, A as ImageGenerationUsageTransaction, B as OpenAIEmbeddingModel, C as FileEvents, Ct as getViewById, D as GenericCreditAddTransaction, E as GenerateImageToolCallSchema, Et as sanitizeTelemetryError, F as KnowledgeType, G as ProjectEvents, H as Permission, I as LLMEvents, J as QuestMasterParamsSchema, K as PromptMetaZodSchema, L as MiscEvents, M as InboxEvents, N as InviteEvents, O as GenericCreditDeductTransaction, P as InviteType, Q as RechartsChartTypeList, R as ModalEvents, S as FeedbackEvents, St as getMcpProviderMetadata, T as GEMINI_IMAGE_MODELS, Tt as resolveNavigationIntents, U as PermissionDeniedError, V as OpenAIImageGenerationInput, W as ProfileEvents, X as RealtimeVoiceUsageTransaction, Y as REASONING_SUPPORTED_MODELS, Z as ReceivedCreditTransaction, _ as CompletionApiUsageTransaction, _t as VoyageAIEmbeddingModel, a as ApiKeyEvents, at as SpeechToTextModels, b as FIXED_TEMPERATURE_MODELS, bt as getAccessibleDataLakes, c as AppFileEvents, ct as TagType, d as BFL_IMAGE_MODELS, dt as ToolUsageTransaction, et as ResearchModeParamsSchema, f as BFL_SAFETY_TOLERANCE, ft as TransferCreditTransaction, g as ChatModels, gt as VideoModels, h as ChatCompletionCreateInputSchema, ht as VideoGenerationUsageTransaction, i as AiEvents, it as SessionEvents, j as ImageModels, k as ImageEditUsageTransaction, kt as CollectionType, l as ArtifactTypeSchema, lt as TaskScheduleHandler, mt as VIDEO_SIZE_CONSTRAINTS, n as logger, nt as ResearchTaskPeriodicFrequencyType, o as ApiKeyScope, ot as SubscriptionCreditTransaction, p as BedrockEmbeddingModel, pt as UiNavigationEvents, q as PurchaseTransaction, r as ALERT_THRESHOLDS, rt as ResearchTaskType, s as ApiKeyType, st as SupportedFabFileMimeTypes, t as ConfigStore, tt as ResearchTaskExecutionType, u as AuthEvents, ut as TextGenerationUsageTransaction, v as DashboardParamsSchema, vt as XAI_IMAGE_MODELS, w as FriendshipEvents, wt as isGPTImageModel, x as FavoriteDocumentType, xt as getDataLakeTags, y as ElabsEvents, yt as b4mLLMTools, z as ModelBackend } from "./ConfigStore-CG7DYbjy.mjs";
2
+ import { $ as RegInviteEvents, A as ImageGenerationUsageTransaction, B as OpenAIEmbeddingModel, C as FileEvents, Ct as getViewById, D as GenericCreditAddTransaction, E as GenerateImageToolCallSchema, Et as sanitizeTelemetryError, F as KnowledgeType, G as ProjectEvents, H as Permission, I as LLMEvents, J as QuestMasterParamsSchema, K as PromptMetaZodSchema, L as MiscEvents, M as InboxEvents, N as InviteEvents, O as GenericCreditDeductTransaction, P as InviteType, Q as RechartsChartTypeList, R as ModalEvents, S as FeedbackEvents, St as getMcpProviderMetadata, T as GEMINI_IMAGE_MODELS, Tt as resolveNavigationIntents, U as PermissionDeniedError, V as OpenAIImageGenerationInput, W as ProfileEvents, X as RealtimeVoiceUsageTransaction, Y as REASONING_SUPPORTED_MODELS, Z as ReceivedCreditTransaction, _ as CompletionApiUsageTransaction, _t as VoyageAIEmbeddingModel, a as ApiKeyEvents, at as SpeechToTextModels, b as FIXED_TEMPERATURE_MODELS, bt as getAccessibleDataLakes, c as AppFileEvents, ct as TagType, d as BFL_IMAGE_MODELS, dt as ToolUsageTransaction, et as ResearchModeParamsSchema, f as BFL_SAFETY_TOLERANCE, ft as TransferCreditTransaction, g as ChatModels, gt as VideoModels, h as ChatCompletionCreateInputSchema, ht as VideoGenerationUsageTransaction, i as AiEvents, it as SessionEvents, j as ImageModels, k as ImageEditUsageTransaction, kt as CollectionType, l as ArtifactTypeSchema, lt as TaskScheduleHandler, mt as VIDEO_SIZE_CONSTRAINTS, n as logger, nt as ResearchTaskPeriodicFrequencyType, o as ApiKeyScope, ot as SubscriptionCreditTransaction, p as BedrockEmbeddingModel, pt as UiNavigationEvents, q as PurchaseTransaction, r as ALERT_THRESHOLDS, rt as ResearchTaskType, s as ApiKeyType, st as SupportedFabFileMimeTypes, t as ConfigStore, tt as ResearchTaskExecutionType, u as AuthEvents, ut as TextGenerationUsageTransaction, v as DashboardParamsSchema, vt as XAI_IMAGE_MODELS, w as FriendshipEvents, wt as isGPTImageModel, x as FavoriteDocumentType, xt as getDataLakeTags, y as ElabsEvents, yt as b4mLLMTools, z as ModelBackend } from "./ConfigStore-DJmY-Fv4.mjs";
3
3
  import { n as isPathAllowed, t as assertPathAllowed } from "./pathValidation-CIytuhr3-Dt5dntLx.mjs";
4
4
  import { execFile, execFileSync, spawn } from "child_process";
5
5
  import { createHash, randomBytes } from "crypto";
@@ -55,6 +55,7 @@ import sum from "lodash/sum.js";
55
55
  import times from "lodash/times.js";
56
56
  import { all, create } from "mathjs";
57
57
  import ExcelJS from "exceljs";
58
+ import { Chess } from "chess.js";
58
59
  import "speakeasy";
59
60
  import "qrcode";
60
61
  import "lodash/throttle.js";
@@ -8298,7 +8299,7 @@ No markdown, no explanation, no code blocks — just the raw JSON object.`;
8298
8299
  "Minimize: sum(error^2)"
8299
8300
  ].join("\n");
8300
8301
  //#endregion
8301
- //#region ../../b4m-core/services/dist/tools-ZP0eeJoJ.mjs
8302
+ //#region ../../b4m-core/services/dist/tools-M5WOOsBu.mjs
8302
8303
  async function performDeepResearch(context, params, config) {
8303
8304
  const maxDepth = config.maxDepth || 7;
8304
8305
  const duration = config.duration || 4.5;
@@ -13174,6 +13175,842 @@ async function executeFmpAction(adapters, params) {
13174
13175
  default: return `Unknown action "${action}". Valid actions: quote, search, profile, history, income_statement, balance_sheet.`;
13175
13176
  }
13176
13177
  }
13178
+ const fmpTool = {
13179
+ name: "fmp_financial_data",
13180
+ implementation: (context) => ({
13181
+ toolFn: async (value) => {
13182
+ const params = value;
13183
+ return executeFmpAction({ db: context.db }, params);
13184
+ },
13185
+ toolSchema: {
13186
+ name: "fmp_financial_data",
13187
+ description: `Query Financial Modeling Prep for real-time stock market and financial data.
13188
+
13189
+ USE FOR:
13190
+ - Stock quotes: Current price, change, volume, market cap, P/E ratio (action=quote)
13191
+ - Ticker search: Find stock symbols by company name (action=search)
13192
+ - Company profiles: Industry, sector, CEO, description, employees (action=profile)
13193
+ - Price history: Daily OHLCV data for charting and analysis (action=history)
13194
+ - Income statements: Revenue, net income, EPS — annual or quarterly (action=income_statement)
13195
+ - Balance sheets: Assets, liabilities, equity — annual or quarterly (action=balance_sheet)
13196
+
13197
+ DO NOT USE FOR:
13198
+ - Cryptocurrency prices (FMP focuses on equities)
13199
+ - Real-time intraday tick data
13200
+ - Options or futures data
13201
+ - General financial advice or predictions`,
13202
+ parameters: {
13203
+ type: "object",
13204
+ properties: {
13205
+ action: {
13206
+ type: "string",
13207
+ enum: [
13208
+ "quote",
13209
+ "search",
13210
+ "profile",
13211
+ "history",
13212
+ "income_statement",
13213
+ "balance_sheet"
13214
+ ],
13215
+ description: "The type of financial data to retrieve"
13216
+ },
13217
+ symbol: {
13218
+ type: "string",
13219
+ description: "Stock ticker symbol (e.g., AAPL, MSFT, GOOGL). Required for all actions except search."
13220
+ },
13221
+ query: {
13222
+ type: "string",
13223
+ description: "Search query to find stock tickers by company name. Required for action=search."
13224
+ },
13225
+ from: {
13226
+ type: "string",
13227
+ description: "Start date in YYYY-MM-DD format (for action=history). Defaults to 1 year ago."
13228
+ },
13229
+ to: {
13230
+ type: "string",
13231
+ description: "End date in YYYY-MM-DD format (for action=history). Defaults to today."
13232
+ },
13233
+ period: {
13234
+ type: "string",
13235
+ enum: ["annual", "quarter"],
13236
+ description: "Reporting period for financial statements. Defaults to annual."
13237
+ }
13238
+ },
13239
+ required: ["action"]
13240
+ }
13241
+ }
13242
+ })
13243
+ };
13244
+ const PIECE_VALUES = {
13245
+ p: 100,
13246
+ n: 320,
13247
+ b: 330,
13248
+ r: 500,
13249
+ q: 900,
13250
+ k: 0
13251
+ };
13252
+ const PIECE_SQUARE_TABLES = {
13253
+ p: [
13254
+ 0,
13255
+ 0,
13256
+ 0,
13257
+ 0,
13258
+ 0,
13259
+ 0,
13260
+ 0,
13261
+ 0,
13262
+ 50,
13263
+ 50,
13264
+ 50,
13265
+ 50,
13266
+ 50,
13267
+ 50,
13268
+ 50,
13269
+ 50,
13270
+ 10,
13271
+ 10,
13272
+ 20,
13273
+ 30,
13274
+ 30,
13275
+ 20,
13276
+ 10,
13277
+ 10,
13278
+ 5,
13279
+ 5,
13280
+ 10,
13281
+ 25,
13282
+ 25,
13283
+ 10,
13284
+ 5,
13285
+ 5,
13286
+ 0,
13287
+ 0,
13288
+ 0,
13289
+ 20,
13290
+ 20,
13291
+ 0,
13292
+ 0,
13293
+ 0,
13294
+ 5,
13295
+ -5,
13296
+ -10,
13297
+ 0,
13298
+ 0,
13299
+ -10,
13300
+ -5,
13301
+ 5,
13302
+ 5,
13303
+ 10,
13304
+ 10,
13305
+ -20,
13306
+ -20,
13307
+ 10,
13308
+ 10,
13309
+ 5,
13310
+ 0,
13311
+ 0,
13312
+ 0,
13313
+ 0,
13314
+ 0,
13315
+ 0,
13316
+ 0,
13317
+ 0
13318
+ ],
13319
+ n: [
13320
+ -50,
13321
+ -40,
13322
+ -30,
13323
+ -30,
13324
+ -30,
13325
+ -30,
13326
+ -40,
13327
+ -50,
13328
+ -40,
13329
+ -20,
13330
+ 0,
13331
+ 0,
13332
+ 0,
13333
+ 0,
13334
+ -20,
13335
+ -40,
13336
+ -30,
13337
+ 0,
13338
+ 10,
13339
+ 15,
13340
+ 15,
13341
+ 10,
13342
+ 0,
13343
+ -30,
13344
+ -30,
13345
+ 5,
13346
+ 15,
13347
+ 20,
13348
+ 20,
13349
+ 15,
13350
+ 5,
13351
+ -30,
13352
+ -30,
13353
+ 0,
13354
+ 15,
13355
+ 20,
13356
+ 20,
13357
+ 15,
13358
+ 0,
13359
+ -30,
13360
+ -30,
13361
+ 5,
13362
+ 10,
13363
+ 15,
13364
+ 15,
13365
+ 10,
13366
+ 5,
13367
+ -30,
13368
+ -40,
13369
+ -20,
13370
+ 0,
13371
+ 5,
13372
+ 5,
13373
+ 0,
13374
+ -20,
13375
+ -40,
13376
+ -50,
13377
+ -40,
13378
+ -30,
13379
+ -30,
13380
+ -30,
13381
+ -30,
13382
+ -40,
13383
+ -50
13384
+ ],
13385
+ b: [
13386
+ -20,
13387
+ -10,
13388
+ -10,
13389
+ -10,
13390
+ -10,
13391
+ -10,
13392
+ -10,
13393
+ -20,
13394
+ -10,
13395
+ 0,
13396
+ 0,
13397
+ 0,
13398
+ 0,
13399
+ 0,
13400
+ 0,
13401
+ -10,
13402
+ -10,
13403
+ 0,
13404
+ 5,
13405
+ 10,
13406
+ 10,
13407
+ 5,
13408
+ 0,
13409
+ -10,
13410
+ -10,
13411
+ 5,
13412
+ 5,
13413
+ 10,
13414
+ 10,
13415
+ 5,
13416
+ 5,
13417
+ -10,
13418
+ -10,
13419
+ 0,
13420
+ 10,
13421
+ 10,
13422
+ 10,
13423
+ 10,
13424
+ 0,
13425
+ -10,
13426
+ -10,
13427
+ 10,
13428
+ 10,
13429
+ 10,
13430
+ 10,
13431
+ 10,
13432
+ 10,
13433
+ -10,
13434
+ -10,
13435
+ 5,
13436
+ 0,
13437
+ 0,
13438
+ 0,
13439
+ 0,
13440
+ 5,
13441
+ -10,
13442
+ -20,
13443
+ -10,
13444
+ -10,
13445
+ -10,
13446
+ -10,
13447
+ -10,
13448
+ -10,
13449
+ -20
13450
+ ],
13451
+ r: [
13452
+ 0,
13453
+ 0,
13454
+ 0,
13455
+ 0,
13456
+ 0,
13457
+ 0,
13458
+ 0,
13459
+ 0,
13460
+ 5,
13461
+ 10,
13462
+ 10,
13463
+ 10,
13464
+ 10,
13465
+ 10,
13466
+ 10,
13467
+ 5,
13468
+ -5,
13469
+ 0,
13470
+ 0,
13471
+ 0,
13472
+ 0,
13473
+ 0,
13474
+ 0,
13475
+ -5,
13476
+ -5,
13477
+ 0,
13478
+ 0,
13479
+ 0,
13480
+ 0,
13481
+ 0,
13482
+ 0,
13483
+ -5,
13484
+ -5,
13485
+ 0,
13486
+ 0,
13487
+ 0,
13488
+ 0,
13489
+ 0,
13490
+ 0,
13491
+ -5,
13492
+ -5,
13493
+ 0,
13494
+ 0,
13495
+ 0,
13496
+ 0,
13497
+ 0,
13498
+ 0,
13499
+ -5,
13500
+ -5,
13501
+ 0,
13502
+ 0,
13503
+ 0,
13504
+ 0,
13505
+ 0,
13506
+ 0,
13507
+ -5,
13508
+ 0,
13509
+ 0,
13510
+ 0,
13511
+ 5,
13512
+ 5,
13513
+ 0,
13514
+ 0,
13515
+ 0
13516
+ ],
13517
+ q: [
13518
+ -20,
13519
+ -10,
13520
+ -10,
13521
+ -5,
13522
+ -5,
13523
+ -10,
13524
+ -10,
13525
+ -20,
13526
+ -10,
13527
+ 0,
13528
+ 0,
13529
+ 0,
13530
+ 0,
13531
+ 0,
13532
+ 0,
13533
+ -10,
13534
+ -10,
13535
+ 0,
13536
+ 5,
13537
+ 5,
13538
+ 5,
13539
+ 5,
13540
+ 0,
13541
+ -10,
13542
+ -5,
13543
+ 0,
13544
+ 5,
13545
+ 5,
13546
+ 5,
13547
+ 5,
13548
+ 0,
13549
+ -5,
13550
+ 0,
13551
+ 0,
13552
+ 5,
13553
+ 5,
13554
+ 5,
13555
+ 5,
13556
+ 0,
13557
+ -5,
13558
+ -10,
13559
+ 5,
13560
+ 5,
13561
+ 5,
13562
+ 5,
13563
+ 5,
13564
+ 0,
13565
+ -10,
13566
+ -10,
13567
+ 0,
13568
+ 5,
13569
+ 0,
13570
+ 0,
13571
+ 0,
13572
+ 0,
13573
+ -10,
13574
+ -20,
13575
+ -10,
13576
+ -10,
13577
+ -5,
13578
+ -5,
13579
+ -10,
13580
+ -10,
13581
+ -20
13582
+ ],
13583
+ k: [
13584
+ -30,
13585
+ -40,
13586
+ -40,
13587
+ -50,
13588
+ -50,
13589
+ -40,
13590
+ -40,
13591
+ -30,
13592
+ -30,
13593
+ -40,
13594
+ -40,
13595
+ -50,
13596
+ -50,
13597
+ -40,
13598
+ -40,
13599
+ -30,
13600
+ -30,
13601
+ -40,
13602
+ -40,
13603
+ -50,
13604
+ -50,
13605
+ -40,
13606
+ -40,
13607
+ -30,
13608
+ -30,
13609
+ -40,
13610
+ -40,
13611
+ -50,
13612
+ -50,
13613
+ -40,
13614
+ -40,
13615
+ -30,
13616
+ -20,
13617
+ -30,
13618
+ -30,
13619
+ -40,
13620
+ -40,
13621
+ -30,
13622
+ -30,
13623
+ -20,
13624
+ -10,
13625
+ -20,
13626
+ -20,
13627
+ -20,
13628
+ -20,
13629
+ -20,
13630
+ -20,
13631
+ -10,
13632
+ 20,
13633
+ 20,
13634
+ 0,
13635
+ 0,
13636
+ 0,
13637
+ 0,
13638
+ 20,
13639
+ 20,
13640
+ 20,
13641
+ 30,
13642
+ 10,
13643
+ 0,
13644
+ 0,
13645
+ 10,
13646
+ 30,
13647
+ 20
13648
+ ]
13649
+ };
13650
+ function evaluatePosition(game) {
13651
+ if (game.isCheckmate()) return game.turn() === "w" ? -99999 : 99999;
13652
+ if (game.isDraw() || game.isStalemate()) return 0;
13653
+ let score = 0;
13654
+ const board = game.board();
13655
+ for (let rank = 0; rank < 8; rank++) for (let file = 0; file < 8; file++) {
13656
+ const piece = board[rank][file];
13657
+ if (!piece) continue;
13658
+ const tableIndex = rank * 8 + file;
13659
+ const pstIndex = piece.color === "w" ? tableIndex : (7 - rank) * 8 + file;
13660
+ const positionalValue = (PIECE_SQUARE_TABLES[piece.type] || [])[pstIndex] || 0;
13661
+ const materialValue = PIECE_VALUES[piece.type] || 0;
13662
+ if (piece.color === "w") score += materialValue + positionalValue;
13663
+ else score -= materialValue + positionalValue;
13664
+ }
13665
+ return score;
13666
+ }
13667
+ function getMaterialCount(game) {
13668
+ const counts = {
13669
+ pawns: {
13670
+ w: 0,
13671
+ b: 0
13672
+ },
13673
+ knights: {
13674
+ w: 0,
13675
+ b: 0
13676
+ },
13677
+ bishops: {
13678
+ w: 0,
13679
+ b: 0
13680
+ },
13681
+ rooks: {
13682
+ w: 0,
13683
+ b: 0
13684
+ },
13685
+ queens: {
13686
+ w: 0,
13687
+ b: 0
13688
+ }
13689
+ };
13690
+ const board = game.board();
13691
+ for (const row of board) for (const piece of row) {
13692
+ if (!piece) continue;
13693
+ const color = piece.color;
13694
+ switch (piece.type) {
13695
+ case "p":
13696
+ counts.pawns[color]++;
13697
+ break;
13698
+ case "n":
13699
+ counts.knights[color]++;
13700
+ break;
13701
+ case "b":
13702
+ counts.bishops[color]++;
13703
+ break;
13704
+ case "r":
13705
+ counts.rooks[color]++;
13706
+ break;
13707
+ case "q":
13708
+ counts.queens[color]++;
13709
+ break;
13710
+ }
13711
+ }
13712
+ return counts;
13713
+ }
13714
+ function getSearchDepth(difficulty) {
13715
+ switch (difficulty) {
13716
+ case "beginner": return 2;
13717
+ case "intermediate": return 3;
13718
+ case "advanced": return 4;
13719
+ }
13720
+ }
13721
+ function orderMoves(game) {
13722
+ return game.moves({ verbose: true }).sort((a, b) => {
13723
+ let scoreA = 0;
13724
+ let scoreB = 0;
13725
+ if (a.captured) scoreA += PIECE_VALUES[a.captured] || 0;
13726
+ if (b.captured) scoreB += PIECE_VALUES[b.captured] || 0;
13727
+ if (a.to === "e4" || a.to === "d4" || a.to === "e5" || a.to === "d5") scoreA += 10;
13728
+ if (b.to === "e4" || b.to === "d4" || b.to === "e5" || b.to === "d5") scoreB += 10;
13729
+ return scoreB - scoreA;
13730
+ });
13731
+ }
13732
+ function minimax(game, depth, alpha, beta, isMaximizing) {
13733
+ if (depth === 0 || game.isGameOver()) return evaluatePosition(game);
13734
+ const moves = orderMoves(game);
13735
+ if (isMaximizing) {
13736
+ let maxEval = -Infinity;
13737
+ for (const move of moves) {
13738
+ game.move(move.san);
13739
+ const evalScore = minimax(game, depth - 1, alpha, beta, false);
13740
+ game.undo();
13741
+ maxEval = Math.max(maxEval, evalScore);
13742
+ alpha = Math.max(alpha, evalScore);
13743
+ if (beta <= alpha) break;
13744
+ }
13745
+ return maxEval;
13746
+ } else {
13747
+ let minEval = Infinity;
13748
+ for (const move of moves) {
13749
+ game.move(move.san);
13750
+ const evalScore = minimax(game, depth - 1, alpha, beta, true);
13751
+ game.undo();
13752
+ minEval = Math.min(minEval, evalScore);
13753
+ beta = Math.min(beta, evalScore);
13754
+ if (beta <= alpha) break;
13755
+ }
13756
+ return minEval;
13757
+ }
13758
+ }
13759
+ function findBestMove(game, difficulty) {
13760
+ const depth = getSearchDepth(difficulty);
13761
+ const isWhite = game.turn() === "w";
13762
+ const moves = orderMoves(game);
13763
+ if (moves.length === 0) return null;
13764
+ if (difficulty === "beginner") {
13765
+ const evaluated = moves.map((move) => {
13766
+ game.move(move.san);
13767
+ const score = minimax(game, depth - 1, -Infinity, Infinity, !isWhite);
13768
+ game.undo();
13769
+ return {
13770
+ move: move.san,
13771
+ score
13772
+ };
13773
+ });
13774
+ evaluated.sort((a, b) => isWhite ? b.score - a.score : a.score - b.score);
13775
+ const topN = Math.min(3, evaluated.length);
13776
+ if (Math.random() < .4 && topN > 1) return evaluated[Math.floor(Math.random() * topN)].move;
13777
+ return evaluated[0].move;
13778
+ }
13779
+ let bestMove = null;
13780
+ let bestEval = isWhite ? -Infinity : Infinity;
13781
+ for (const move of moves) {
13782
+ game.move(move.san);
13783
+ const evalScore = minimax(game, depth - 1, -Infinity, Infinity, !isWhite);
13784
+ game.undo();
13785
+ if (isWhite ? evalScore > bestEval : evalScore < bestEval) {
13786
+ bestEval = evalScore;
13787
+ bestMove = move.san;
13788
+ }
13789
+ }
13790
+ return bestMove;
13791
+ }
13792
+ function wrapWithArtifact(data) {
13793
+ const json = JSON.stringify(data);
13794
+ return `<artifact identifier="${`chess-${Date.now()}`}" type="application/vnd.ant.chess" title="Chess Game">\n${json}\n</artifact>`;
13795
+ }
13796
+ function handleNewGame() {
13797
+ const game = new Chess();
13798
+ return wrapWithArtifact({
13799
+ success: true,
13800
+ fen: game.fen(),
13801
+ turn: "w",
13802
+ legalMoves: game.moves(),
13803
+ message: "New game started. White to move."
13804
+ });
13805
+ }
13806
+ function handlePlayTurn(fen, moveStr, difficulty = "intermediate") {
13807
+ if (!fen) return JSON.stringify({
13808
+ success: false,
13809
+ error: "FEN string is required."
13810
+ });
13811
+ if (!moveStr) return JSON.stringify({
13812
+ success: false,
13813
+ error: "Move is required."
13814
+ });
13815
+ const game = new Chess(fen);
13816
+ let playerMove;
13817
+ try {
13818
+ playerMove = game.move(moveStr);
13819
+ } catch {
13820
+ return JSON.stringify({
13821
+ success: false,
13822
+ error: `Invalid move: "${moveStr}". Legal moves: ${game.moves().join(", ")}`,
13823
+ legalMoves: game.moves()
13824
+ });
13825
+ }
13826
+ if (game.isGameOver()) {
13827
+ const status = getGameStatusInfo(game);
13828
+ return wrapWithArtifact({
13829
+ success: true,
13830
+ fen: game.fen(),
13831
+ playerMove: {
13832
+ from: playerMove.from,
13833
+ to: playerMove.to,
13834
+ san: playerMove.san,
13835
+ piece: playerMove.piece,
13836
+ captured: playerMove.captured || null
13837
+ },
13838
+ aiMove: null,
13839
+ turn: game.turn(),
13840
+ legalMoves: [],
13841
+ ...status
13842
+ });
13843
+ }
13844
+ const bestMove = findBestMove(game, difficulty);
13845
+ if (!bestMove) {
13846
+ const status = getGameStatusInfo(game);
13847
+ return wrapWithArtifact({
13848
+ success: true,
13849
+ fen: game.fen(),
13850
+ playerMove: {
13851
+ from: playerMove.from,
13852
+ to: playerMove.to,
13853
+ san: playerMove.san,
13854
+ piece: playerMove.piece,
13855
+ captured: playerMove.captured || null
13856
+ },
13857
+ aiMove: null,
13858
+ turn: game.turn(),
13859
+ legalMoves: game.moves(),
13860
+ ...status
13861
+ });
13862
+ }
13863
+ const aiResult = game.move(bestMove);
13864
+ const status = getGameStatusInfo(game);
13865
+ return wrapWithArtifact({
13866
+ success: true,
13867
+ fen: game.fen(),
13868
+ move: {
13869
+ from: aiResult.from,
13870
+ to: aiResult.to,
13871
+ san: aiResult.san,
13872
+ piece: aiResult.piece,
13873
+ captured: aiResult.captured || null
13874
+ },
13875
+ playerMove: {
13876
+ from: playerMove.from,
13877
+ to: playerMove.to,
13878
+ san: playerMove.san,
13879
+ piece: playerMove.piece,
13880
+ captured: playerMove.captured || null
13881
+ },
13882
+ aiMove: {
13883
+ from: aiResult.from,
13884
+ to: aiResult.to,
13885
+ san: aiResult.san,
13886
+ piece: aiResult.piece,
13887
+ captured: aiResult.captured || null
13888
+ },
13889
+ turn: game.turn(),
13890
+ legalMoves: game.moves(),
13891
+ ...status,
13892
+ moveNumber: game.moveNumber()
13893
+ });
13894
+ }
13895
+ function handleGetLegalMoves(fen) {
13896
+ if (!fen) return JSON.stringify({
13897
+ success: false,
13898
+ error: "FEN string is required."
13899
+ });
13900
+ const game = new Chess(fen);
13901
+ const verbose = game.moves({ verbose: true });
13902
+ return JSON.stringify({
13903
+ success: true,
13904
+ fen,
13905
+ turn: game.turn(),
13906
+ moves: game.moves(),
13907
+ verboseMoves: verbose.map((m) => ({
13908
+ from: m.from,
13909
+ to: m.to,
13910
+ san: m.san,
13911
+ piece: m.piece,
13912
+ captured: m.captured || null
13913
+ })),
13914
+ count: verbose.length
13915
+ });
13916
+ }
13917
+ function handleEvaluatePosition(fen) {
13918
+ if (!fen) return JSON.stringify({
13919
+ success: false,
13920
+ error: "FEN string is required."
13921
+ });
13922
+ const game = new Chess(fen);
13923
+ const score = evaluatePosition(game);
13924
+ const material = getMaterialCount(game);
13925
+ const status = getGameStatusInfo(game);
13926
+ let advantage;
13927
+ const absScore = Math.abs(score);
13928
+ if (absScore < 50) advantage = "Equal position";
13929
+ else if (absScore < 150) advantage = `Slight ${score > 0 ? "white" : "black"} advantage`;
13930
+ else if (absScore < 300) advantage = `Clear ${score > 0 ? "white" : "black"} advantage`;
13931
+ else if (absScore < 900) advantage = `Winning ${score > 0 ? "white" : "black"} advantage`;
13932
+ else if (absScore < 99999) advantage = `Decisive ${score > 0 ? "white" : "black"} advantage`;
13933
+ else advantage = `${score > 0 ? "White" : "Black"} has checkmate`;
13934
+ return JSON.stringify({
13935
+ success: true,
13936
+ fen,
13937
+ evaluation: {
13938
+ score,
13939
+ advantage
13940
+ },
13941
+ material,
13942
+ ...status
13943
+ });
13944
+ }
13945
+ function handleGetBestMove(fen, difficulty = "intermediate") {
13946
+ if (!fen) return JSON.stringify({
13947
+ success: false,
13948
+ error: "FEN string is required."
13949
+ });
13950
+ const game = new Chess(fen);
13951
+ if (game.isGameOver()) return JSON.stringify({
13952
+ success: false,
13953
+ error: "Game is already over.",
13954
+ ...getGameStatusInfo(game)
13955
+ });
13956
+ const bestMove = findBestMove(game, difficulty);
13957
+ if (!bestMove) return JSON.stringify({
13958
+ success: false,
13959
+ error: "No legal moves available."
13960
+ });
13961
+ game.move(bestMove);
13962
+ const status = getGameStatusInfo(game);
13963
+ return wrapWithArtifact({
13964
+ success: true,
13965
+ bestMove,
13966
+ fen: game.fen(),
13967
+ resultingFen: game.fen(),
13968
+ difficulty,
13969
+ turn: game.turn(),
13970
+ ...status
13971
+ });
13972
+ }
13973
+ function handleGetGameStatus(fen) {
13974
+ if (!fen) return JSON.stringify({
13975
+ success: false,
13976
+ error: "FEN string is required."
13977
+ });
13978
+ const game = new Chess(fen);
13979
+ return JSON.stringify({
13980
+ success: true,
13981
+ fen,
13982
+ turn: game.turn(),
13983
+ legalMoves: game.moves(),
13984
+ ...getGameStatusInfo(game)
13985
+ });
13986
+ }
13987
+ function getGameStatusInfo(game) {
13988
+ return {
13989
+ isCheck: game.isCheck(),
13990
+ isCheckmate: game.isCheckmate(),
13991
+ isDraw: game.isDraw(),
13992
+ isStalemate: game.isStalemate(),
13993
+ isThreefoldRepetition: game.isThreefoldRepetition(),
13994
+ isInsufficientMaterial: game.isInsufficientMaterial(),
13995
+ isGameOver: game.isGameOver(),
13996
+ moveNumber: game.moveNumber()
13997
+ };
13998
+ }
13999
+ const chessEngine = async (parameters) => {
14000
+ if (!parameters?.action) throw new Error("Chess engine: Missing required \"action\" parameter.");
14001
+ switch (parameters.action) {
14002
+ case "new_game": return handleNewGame();
14003
+ case "play_turn": return handlePlayTurn(parameters.fen, parameters.move, parameters.difficulty || "intermediate");
14004
+ case "get_legal_moves": return handleGetLegalMoves(parameters.fen);
14005
+ case "evaluate_position": return handleEvaluatePosition(parameters.fen);
14006
+ case "get_best_move": return handleGetBestMove(parameters.fen, parameters.difficulty || "intermediate");
14007
+ case "get_game_status": return handleGetGameStatus(parameters.fen);
14008
+ default: return JSON.stringify({
14009
+ success: false,
14010
+ error: `Unknown action: "${parameters.action}"`
14011
+ });
14012
+ }
14013
+ };
13177
14014
  const b4mTools = {
13178
14015
  dice_roll: diceRollTool,
13179
14016
  weather_info: weatherTool,
@@ -13198,78 +14035,58 @@ const b4mTools = {
13198
14035
  iss_tracker: issTrackerTool,
13199
14036
  planet_visibility: planetVisibilityTool,
13200
14037
  search_knowledge_base: knowledgeBaseSearchTool,
13201
- retrieve_knowledge_content: knowledgeBaseRetrieveTool,
13202
- quantum_schedule: quantumScheduleTool,
13203
- quantum_formulate: quantumFormulateTool,
13204
- navigate_view: navigateViewTool,
13205
- generate_jupyter_notebook: jupyterNotebookTool,
13206
- excel_generation: excelGenerationTool,
13207
- fmp_financial_data: {
13208
- name: "fmp_financial_data",
13209
- implementation: (context) => ({
13210
- toolFn: async (value) => {
13211
- const params = value;
13212
- return executeFmpAction({ db: context.db }, params);
13213
- },
14038
+ chess_engine: {
14039
+ name: "chess_engine",
14040
+ implementation: () => ({
14041
+ toolFn: (value) => chessEngine(value),
13214
14042
  toolSchema: {
13215
- name: "fmp_financial_data",
13216
- description: `Query Financial Modeling Prep for real-time stock market and financial data.
13217
-
13218
- USE FOR:
13219
- - Stock quotes: Current price, change, volume, market cap, P/E ratio (action=quote)
13220
- - Ticker search: Find stock symbols by company name (action=search)
13221
- - Company profiles: Industry, sector, CEO, description, employees (action=profile)
13222
- - Price history: Daily OHLCV data for charting and analysis (action=history)
13223
- - Income statements: Revenue, net income, EPS — annual or quarterly (action=income_statement)
13224
- - Balance sheets: Assets, liabilities, equity — annual or quarterly (action=balance_sheet)
13225
-
13226
- DO NOT USE FOR:
13227
- - Cryptocurrency prices (FMP focuses on equities)
13228
- - Real-time intraday tick data
13229
- - Options or futures data
13230
- - General financial advice or predictions`,
14043
+ name: "chess_engine",
14044
+ description: "A chess engine tool for managing chess games. Validates moves, evaluates positions, and suggests best moves. Use \"new_game\" to start a game. Use \"play_turn\" when the player makes a move — it applies the player's move, computes the AI's best response, applies it, and returns the resulting board position after BOTH moves. \"get_best_move\" suggests a move, \"evaluate_position\" analyzes the board. All positions use FEN (Forsyth-Edwards Notation) and moves use SAN (Standard Algebraic Notation) e.g. \"e4\", \"Nf3\", \"O-O\".",
13231
14045
  parameters: {
13232
14046
  type: "object",
13233
14047
  properties: {
13234
14048
  action: {
13235
14049
  type: "string",
14050
+ description: "The action to perform. \"new_game\" starts a fresh game. \"play_turn\" applies the player's move AND the AI's counter-move in one call — always use this for interactive games. \"get_legal_moves\" lists all legal moves. \"evaluate_position\" gives material and positional analysis. \"get_best_move\" suggests the best move at the given difficulty. \"get_game_status\" checks check/checkmate/draw.",
13236
14051
  enum: [
13237
- "quote",
13238
- "search",
13239
- "profile",
13240
- "history",
13241
- "income_statement",
13242
- "balance_sheet"
13243
- ],
13244
- description: "The type of financial data to retrieve"
14052
+ "new_game",
14053
+ "play_turn",
14054
+ "get_legal_moves",
14055
+ "evaluate_position",
14056
+ "get_best_move",
14057
+ "get_game_status"
14058
+ ]
13245
14059
  },
13246
- symbol: {
14060
+ fen: {
13247
14061
  type: "string",
13248
- description: "Stock ticker symbol (e.g., AAPL, MSFT, GOOGL). Required for all actions except search."
14062
+ description: "FEN string representing the current board position. Required for all actions except \"new_game\". Example starting position: \"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1\""
13249
14063
  },
13250
- query: {
14064
+ move: {
13251
14065
  type: "string",
13252
- description: "Search query to find stock tickers by company name. Required for action=search."
14066
+ description: "The player's move in SAN (Standard Algebraic Notation). Required for \"play_turn\". Examples: \"e4\", \"Nf3\", \"Bxc6\", \"O-O\" (kingside castle), \"O-O-O\" (queenside castle), \"e8=Q\" (promotion)."
13253
14067
  },
13254
- from: {
14068
+ difficulty: {
13255
14069
  type: "string",
13256
- description: "Start date in YYYY-MM-DD format (for action=history). Defaults to 1 year ago."
13257
- },
13258
- to: {
13259
- type: "string",
13260
- description: "End date in YYYY-MM-DD format (for action=history). Defaults to today."
13261
- },
13262
- period: {
13263
- type: "string",
13264
- enum: ["annual", "quarter"],
13265
- description: "Reporting period for financial statements. Defaults to annual."
14070
+ description: "Difficulty level for \"get_best_move\". Controls search depth: beginner (depth 2, some randomness), intermediate (depth 3), advanced (depth 4). Defaults to \"intermediate\".",
14071
+ enum: [
14072
+ "beginner",
14073
+ "intermediate",
14074
+ "advanced"
14075
+ ]
13266
14076
  }
13267
14077
  },
13268
14078
  required: ["action"]
13269
14079
  }
13270
14080
  }
13271
14081
  })
13272
- }
14082
+ },
14083
+ retrieve_knowledge_content: knowledgeBaseRetrieveTool,
14084
+ quantum_schedule: quantumScheduleTool,
14085
+ quantum_formulate: quantumFormulateTool,
14086
+ navigate_view: navigateViewTool,
14087
+ generate_jupyter_notebook: jupyterNotebookTool,
14088
+ excel_generation: excelGenerationTool,
14089
+ fmp_financial_data: fmpTool
13273
14090
  };
13274
14091
  const generateTools = (userId, user, logger, { db }, storage, imageGenerateStorage, statusUpdate, onStart, onFinish, llm, config, model, imageProcessorLambdaName, tools = b4mTools, allowedDirectories) => {
13275
14092
  const context = {
@@ -13747,7 +14564,8 @@ z.object({
13747
14564
  createdFrom: z.enum([
13748
14565
  "dashboard",
13749
14566
  "cli",
13750
- "api"
14567
+ "api",
14568
+ "bridge"
13751
14569
  ])
13752
14570
  })
13753
14571
  });
@@ -19514,14 +20332,18 @@ var ApiClient = class {
19514
20332
  }, (error) => Promise.reject(error));
19515
20333
  this.client.interceptors.response.use((response) => response, async (error) => {
19516
20334
  const originalRequest = error.config;
19517
- if (error.response?.status === 401) logger.error("401 Unauthorized", error);
20335
+ if (error.response?.status === 401) logger.debug("AUTH: Received 401 Unauthorized");
19518
20336
  else if (error.response?.status === 403) logger.error("403 Forbidden", error);
19519
20337
  if (error.response?.status === 401 && !originalRequest._retry) {
19520
20338
  originalRequest._retry = true;
19521
- logger.debug("AUTH: Attempting token refresh");
19522
20339
  try {
19523
20340
  const tokens = await this.configStore.getAuthTokens();
19524
20341
  if (!tokens) throw new Error("Not authenticated");
20342
+ if (Date.now() - (new Date(tokens.expiresAt).getTime() - 10080 * 60 * 1e3) < 3600 * 1e3) {
20343
+ logger.debug("AUTH: Access token is fresh, skipping refresh — 401 is likely transient");
20344
+ return Promise.reject(error);
20345
+ }
20346
+ logger.debug("AUTH: Attempting token refresh");
19525
20347
  const newTokens = await this.oauthClient.refreshToken(tokens.refreshToken);
19526
20348
  logger.debug("AUTH: Token refresh successful");
19527
20349
  const expiresAt = new Date(Date.now() + newTokens.expires_in * 1e3).toISOString();
@@ -19535,16 +20357,17 @@ var ApiClient = class {
19535
20357
  logger.debug("AUTH: Retrying request with new token");
19536
20358
  return this.client(originalRequest);
19537
20359
  } catch (refreshError) {
19538
- console.error("❌ Token refresh failed:", refreshError instanceof Error ? refreshError.message : "Unknown error");
19539
- console.log("Please run `b4m login` again to re-authenticate.");
19540
- logger.error("AUTH: Token refresh failed", refreshError);
19541
- await this.configStore.clearAuthTokens();
20360
+ const refreshMsg = refreshError instanceof Error ? refreshError.message : "Unknown error";
20361
+ logger.warn(`AUTH: Token refresh failed: ${refreshMsg}`);
20362
+ const tokens = await this.configStore.getAuthTokens();
20363
+ if (tokens && new Date(tokens.expiresAt) <= /* @__PURE__ */ new Date()) await this.configStore.clearAuthTokens();
19542
20364
  throw new Error("Authentication expired. Please run `b4m login` again.");
19543
20365
  }
19544
20366
  }
19545
20367
  if (error.response?.status === 401 && originalRequest._retry) {
19546
- logger.debug("AUTH: Token refresh retry failed - clearing tokens");
19547
- await this.configStore.clearAuthTokens();
20368
+ logger.debug("AUTH: Token refresh retry failed");
20369
+ const tokens = await this.configStore.getAuthTokens();
20370
+ if (tokens && new Date(tokens.expiresAt) <= /* @__PURE__ */ new Date()) await this.configStore.clearAuthTokens();
19548
20371
  throw new Error("Authentication failed. Please run /login to authenticate.");
19549
20372
  }
19550
20373
  return Promise.reject(error);
@@ -20138,12 +20961,13 @@ const FULL_MODEL_ID_PREFIXES = [
20138
20961
  * 2. Set the value to the full model ID from ChatModels enum
20139
20962
  */
20140
20963
  const MODEL_ALIASES = {
20141
- opus: ChatModels.CLAUDE_4_6_OPUS,
20964
+ opus: ChatModels.CLAUDE_4_7_OPUS,
20142
20965
  sonnet: ChatModels.CLAUDE_4_5_SONNET,
20143
20966
  haiku: ChatModels.CLAUDE_4_5_HAIKU,
20144
- "claude-opus": ChatModels.CLAUDE_4_6_OPUS,
20967
+ "claude-opus": ChatModels.CLAUDE_4_7_OPUS,
20145
20968
  "claude-sonnet": ChatModels.CLAUDE_4_5_SONNET,
20146
20969
  "claude-haiku": ChatModels.CLAUDE_4_5_HAIKU,
20970
+ "claude-4.7-opus": ChatModels.CLAUDE_4_7_OPUS,
20147
20971
  "claude-4.6-opus": ChatModels.CLAUDE_4_6_OPUS,
20148
20972
  "claude-4.6-sonnet": ChatModels.CLAUDE_4_6_SONNET,
20149
20973
  "claude-4.5-opus": ChatModels.CLAUDE_4_5_OPUS,
@@ -20155,7 +20979,7 @@ const MODEL_ALIASES = {
20155
20979
  "claude-3.7-sonnet": ChatModels.CLAUDE_4_6_SONNET,
20156
20980
  "claude-3.5-sonnet": ChatModels.CLAUDE_4_5_SONNET,
20157
20981
  "claude-3.5-haiku": ChatModels.CLAUDE_4_5_HAIKU,
20158
- "claude-3-opus": ChatModels.CLAUDE_4_6_OPUS,
20982
+ "claude-3-opus": ChatModels.CLAUDE_4_7_OPUS,
20159
20983
  "gpt-4": ChatModels.GPT4,
20160
20984
  "gpt-4o": ChatModels.GPT4o,
20161
20985
  "gpt-4o-mini": ChatModels.GPT4o_MINI,