hive-intelligence 1.7.2 → 1.8.0

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.
@@ -19461,8 +19461,15 @@ var DeFiLlamaAPI = class {
19461
19461
  async getPriceChart(coins, start, span, period, searchWidth, end) {
19462
19462
  const endpoint = `/chart/${encodeURIComponent(coins)}`;
19463
19463
  const params = {};
19464
+ const bounded = Boolean(start && end && end > start);
19465
+ if (bounded && !span) {
19466
+ span = Math.min(
19467
+ Math.ceil((end - start) / chartPeriodSeconds(period)) + 1,
19468
+ 500
19469
+ );
19470
+ }
19464
19471
  if (start) params.start = start;
19465
- if (end) params.end = end;
19472
+ if (end && !start) params.end = end;
19466
19473
  if (span) params.span = span;
19467
19474
  if (period) params.period = period;
19468
19475
  if (searchWidth) params.searchWidth = searchWidth;
@@ -19473,10 +19480,13 @@ var DeFiLlamaAPI = class {
19473
19480
  for (const [coin, coinData] of Object.entries(data.coins)) {
19474
19481
  const typedCoinData = coinData;
19475
19482
  if (typedCoinData.prices && Array.isArray(typedCoinData.prices)) {
19483
+ const inRange = bounded ? typedCoinData.prices.filter(
19484
+ (point) => typeof point.timestamp !== "number" || point.timestamp <= end
19485
+ ) : typedCoinData.prices;
19476
19486
  limitedData.coins[coin] = {
19477
19487
  ...typedCoinData,
19478
- prices: typedCoinData.prices.slice(-100),
19479
- originalPriceCount: typedCoinData.prices.length
19488
+ prices: inRange.slice(-100),
19489
+ originalPriceCount: inRange.length
19480
19490
  };
19481
19491
  } else {
19482
19492
  limitedData.coins[coin] = typedCoinData;
@@ -19806,6 +19816,12 @@ var DeFiLlamaAPI = class {
19806
19816
  return data;
19807
19817
  }
19808
19818
  };
19819
+ function chartPeriodSeconds(period) {
19820
+ const match = /^(\d+)\s*([mhdw])$/i.exec((period ?? "").trim());
19821
+ if (!match) return 86400;
19822
+ const unit = { m: 60, h: 3600, d: 86400, w: 604800 };
19823
+ return Math.max(Number(match[1]), 1) * unit[match[2].toLowerCase()];
19824
+ }
19809
19825
 
19810
19826
  // src/tools/defillamaTools/tools/categories/protocols.ts
19811
19827
  function protocolsTools(apiClient) {
@@ -26777,7 +26793,14 @@ function classifyRuntimeStatusFromError(error) {
26777
26793
  normalized.includes("unknown chain") || // Provider-side rejections of a malformed identifier (GoPlus "Address
26778
26794
  // format error!", "invalid address", "not a valid address") are the
26779
26795
  // caller's to fix, not an outage (2026-09-16 audit).
26780
- normalized.includes("address format") || normalized.includes("invalid address") || normalized.includes("not a valid address") || normalized.includes("malformed address")) {
26796
+ normalized.includes("address format") || normalized.includes("invalid address") || normalized.includes("not a valid address") || normalized.includes("malformed address") || // 2026-09-24 sweep: upstream bodies the HTTP client now surfaces. Helius
26797
+ // "Invalid wallet address ... is not a valid Solana address", DAS "Pubkey
26798
+ // Validation Err", GoPlus 7012 "Not fungible spl token address", Alchemy
26799
+ // "invalid 1st argument", and a simulated transaction that reverts.
26800
+ /\binvalid [a-z ]{0,24}address\b/.test(normalized) || /\bnot a valid [a-z ]{0,24}address\b/.test(normalized) || normalized.includes("pubkey validation") || normalized.includes("invalid pubkey") || normalized.includes("not fungible") || /\binvalid \d+(st|nd|rd|th) argument\b/.test(normalized) || normalized.includes("execution reverted") || // Tenderly gateway: -32006 "Bad request input parameters".
26801
+ normalized.includes("bad request input") || // An upstream 404 that says the id or address does not exist. A bare
26802
+ // "status code 404" with no body stays failing: it may be our own route.
26803
+ /\b404\b/.test(normalized) && normalized.includes("not found")) {
26781
26804
  return "invalid_input";
26782
26805
  }
26783
26806
  if (normalized.includes("timed out") || normalized.includes("timeout") || normalized.includes("temporarily") || normalized.includes("service unavailable") || normalized.includes("502") || normalized.includes("503") || normalized.includes("504")) {
@@ -30937,16 +30960,35 @@ function getCircuitBreaker(serviceName) {
30937
30960
  }
30938
30961
  return circuitBreakers.get(serviceName);
30939
30962
  }
30963
+ function upstreamDetail(error) {
30964
+ const data = error.response?.data;
30965
+ const text = (value) => typeof value === "string" && value.trim() ? value.trim() : void 0;
30966
+ let detail;
30967
+ if (typeof data === "string") {
30968
+ detail = text(data.replace(/<[^>]*>/g, " "));
30969
+ } else if (data && typeof data === "object") {
30970
+ const body = data;
30971
+ const nested = body.error && typeof body.error === "object" ? text(body.error.message) : void 0;
30972
+ const primary = text(body.message) ?? text(body.error) ?? nested ?? text(body.error_message) ?? text(body.status?.error_message) ?? text(body.msg);
30973
+ const details = text(body.details);
30974
+ detail = primary && details && !primary.includes(details) ? `${primary} (${details})` : primary ?? details;
30975
+ }
30976
+ if (!detail) return null;
30977
+ const compact = detail.replace(/\s+/g, " ").trim();
30978
+ return compact ? compact.slice(0, 240) : null;
30979
+ }
30980
+ function withUpstreamDetail(error) {
30981
+ if (!(error instanceof AxiosError)) return error;
30982
+ const detail = upstreamDetail(error);
30983
+ if (detail && !error.message.includes(detail)) {
30984
+ error.message = `${error.message}: ${detail}`;
30985
+ }
30986
+ return error;
30987
+ }
30940
30988
  function failureMessage(error) {
30941
30989
  let message = "";
30942
30990
  if (error instanceof AxiosError) {
30943
- const data = error.response?.data;
30944
- const fromBody = [
30945
- data?.message,
30946
- data?.error,
30947
- data?.status?.error_message
30948
- ].find((value) => typeof value === "string" && value.trim());
30949
- message = typeof fromBody === "string" ? fromBody : error.message;
30991
+ message = upstreamDetail(error) ?? error.message;
30950
30992
  } else if (error instanceof Error) {
30951
30993
  message = error.message;
30952
30994
  } else if (error) {
@@ -31159,7 +31201,7 @@ var ResilientHttpClient = class {
31159
31201
  break;
31160
31202
  }
31161
31203
  }
31162
- throw lastError;
31204
+ throw withUpstreamDetail(lastError);
31163
31205
  }
31164
31206
  /**
31165
31207
  * Perform a GET request
@@ -31243,6 +31285,39 @@ function createHttpClient(config2) {
31243
31285
  }
31244
31286
 
31245
31287
  // src/tools/tenderly/tenderlyClient.ts
31288
+ var GATEWAY_MAX_IN_FLIGHT = 2;
31289
+ var GATEWAY_MAX_ATTEMPTS = 4;
31290
+ var gatewayInFlight = 0;
31291
+ var gatewayWaiters = [];
31292
+ async function withGatewaySlot(task) {
31293
+ if (gatewayInFlight >= GATEWAY_MAX_IN_FLIGHT) {
31294
+ await new Promise((resolve) => gatewayWaiters.push(resolve));
31295
+ }
31296
+ gatewayInFlight++;
31297
+ try {
31298
+ return await task();
31299
+ } finally {
31300
+ gatewayInFlight--;
31301
+ gatewayWaiters.shift()?.();
31302
+ }
31303
+ }
31304
+ function gatewayRetryDelayMs(attempt, retryAfter) {
31305
+ const seconds = Number(retryAfter);
31306
+ if (Number.isFinite(seconds) && seconds > 0) {
31307
+ return Math.min(seconds * 1e3, 5e3);
31308
+ }
31309
+ return 1e3 * 2 ** (attempt - 1) + Math.random() * 250;
31310
+ }
31311
+ function gatewayErrorDetail(bodyText) {
31312
+ try {
31313
+ const parsed = JSON.parse(bodyText);
31314
+ const message = parsed?.error?.message;
31315
+ return typeof message === "string" && message.trim() ? `: ${message.trim()}` : "";
31316
+ } catch {
31317
+ const compact = bodyText.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim();
31318
+ return compact ? `: ${compact.slice(0, 200)}` : "";
31319
+ }
31320
+ }
31246
31321
  var TenderlyClient = class {
31247
31322
  httpClient;
31248
31323
  apiKey;
@@ -31428,17 +31503,37 @@ var TenderlyClient = class {
31428
31503
  params
31429
31504
  };
31430
31505
  try {
31431
- const response = await fetch(url, {
31432
- method: "POST",
31433
- headers: { "Content-Type": "application/json" },
31434
- body: JSON.stringify(body),
31435
- signal: AbortSignal.timeout(3e4)
31506
+ const response = await withGatewaySlot(async () => {
31507
+ for (let attempt = 1; ; attempt++) {
31508
+ const attemptResponse = await fetch(url, {
31509
+ method: "POST",
31510
+ headers: { "Content-Type": "application/json" },
31511
+ body: JSON.stringify(body),
31512
+ signal: AbortSignal.timeout(3e4)
31513
+ });
31514
+ if (attemptResponse.ok) return attemptResponse;
31515
+ const retryable = attemptResponse.status === 429 || attemptResponse.status >= 500;
31516
+ if (retryable && attempt < GATEWAY_MAX_ATTEMPTS) {
31517
+ await attemptResponse.body?.cancel().catch(() => void 0);
31518
+ await new Promise(
31519
+ (resolve) => setTimeout(
31520
+ resolve,
31521
+ gatewayRetryDelayMs(
31522
+ attempt,
31523
+ attemptResponse.headers.get("retry-after")
31524
+ )
31525
+ )
31526
+ );
31527
+ continue;
31528
+ }
31529
+ const detail = gatewayErrorDetail(
31530
+ await attemptResponse.text().catch(() => "")
31531
+ );
31532
+ throw new Error(
31533
+ `Gateway RPC error: ${attemptResponse.status} ${attemptResponse.statusText}${detail}`
31534
+ );
31535
+ }
31436
31536
  });
31437
- if (!response.ok) {
31438
- throw new Error(
31439
- `Gateway RPC error: ${response.status} ${response.statusText}`
31440
- );
31441
- }
31442
31537
  const json = await response.json();
31443
31538
  if (json.error) {
31444
31539
  throw new Error(`RPC error ${json.error.code}: ${json.error.message}`);
@@ -32608,7 +32703,9 @@ var gatewayDefinitions = [
32608
32703
  makeGatewayTool(
32609
32704
  "suggestGasFee",
32610
32705
  "tenderly_suggest_gas_fee",
32611
- "suggestGasFee",
32706
+ // The gateway method is plural; "suggestGasFee" answers "method not
32707
+ // found" (2026-09-24 sweep).
32708
+ "suggestGasFees",
32612
32709
  "Get EIP-1559 max-fee and priority-fee suggestions with estimated inclusion times.",
32613
32710
  {},
32614
32711
  [],
@@ -43819,7 +43916,7 @@ var AlchemyClient = class {
43819
43916
  apiPath(path) {
43820
43917
  return path.replace("{apiKey}", encodeURIComponent(this.apiKey));
43821
43918
  }
43822
- async rpc(network, method, params = []) {
43919
+ async rpc(network, method, params = [], options = {}) {
43823
43920
  const startTime = Date.now();
43824
43921
  const client2 = this.getHttpClient(
43825
43922
  `https://${network}.g.alchemy.com`,
@@ -43834,7 +43931,7 @@ var AlchemyClient = class {
43834
43931
  try {
43835
43932
  const response = await client2.post(
43836
43933
  `/v2/${encodeURIComponent(this.apiKey)}`,
43837
- { body }
43934
+ { body, ...options }
43838
43935
  );
43839
43936
  if (response.error) {
43840
43937
  secureLogger.toolCall(`AlchemyRPC:${method}`, false, Date.now() - startTime, {
@@ -44226,46 +44323,146 @@ function rpcTool(key, name, description, method, properties, paramsBuilder, requ
44226
44323
  }
44227
44324
  };
44228
44325
  }
44326
+ var HELIUS_DAS_METHODS = {
44327
+ getAssets: "getAssetBatch",
44328
+ getAssetProofs: "getAssetProofBatch",
44329
+ getAssetSignatures: "getSignaturesForAsset"
44330
+ };
44331
+ var HELIUS_DAS_PARAM_RENAMES = {
44332
+ getNftEditions: { mintAddress: "mint" },
44333
+ getTokenAccounts: { ownerAddress: "owner", mintAddress: "mint" }
44334
+ };
44335
+ var ALCHEMY_SOLANA_INDEXER_TIMEOUT_MS = 6e3;
44336
+ var heliusFallbackClient = null;
44337
+ function getHeliusFallbackClient() {
44338
+ if (!heliusFallbackClient && process.env.HELIUS_API_KEY) {
44339
+ heliusFallbackClient = new HeliusClient(process.env.HELIUS_API_KEY);
44340
+ }
44341
+ return heliusFallbackClient;
44342
+ }
44343
+ function toHeliusRequest(method, params) {
44344
+ const renames = HELIUS_DAS_PARAM_RENAMES[method];
44345
+ const renamed = renames && params && typeof params === "object" && !Array.isArray(params) ? Object.fromEntries(
44346
+ Object.entries(params).map(
44347
+ ([key, value]) => [renames[key] ?? key, value]
44348
+ )
44349
+ ) : params;
44350
+ return { method: HELIUS_DAS_METHODS[method] ?? method, params: renamed };
44351
+ }
44352
+ function withSolanaIndexerFallback(definition, method, paramsBuilder) {
44353
+ const name = definition.tool.name;
44354
+ return {
44355
+ ...definition,
44356
+ handler: async (clientParam, args = {}) => {
44357
+ const network = String(args.network || "solana-mainnet");
44358
+ const helius2 = network === "solana-mainnet" ? getHeliusFallbackClient() : null;
44359
+ if (!helius2) return definition.handler(clientParam, args);
44360
+ let alchemyError = new Error("Alchemy API key not configured");
44361
+ const client2 = resolveClient4(clientParam);
44362
+ if (client2) {
44363
+ try {
44364
+ const result2 = await client2.rpc(network, method, paramsBuilder(args), {
44365
+ timeout: ALCHEMY_SOLANA_INDEXER_TIMEOUT_MS,
44366
+ skipRetry: true
44367
+ });
44368
+ return createSuccessResponse6(shapeRpcResult(name, network, result2));
44369
+ } catch (error) {
44370
+ const message = error instanceof Error ? error.message : String(error);
44371
+ if (classifyRuntimeStatusFromError(message) === "invalid_input") {
44372
+ return createErrorResponse6(
44373
+ error,
44374
+ name,
44375
+ "Check JSON-RPC params and network support.",
44376
+ args
44377
+ );
44378
+ }
44379
+ alchemyError = error;
44380
+ }
44381
+ }
44382
+ const request = toHeliusRequest(method, paramsBuilder(args));
44383
+ try {
44384
+ const result2 = await helius2.request(
44385
+ request.method,
44386
+ request.params
44387
+ );
44388
+ const reason = alchemyError instanceof Error ? alchemyError.message : String(alchemyError);
44389
+ const shaped = shapeRpcResult(name, network, result2);
44390
+ const payload = shaped && typeof shaped === "object" && !Array.isArray(shaped) ? { ...shaped } : { result: shaped };
44391
+ return {
44392
+ ...createSuccessResponse6({
44393
+ ...payload,
44394
+ _fallback: {
44395
+ provider: "Helius",
44396
+ method: request.method,
44397
+ reason: `Alchemy ${method} unavailable: ${reason.slice(0, 160)}`
44398
+ }
44399
+ }),
44400
+ _hiveExec: { source: "fallback", originSource: "fallback" }
44401
+ };
44402
+ } catch (heliusError) {
44403
+ const heliusMessage = heliusError instanceof Error ? heliusError.message : String(heliusError);
44404
+ const alchemyMessage = alchemyError instanceof Error ? alchemyError.message : String(alchemyError);
44405
+ return createErrorResponse6(
44406
+ new Error(
44407
+ `${alchemyMessage}; Helius fallback (${request.method}) also failed: ${heliusMessage}`
44408
+ ),
44409
+ name,
44410
+ "Check JSON-RPC params and network support.",
44411
+ args
44412
+ );
44413
+ }
44414
+ }
44415
+ };
44416
+ }
44229
44417
  function dasTool(key, name, description, method, properties, required = [], schemaExtensions = {}) {
44230
- return rpcTool(
44231
- key,
44232
- name,
44233
- `${description} Uses Alchemy's Solana Digital Asset Standard (DAS) API.`,
44234
- method,
44235
- {
44236
- network: {
44237
- type: "string",
44238
- enum: ["solana-mainnet", "solana-devnet"],
44239
- default: "solana-mainnet",
44240
- description: "Alchemy Solana network slug."
44418
+ const paramsBuilder = (args) => omitKeys(args, ["network"]);
44419
+ return withSolanaIndexerFallback(
44420
+ rpcTool(
44421
+ key,
44422
+ name,
44423
+ `${description} Uses Alchemy's Solana Digital Asset Standard (DAS) API, with Helius as the mainnet fallback.`,
44424
+ method,
44425
+ {
44426
+ network: {
44427
+ type: "string",
44428
+ enum: ["solana-mainnet", "solana-devnet"],
44429
+ default: "solana-mainnet",
44430
+ description: "Alchemy Solana network slug."
44431
+ },
44432
+ ...properties
44241
44433
  },
44242
- ...properties
44243
- },
44244
- (args) => omitKeys(args, ["network"]),
44245
- required,
44246
- { ...schemaExtensions, additionalProperties: false },
44247
- "solana-mainnet"
44434
+ paramsBuilder,
44435
+ required,
44436
+ { ...schemaExtensions, additionalProperties: false },
44437
+ "solana-mainnet"
44438
+ ),
44439
+ method,
44440
+ paramsBuilder
44248
44441
  );
44249
44442
  }
44250
44443
  function photonTool(key, name, description, method, properties, paramsBuilder, required = [], schemaExtensions = {}) {
44251
- return rpcTool(
44252
- key,
44253
- name,
44254
- `${description} Uses Alchemy's Solana Photon/ZK Compression indexer.`,
44255
- method,
44256
- {
44257
- network: {
44258
- type: "string",
44259
- enum: ["solana-mainnet", "solana-devnet"],
44260
- default: "solana-mainnet",
44261
- description: "Alchemy Solana network slug."
44444
+ return withSolanaIndexerFallback(
44445
+ rpcTool(
44446
+ key,
44447
+ name,
44448
+ `${description} Uses Alchemy's Solana Photon/ZK Compression indexer, with Helius as the mainnet fallback.`,
44449
+ method,
44450
+ {
44451
+ network: {
44452
+ type: "string",
44453
+ enum: ["solana-mainnet", "solana-devnet"],
44454
+ default: "solana-mainnet",
44455
+ description: "Alchemy Solana network slug."
44456
+ },
44457
+ ...properties
44262
44458
  },
44263
- ...properties
44264
- },
44265
- paramsBuilder,
44266
- required,
44267
- { ...schemaExtensions, additionalProperties: false },
44268
- "solana-mainnet"
44459
+ paramsBuilder,
44460
+ required,
44461
+ { ...schemaExtensions, additionalProperties: false },
44462
+ "solana-mainnet"
44463
+ ),
44464
+ method,
44465
+ paramsBuilder
44269
44466
  );
44270
44467
  }
44271
44468
  function requireExactlyOne(args, first, second) {
@@ -44865,8 +45062,16 @@ var definitions = [
44865
45062
  description: "Block context used for the simulation."
44866
45063
  }
44867
45064
  },
44868
- (args) => [args.format ?? "FLAT", args.transaction, args.blockTag ?? "latest"],
44869
- ["format", "transaction", "blockTag"]
45065
+ // Alchemy's positional order is [transaction, blockTag, { format }]. Sending
45066
+ // the format first made every call fail with "invalid 1st argument"
45067
+ // (2026-09-24 sweep); format and blockTag have defaults, so neither is
45068
+ // required.
45069
+ (args) => [
45070
+ args.transaction,
45071
+ args.blockTag ?? "latest",
45072
+ { format: args.format ?? "FLAT" }
45073
+ ],
45074
+ ["transaction"]
44870
45075
  ),
44871
45076
  rpcTool(
44872
45077
  "simulateAssetChangesBundle",
@@ -46235,6 +46440,42 @@ var HyperliquidAPI = class {
46235
46440
 
46236
46441
  // src/tools/hyperliquid/infoTools.ts
46237
46442
  var MAX_ARRAY_ITEMS = 500;
46443
+ var SPOT_TOKEN_TTL_MS = 10 * 60 * 1e3;
46444
+ var spotTokenCache = null;
46445
+ async function listSpotTokens(api) {
46446
+ if (spotTokenCache && Date.now() - spotTokenCache.at < SPOT_TOKEN_TTL_MS) {
46447
+ return spotTokenCache.tokens;
46448
+ }
46449
+ const meta2 = await api.info({ type: "spotMeta" });
46450
+ const tokens = (meta2?.tokens ?? []).flatMap(
46451
+ (token) => typeof token.name === "string" && typeof token.tokenId === "string" ? [
46452
+ {
46453
+ name: token.name,
46454
+ tokenId: token.tokenId,
46455
+ index: typeof token.index === "number" ? token.index : void 0
46456
+ }
46457
+ ] : []
46458
+ );
46459
+ spotTokenCache = { at: Date.now(), tokens };
46460
+ return tokens;
46461
+ }
46462
+ async function resolveSpotTokenId(value, api) {
46463
+ const raw = String(value).trim();
46464
+ let tokens;
46465
+ try {
46466
+ tokens = await listSpotTokens(api);
46467
+ } catch {
46468
+ return raw;
46469
+ }
46470
+ const lower = raw.toLowerCase();
46471
+ const match = tokens.find((token) => token.tokenId.toLowerCase() === lower) ?? tokens.find((token) => token.name.toLowerCase() === lower) ?? (/^\d+$/.test(raw) ? tokens.find((token) => token.index === Number(raw)) : void 0);
46472
+ if (!match) {
46473
+ throw new Error(
46474
+ `Invalid arguments: unknown Hyperliquid spot token '${raw}'. Pass a tokenId from hyperliquid_get_spot_meta tokens[].tokenId (USDC is 0x6d1e7cde53ba9467b783cb7c530ce054) or a spot token name such as "HYPE".`
46475
+ );
46476
+ }
46477
+ return match.tokenId;
46478
+ }
46238
46479
  var USER = {
46239
46480
  arg: "user",
46240
46481
  field: "user",
@@ -46738,8 +46979,9 @@ var HYPERLIQUID_INFO_DESCRIPTORS = [
46738
46979
  required: true,
46739
46980
  schema: {
46740
46981
  type: "string",
46741
- description: 'Token id in 34-character hexadecimal format (from hyperliquid_get_spot_meta tokens[].tokenId), e.g. "0x00000000000000000000000000000000".'
46742
- }
46982
+ description: 'Token id in 34-character hexadecimal format (from hyperliquid_get_spot_meta tokens[].tokenId), e.g. "0x6d1e7cde53ba9467b783cb7c530ce054" (USDC). A spot token name such as "HYPE" is also accepted.'
46983
+ },
46984
+ resolve: resolveSpotTokenId
46743
46985
  }
46744
46986
  ]
46745
46987
  },
@@ -47103,7 +47345,8 @@ function getHyperliquidInfoEndpoints(api) {
47103
47345
  }
47104
47346
  continue;
47105
47347
  }
47106
- body[param.field] = param.coerce ? param.coerce(raw) : raw;
47348
+ const coerced = param.coerce ? param.coerce(raw) : raw;
47349
+ body[param.field] = param.resolve ? await param.resolve(coerced, api) : coerced;
47107
47350
  }
47108
47351
  const data = await api.info(body);
47109
47352
  const transformed = descriptor.transform ? descriptor.transform(data) : data;
@@ -54089,6 +54332,199 @@ function normalizeEndpointSchema(endpoint) {
54089
54332
  };
54090
54333
  }
54091
54334
 
54335
+ // src/config/retiredTools.ts
54336
+ var RETIRED_TOOLS_DATE = "2026-09-06";
54337
+ var RETIRED_TOOL_REPLACEMENTS = {
54338
+ // wallet
54339
+ codex_filter_wallets_by_network: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
54340
+ codex_get_wallet_aggregate_backfill_state: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
54341
+ codex_get_wallet_label_types: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
54342
+ filter_network_wallets: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
54343
+ filter_token_wallets: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
54344
+ filter_wallets: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
54345
+ get_wallet_balances: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
54346
+ get_wallet_chart: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
54347
+ get_wallet_stats: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
54348
+ get_wallet_token_events: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
54349
+ // holders
54350
+ get_token_holders: "Use get_token_top_holders for holders on any network, coingecko_get_onchain_token_top_traders for traders where CoinGecko serves them (base and similar; not Ethereum on the current plan), or moralis_get_token_holder_metrics for holder metrics.",
54351
+ get_token_top_traders: "Use get_token_top_holders for holders on any network, coingecko_get_onchain_token_top_traders for traders where CoinGecko serves them (base and similar; not Ethereum on the current plan), or moralis_get_token_holder_metrics for holder metrics.",
54352
+ get_top_holders_percentage: "Use get_token_top_holders for holders on any network, coingecko_get_onchain_token_top_traders for traders where CoinGecko serves them (base and similar; not Ethereum on the current plan), or moralis_get_token_holder_metrics for holder metrics.",
54353
+ // pairs
54354
+ codex_get_detailed_token_stats: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
54355
+ codex_get_windowed_pair_stats: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
54356
+ filter_pairs: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
54357
+ get_detailed_stats: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
54358
+ get_latest_pairs: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
54359
+ get_liquidity_info: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
54360
+ get_pair_chart_metadata: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
54361
+ get_pair_info: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
54362
+ get_pair_stats: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
54363
+ get_pairs_stats: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
54364
+ get_token_liquidity_metadata: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
54365
+ get_token_pairs: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
54366
+ get_token_pairs_metadata: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
54367
+ // charts
54368
+ codex_get_bars: "Use get_token_ohlcv, get_pool_ohlcv, or moralis_get_pair_ohlcv for candles.",
54369
+ codex_get_token_bars: "Use get_token_ohlcv, get_pool_ohlcv, or moralis_get_pair_ohlcv for candles.",
54370
+ get_token_chart_data: "Use get_token_ohlcv, get_pool_ohlcv, or moralis_get_pair_ohlcv for candles.",
54371
+ get_token_chart_urls: "Use get_token_ohlcv, get_pool_ohlcv, or moralis_get_pair_ohlcv for candles.",
54372
+ get_token_sparklines: "Use get_token_ohlcv, get_pool_ohlcv, or moralis_get_pair_ohlcv for candles.",
54373
+ // price
54374
+ codex_get_token_price: "Use alchemy_get_token_prices_by_address or get_onchain_token_price for on-chain token prices.",
54375
+ // tokens
54376
+ codex_filter_launchpads: "Use get_token_info, alchemy_get_token_metadata, moralis_search_tokens, get_new_pools, or get_token_trades for token discovery and activity.",
54377
+ filter_tokens: "Use get_token_info, alchemy_get_token_metadata, moralis_search_tokens, get_new_pools, or get_token_trades for token discovery and activity.",
54378
+ get_new_tokens: "Use get_token_info, alchemy_get_token_metadata, moralis_search_tokens, get_new_pools, or get_token_trades for token discovery and activity.",
54379
+ get_token_details: "Use get_token_info, alchemy_get_token_metadata, moralis_search_tokens, get_new_pools, or get_token_trades for token discovery and activity.",
54380
+ get_token_transactions: "Use get_token_info, alchemy_get_token_metadata, moralis_search_tokens, get_new_pools, or get_token_trades for token discovery and activity.",
54381
+ get_tokens: "Use get_token_info, alchemy_get_token_metadata, moralis_search_tokens, get_new_pools, or get_token_trades for token discovery and activity.",
54382
+ list_top_tokens: "Use get_token_info, alchemy_get_token_metadata, moralis_search_tokens, get_new_pools, or get_token_trades for token discovery and activity.",
54383
+ search_tokens: "Use get_token_info, alchemy_get_token_metadata, moralis_search_tokens, get_new_pools, or get_token_trades for token discovery and activity.",
54384
+ // network
54385
+ codex_get_blocks: "Use get_networks, tenderly_get_supported_networks, alchemy_get_block_by_number, or get_dexes for network and DEX reads.",
54386
+ codex_get_network_configs: "Use get_networks, tenderly_get_supported_networks, alchemy_get_block_by_number, or get_dexes for network and DEX reads.",
54387
+ filter_exchanges: "Use get_networks, tenderly_get_supported_networks, alchemy_get_block_by_number, or get_dexes for network and DEX reads.",
54388
+ filter_networks: "Use get_networks, tenderly_get_supported_networks, alchemy_get_block_by_number, or get_dexes for network and DEX reads.",
54389
+ get_network_dexes: "Use get_networks, tenderly_get_supported_networks, alchemy_get_block_by_number, or get_dexes for network and DEX reads.",
54390
+ get_network_stats: "Use get_networks, tenderly_get_supported_networks, alchemy_get_block_by_number, or get_dexes for network and DEX reads.",
54391
+ get_network_status: "Use get_networks, tenderly_get_supported_networks, alchemy_get_block_by_number, or get_dexes for network and DEX reads.",
54392
+ get_networks_list: "Use get_networks, tenderly_get_supported_networks, alchemy_get_block_by_number, or get_dexes for network and DEX reads.",
54393
+ // locks
54394
+ get_liquidity_locks: "Use get_token_lock_info or the goplus_get_lp_v3_locks and goplus_get_lp_v4_locks security tools for LP locks.",
54395
+ // misc
54396
+ codex_get_categories: "No direct replacement; use get_categories_market_data or moralis_get_entity_categories for category data.",
54397
+ codex_get_category: "No direct replacement; use get_categories_market_data or moralis_get_entity_categories for category data.",
54398
+ codex_get_category_tokens: "No direct replacement; use get_categories_market_data or moralis_get_entity_categories for category data.",
54399
+ get_community_notes: "No direct replacement; use get_categories_market_data or moralis_get_entity_categories for category data.",
54400
+ get_event_labels: "No direct replacement; use get_categories_market_data or moralis_get_entity_categories for category data."
54401
+ };
54402
+ var PREDICTION_REPLACEMENT = 'Prediction markets are served by first-party Polymarket tools since 1.7.0: polymarket_search_markets, polymarket_get_events, polymarket_get_market, polymarket_get_price_history, polymarket_get_orderbook, polymarket_get_wallet_positions, polymarket_get_wallet_activity. Kalshi is not covered. Start with search_tools({"query": "prediction markets"}) or hive://toolsets/prediction_markets.';
54403
+ var UNSERVABLE_TOOLS_DATE = "2026-09-24";
54404
+ var COINGECKO_ENTERPRISE = "because it needs a CoinGecko Enterprise plan, which Hive does not have";
54405
+ var COINGECKO_SUPPLY_REPLACEMENT = "Use get_coin_supply_breakdown for current circulating, total, and max supply, or get_coin_market_chart_range for a market-cap and price series.";
54406
+ var HELIUS_WALLET_PLAN = "because Helius answers 403 for it on Hive's current Helius plan";
54407
+ var DEFILLAMA_PRO = "because it needs a DeFiLlama Pro plan, which Hive does not have";
54408
+ var DEFILLAMA_DERIVATIVES_REPLACEMENT = "Use defillama_get_open_interest, defillama_get_derivatives_aggregator_volumes, or get_derivatives_exchanges for derivatives activity.";
54409
+ var ALCHEMY_PAYG = "because Alchemy offers it only on Pay As You Go and Enterprise plans, and Hive's key is on the Free tier";
54410
+ var ALCHEMY_BUNDLE_REPLACEMENT = "Use tenderly_simulate_bundle for multi-transaction simulation, or alchemy_simulate_asset_changes and alchemy_simulate_execution one transaction at a time.";
54411
+ var CCXT_PRIVATE = "because every exchange that serves it requires an authenticated exchange account";
54412
+ var CCXT_BORROW_REPLACEMENT = "Use ccxt_fetch_borrow_rate_history or ccxt_fetch_borrow_rate_histories (public) and read the latest point.";
54413
+ var UNSERVABLE_TOOLS = {
54414
+ get_coin_circulating_supply_chart: {
54415
+ reason: COINGECKO_ENTERPRISE,
54416
+ replacement: COINGECKO_SUPPLY_REPLACEMENT
54417
+ },
54418
+ get_coin_circulating_supply_chart_range: {
54419
+ reason: COINGECKO_ENTERPRISE,
54420
+ replacement: COINGECKO_SUPPLY_REPLACEMENT
54421
+ },
54422
+ get_coin_total_supply_chart: {
54423
+ reason: COINGECKO_ENTERPRISE,
54424
+ replacement: COINGECKO_SUPPLY_REPLACEMENT
54425
+ },
54426
+ get_coin_total_supply_chart_range: {
54427
+ reason: COINGECKO_ENTERPRISE,
54428
+ replacement: COINGECKO_SUPPLY_REPLACEMENT
54429
+ },
54430
+ get_coin_insights: {
54431
+ reason: COINGECKO_ENTERPRISE,
54432
+ replacement: "No direct replacement; use get_coins_market_data and get_coin_tickers for the market facts behind an insight."
54433
+ },
54434
+ helius_get_wallet_identity: {
54435
+ reason: HELIUS_WALLET_PLAN,
54436
+ replacement: "No other wallet-identity source is live on Hive's plans; use helius_get_wallet_history or helius_get_transfers_by_address for the wallet's activity."
54437
+ },
54438
+ helius_get_wallet_batch_identity: {
54439
+ reason: HELIUS_WALLET_PLAN,
54440
+ replacement: "No other wallet-identity source is live on Hive's plans; use helius_get_wallet_history or helius_get_transfers_by_address for each wallet's activity."
54441
+ },
54442
+ helius_get_wallet_funded_by: {
54443
+ reason: HELIUS_WALLET_PLAN,
54444
+ replacement: "Use helius_get_wallet_transfers or helius_get_transfers_by_address and take the earliest inbound SOL transfer."
54445
+ },
54446
+ alchemy_simulate_asset_changes_bundle: {
54447
+ reason: ALCHEMY_PAYG,
54448
+ replacement: ALCHEMY_BUNDLE_REPLACEMENT
54449
+ },
54450
+ alchemy_simulate_execution_bundle: {
54451
+ reason: ALCHEMY_PAYG,
54452
+ replacement: ALCHEMY_BUNDLE_REPLACEMENT
54453
+ },
54454
+ defillama_get_derivatives_volumes: {
54455
+ reason: DEFILLAMA_PRO,
54456
+ replacement: DEFILLAMA_DERIVATIVES_REPLACEMENT
54457
+ },
54458
+ defillama_get_derivatives_volumes_by_chain: {
54459
+ reason: DEFILLAMA_PRO,
54460
+ replacement: DEFILLAMA_DERIVATIVES_REPLACEMENT
54461
+ },
54462
+ defillama_get_derivatives_volume: {
54463
+ reason: DEFILLAMA_PRO,
54464
+ replacement: DEFILLAMA_DERIVATIVES_REPLACEMENT
54465
+ },
54466
+ defillama_get_categories: {
54467
+ reason: DEFILLAMA_PRO,
54468
+ replacement: "Use get_categories_market_data for sector data, or get_defi_protocols, whose records carry each protocol's category."
54469
+ },
54470
+ defillama_get_oracles: {
54471
+ reason: DEFILLAMA_PRO,
54472
+ replacement: "Use get_defi_protocols or get_defi_protocol; protocol records list the oracles they use where DeFiLlama has them."
54473
+ },
54474
+ defillama_get_forks: {
54475
+ reason: DEFILLAMA_PRO,
54476
+ replacement: "Use get_defi_protocols; protocol records carry forkedFrom where DeFiLlama has it."
54477
+ },
54478
+ defillama_get_entities: {
54479
+ reason: DEFILLAMA_PRO,
54480
+ replacement: "Use get_entities_list or get_treasury_by_entity for public companies and their treasuries."
54481
+ },
54482
+ ccxt_fetch_cross_borrow_rates: {
54483
+ reason: CCXT_PRIVATE,
54484
+ replacement: CCXT_BORROW_REPLACEMENT
54485
+ },
54486
+ ccxt_fetch_cross_borrow_rate: {
54487
+ reason: CCXT_PRIVATE,
54488
+ replacement: CCXT_BORROW_REPLACEMENT
54489
+ },
54490
+ ccxt_fetch_isolated_borrow_rates: {
54491
+ reason: CCXT_PRIVATE,
54492
+ replacement: CCXT_BORROW_REPLACEMENT
54493
+ },
54494
+ goplus_simulate_solana_transaction: {
54495
+ reason: 'because GoPlus answers "system error" to every Solana pre-execution request, including a fresh valid transfer',
54496
+ replacement: "Use get_solana_token_security for the tokens the transaction touches; Hive has no other Solana pre-signing simulation."
54497
+ }
54498
+ };
54499
+ function isUnservableTool(toolName) {
54500
+ return Object.prototype.hasOwnProperty.call(UNSERVABLE_TOOLS, toolName);
54501
+ }
54502
+ function getRetiredTool(toolName) {
54503
+ if (isUnservableTool(toolName)) {
54504
+ const entry2 = UNSERVABLE_TOOLS[toolName];
54505
+ return {
54506
+ date: UNSERVABLE_TOOLS_DATE,
54507
+ cause: entry2.reason,
54508
+ replacement: entry2.replacement
54509
+ };
54510
+ }
54511
+ const replacement = getRetiredToolReplacement(toolName);
54512
+ return replacement ? {
54513
+ date: RETIRED_TOOLS_DATE,
54514
+ cause: "when the Codex.io provider was removed",
54515
+ replacement
54516
+ } : null;
54517
+ }
54518
+ function getRetiredToolReplacement(toolName) {
54519
+ if (isUnservableTool(toolName)) return UNSERVABLE_TOOLS[toolName].replacement;
54520
+ const direct = RETIRED_TOOL_REPLACEMENTS[toolName];
54521
+ if (direct) return direct;
54522
+ if (/^codex_/.test(toolName)) {
54523
+ return PREDICTION_REPLACEMENT;
54524
+ }
54525
+ return null;
54526
+ }
54527
+
54092
54528
  // src/wrapper/index.ts
54093
54529
  var CHARACTER_LIMIT = 1e5;
54094
54530
  var ANNOTATION_HEADROOM = 1024;
@@ -54479,6 +54915,7 @@ function createSafeHandler(handler96, metadata100, toolName) {
54479
54915
  }
54480
54916
  let result2 = await handler96(effectiveClient, safeArgs);
54481
54917
  const observedAt = (/* @__PURE__ */ new Date()).toISOString();
54918
+ if (result2._hiveExec?.source === "fallback") usedFallback = true;
54482
54919
  if (!result2.isError && credentialRequirement && !credentialRequirement.isConfigured() && result2?.content?.[0]?.type === "text" && result2.content[0].text) {
54483
54920
  const rawText = result2.content[0].text;
54484
54921
  let warningText;
@@ -54805,7 +55242,7 @@ function getAllWrappedEndpoints() {
54805
55242
  }
54806
55243
  }
54807
55244
  }
54808
- _wrappedEndpointsCache = updatedTools.map(normalizeEndpointSchema).map((endpoint) => ({
55245
+ _wrappedEndpointsCache = updatedTools.filter((endpoint) => !isUnservableTool(endpoint.tool.name)).map(normalizeEndpointSchema).map((endpoint) => ({
54809
55246
  ...endpoint,
54810
55247
  tool: withResponseHeadroomMeta(endpoint.tool)
54811
55248
  }));
@@ -54852,11 +55289,6 @@ var ToolRegistry = [
54852
55289
  "get_global_market_cap_chart",
54853
55290
  "get_coin_ohlc",
54854
55291
  "get_coin_ohlc_range",
54855
- "get_coin_insights",
54856
- "get_coin_circulating_supply_chart",
54857
- "get_coin_circulating_supply_chart_range",
54858
- "get_coin_total_supply_chart",
54859
- "get_coin_total_supply_chart_range",
54860
55292
  "get_rwa_list",
54861
55293
  "get_rwa_markets",
54862
55294
  "get_rwa_asset",
@@ -54981,9 +55413,6 @@ var ToolRegistry = [
54981
55413
  "ccxt_fetch_convert_quote",
54982
55414
  "ccxt_fetch_borrow_rate_history",
54983
55415
  "ccxt_fetch_borrow_rate_histories",
54984
- "ccxt_fetch_cross_borrow_rates",
54985
- "ccxt_fetch_cross_borrow_rate",
54986
- "ccxt_fetch_isolated_borrow_rates",
54987
55416
  "ccxt_fetch_funding_rates_multi",
54988
55417
  "ccxt_fetch_open_interest_multi",
54989
55418
  "alchemy_get_token_prices_by_symbol",
@@ -55142,13 +55571,10 @@ var ToolRegistry = [
55142
55571
  "helius_get_parsed_address_transactions",
55143
55572
  "helius_get_parsed_events_transactions",
55144
55573
  "helius_get_parsed_events_transaction_history",
55145
- "helius_get_wallet_identity",
55146
- "helius_get_wallet_batch_identity",
55147
55574
  "helius_get_wallet_balances",
55148
55575
  "helius_get_wallet_balance_at",
55149
55576
  "helius_get_wallet_history",
55150
55577
  "helius_get_wallet_transfers",
55151
- "helius_get_wallet_funded_by",
55152
55578
  "helius_get_transactions_for_address",
55153
55579
  "helius_get_transfers_by_address"
55154
55580
  ]
@@ -55233,13 +55659,6 @@ var ToolRegistry = [
55233
55659
  "defillama_get_open_interest_by_chain",
55234
55660
  "defillama_get_open_interest_protocol",
55235
55661
  // Coverage wave 1: perps-protocol volumes + protocol metadata
55236
- "defillama_get_derivatives_volumes",
55237
- "defillama_get_derivatives_volumes_by_chain",
55238
- "defillama_get_derivatives_volume",
55239
- "defillama_get_categories",
55240
- "defillama_get_oracles",
55241
- "defillama_get_forks",
55242
- "defillama_get_entities",
55243
55662
  // Moralis DeFi / volume analytics
55244
55663
  "moralis_get_defi_positions_by_protocol",
55245
55664
  "moralis_get_supported_defi_protocols",
@@ -55345,7 +55764,6 @@ var ToolRegistry = [
55345
55764
  "goplus_detect_dust_attack",
55346
55765
  "goplus_start_address_scan",
55347
55766
  "goplus_get_address_scan_result",
55348
- "goplus_simulate_solana_transaction",
55349
55767
  "goplus_get_lp_v4_lock",
55350
55768
  "goplus_get_lp_v4_locks",
55351
55769
  "goplus_get_lp_v3_lock",
@@ -55375,9 +55793,7 @@ var ToolRegistry = [
55375
55793
  "tenderly_get_transactions_range",
55376
55794
  "alchemy_get_token_allowance",
55377
55795
  "alchemy_simulate_asset_changes",
55378
- "alchemy_simulate_execution",
55379
- "alchemy_simulate_asset_changes_bundle",
55380
- "alchemy_simulate_execution_bundle"
55796
+ "alchemy_simulate_execution"
55381
55797
  ]
55382
55798
  },
55383
55799
  {
@@ -57087,83 +57503,6 @@ function clientProfileFromName(raw) {
57087
57503
  return normalizeClientName(raw).profile;
57088
57504
  }
57089
57505
 
57090
- // src/config/retiredTools.ts
57091
- var RETIRED_TOOLS_DATE = "2026-09-06";
57092
- var RETIRED_TOOL_REPLACEMENTS = {
57093
- // wallet
57094
- codex_filter_wallets_by_network: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
57095
- codex_get_wallet_aggregate_backfill_state: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
57096
- codex_get_wallet_label_types: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
57097
- filter_network_wallets: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
57098
- filter_token_wallets: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
57099
- filter_wallets: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
57100
- get_wallet_balances: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
57101
- get_wallet_chart: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
57102
- get_wallet_stats: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
57103
- get_wallet_token_events: "Use alchemy_get_token_balances_by_wallet, alchemy_get_asset_transfers, or moralis_get_wallet_profitability_summary for wallet balances, transfers, and PnL.",
57104
- // holders
57105
- get_token_holders: "Use get_token_top_holders for holders on any network, coingecko_get_onchain_token_top_traders for traders where CoinGecko serves them (base and similar; not Ethereum on the current plan), or moralis_get_token_holder_metrics for holder metrics.",
57106
- get_token_top_traders: "Use get_token_top_holders for holders on any network, coingecko_get_onchain_token_top_traders for traders where CoinGecko serves them (base and similar; not Ethereum on the current plan), or moralis_get_token_holder_metrics for holder metrics.",
57107
- get_top_holders_percentage: "Use get_token_top_holders for holders on any network, coingecko_get_onchain_token_top_traders for traders where CoinGecko serves them (base and similar; not Ethereum on the current plan), or moralis_get_token_holder_metrics for holder metrics.",
57108
- // pairs
57109
- codex_get_detailed_token_stats: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
57110
- codex_get_windowed_pair_stats: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
57111
- filter_pairs: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
57112
- get_detailed_stats: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
57113
- get_latest_pairs: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
57114
- get_liquidity_info: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
57115
- get_pair_chart_metadata: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
57116
- get_pair_info: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
57117
- get_pair_stats: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
57118
- get_pairs_stats: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
57119
- get_token_liquidity_metadata: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
57120
- get_token_pairs: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
57121
- get_token_pairs_metadata: "Use get_token_pools, get_pool_info, get_pools_by_address, moralis_get_pair_stats, or get_new_pools for pool and pair data.",
57122
- // charts
57123
- codex_get_bars: "Use get_token_ohlcv, get_pool_ohlcv, or moralis_get_pair_ohlcv for candles.",
57124
- codex_get_token_bars: "Use get_token_ohlcv, get_pool_ohlcv, or moralis_get_pair_ohlcv for candles.",
57125
- get_token_chart_data: "Use get_token_ohlcv, get_pool_ohlcv, or moralis_get_pair_ohlcv for candles.",
57126
- get_token_chart_urls: "Use get_token_ohlcv, get_pool_ohlcv, or moralis_get_pair_ohlcv for candles.",
57127
- get_token_sparklines: "Use get_token_ohlcv, get_pool_ohlcv, or moralis_get_pair_ohlcv for candles.",
57128
- // price
57129
- codex_get_token_price: "Use alchemy_get_token_prices_by_address or get_onchain_token_price for on-chain token prices.",
57130
- // tokens
57131
- codex_filter_launchpads: "Use get_token_info, alchemy_get_token_metadata, moralis_search_tokens, get_new_pools, or get_token_trades for token discovery and activity.",
57132
- filter_tokens: "Use get_token_info, alchemy_get_token_metadata, moralis_search_tokens, get_new_pools, or get_token_trades for token discovery and activity.",
57133
- get_new_tokens: "Use get_token_info, alchemy_get_token_metadata, moralis_search_tokens, get_new_pools, or get_token_trades for token discovery and activity.",
57134
- get_token_details: "Use get_token_info, alchemy_get_token_metadata, moralis_search_tokens, get_new_pools, or get_token_trades for token discovery and activity.",
57135
- get_token_transactions: "Use get_token_info, alchemy_get_token_metadata, moralis_search_tokens, get_new_pools, or get_token_trades for token discovery and activity.",
57136
- get_tokens: "Use get_token_info, alchemy_get_token_metadata, moralis_search_tokens, get_new_pools, or get_token_trades for token discovery and activity.",
57137
- list_top_tokens: "Use get_token_info, alchemy_get_token_metadata, moralis_search_tokens, get_new_pools, or get_token_trades for token discovery and activity.",
57138
- search_tokens: "Use get_token_info, alchemy_get_token_metadata, moralis_search_tokens, get_new_pools, or get_token_trades for token discovery and activity.",
57139
- // network
57140
- codex_get_blocks: "Use get_networks, tenderly_get_supported_networks, alchemy_get_block_by_number, or get_dexes for network and DEX reads.",
57141
- codex_get_network_configs: "Use get_networks, tenderly_get_supported_networks, alchemy_get_block_by_number, or get_dexes for network and DEX reads.",
57142
- filter_exchanges: "Use get_networks, tenderly_get_supported_networks, alchemy_get_block_by_number, or get_dexes for network and DEX reads.",
57143
- filter_networks: "Use get_networks, tenderly_get_supported_networks, alchemy_get_block_by_number, or get_dexes for network and DEX reads.",
57144
- get_network_dexes: "Use get_networks, tenderly_get_supported_networks, alchemy_get_block_by_number, or get_dexes for network and DEX reads.",
57145
- get_network_stats: "Use get_networks, tenderly_get_supported_networks, alchemy_get_block_by_number, or get_dexes for network and DEX reads.",
57146
- get_network_status: "Use get_networks, tenderly_get_supported_networks, alchemy_get_block_by_number, or get_dexes for network and DEX reads.",
57147
- get_networks_list: "Use get_networks, tenderly_get_supported_networks, alchemy_get_block_by_number, or get_dexes for network and DEX reads.",
57148
- // locks
57149
- get_liquidity_locks: "Use get_token_lock_info or the goplus_get_lp_v3_locks and goplus_get_lp_v4_locks security tools for LP locks.",
57150
- // misc
57151
- codex_get_categories: "No direct replacement; use get_categories_market_data or moralis_get_entity_categories for category data.",
57152
- codex_get_category: "No direct replacement; use get_categories_market_data or moralis_get_entity_categories for category data.",
57153
- codex_get_category_tokens: "No direct replacement; use get_categories_market_data or moralis_get_entity_categories for category data.",
57154
- get_community_notes: "No direct replacement; use get_categories_market_data or moralis_get_entity_categories for category data.",
57155
- get_event_labels: "No direct replacement; use get_categories_market_data or moralis_get_entity_categories for category data."
57156
- };
57157
- var PREDICTION_REPLACEMENT = 'Prediction markets are served by first-party Polymarket tools since 1.7.0: polymarket_search_markets, polymarket_get_events, polymarket_get_market, polymarket_get_price_history, polymarket_get_orderbook, polymarket_get_wallet_positions, polymarket_get_wallet_activity. Kalshi is not covered. Start with search_tools({"query": "prediction markets"}) or hive://toolsets/prediction_markets.';
57158
- function getRetiredToolReplacement(toolName) {
57159
- const direct = RETIRED_TOOL_REPLACEMENTS[toolName];
57160
- if (direct) return direct;
57161
- if (/^codex_/.test(toolName)) {
57162
- return PREDICTION_REPLACEMENT;
57163
- }
57164
- return null;
57165
- }
57166
-
57167
57506
  // src/services/tool-execution-pipeline.ts
57168
57507
  function isToolExecutionBilling(value) {
57169
57508
  return typeof value === "object" && value !== null && value.type === "billing";
@@ -57484,9 +57823,10 @@ function unavailableReplacementNote(guidance) {
57484
57823
  ).join(" ");
57485
57824
  }
57486
57825
  function createToolNotFoundResult(toolName, durationMs = 0) {
57487
- const retired = getRetiredToolReplacement(toolName);
57826
+ const retiredTool = getRetiredTool(toolName);
57827
+ const retired = retiredTool?.replacement ?? null;
57488
57828
  const availabilityNote = retired ? unavailableReplacementNote(retired) : "";
57489
- const message = retired ? `Tool '${toolName}' was retired on ${RETIRED_TOOLS_DATE}. ${retired}${availabilityNote}` : `Tool '${toolName}' not found.`;
57829
+ const message = retiredTool ? `Tool '${toolName}' was retired on ${retiredTool.date}. ${retired}${availabilityNote}` : `Tool '${toolName}' not found.`;
57490
57830
  const errorCode = retired ? "TOOL_RETIRED" : "TOOL_NOT_FOUND";
57491
57831
  const mcpResult = createErrorResponse7(errorCode, message);
57492
57832
  const hive = {
@@ -57514,7 +57854,7 @@ function createToolNotFoundResult(toolName, durationMs = 0) {
57514
57854
  warnings: [
57515
57855
  retired ? "Tool name was retired; the replacement is named in the message." : "Tool name did not resolve to a Hive endpoint."
57516
57856
  ],
57517
- cause: retired ? `Tool '${toolName}' was retired on ${RETIRED_TOOLS_DATE} when the Codex.io provider was removed; nothing was executed.` : `Tool '${toolName}' does not resolve to a Hive endpoint; nothing was executed.`,
57857
+ cause: retiredTool ? `Tool '${toolName}' was retired on ${retiredTool.date} ${retiredTool.cause}; nothing was executed.` : `Tool '${toolName}' does not resolve to a Hive endpoint; nothing was executed.`,
57518
57858
  next_action: retired ? `${retired}${availabilityNote} Call search_tools with your task if that tool does not fit.` : "Call search_tools (or a category endpoint tools/list) to find the exact endpoint name, then retry with that name."
57519
57859
  };
57520
57860
  const enrichedMcpResult = attachHiveMetadata(mcpResult, hive);
@@ -59369,7 +59709,7 @@ var TASK_TOOLSET_ROUTES = {
59369
59709
  {
59370
59710
  id: "transaction_readiness",
59371
59711
  label: "Solana transaction readiness",
59372
- trigger: "Solana transaction details, priority fee, compression context, or pre-execution risk.",
59712
+ trigger: "Solana transaction details, priority fee, compression context, or the risk of the tokens it touches.",
59373
59713
  exampleQuestion: "Inspect this Solana transaction and tell me whether the proposed call looks safe.",
59374
59714
  requiredIdentifiers: ["transaction signature or serialized transaction"],
59375
59715
  maxMaterialCalls: 4,
@@ -59389,12 +59729,12 @@ var TASK_TOOLSET_ROUTES = {
59389
59729
  ),
59390
59730
  step(
59391
59731
  "risk",
59392
- "Simulate a serialized transaction without broadcasting.",
59393
- "goplus_simulate_solana_transaction",
59732
+ "Check GoPlus token security for the mints the transaction touches.",
59733
+ "get_solana_token_security",
59394
59734
  null
59395
59735
  )
59396
59736
  ],
59397
- stopCondition: "Stop after transaction context and the requested fee or simulation check; never submit the transaction."
59737
+ stopCondition: "Stop after transaction context and the requested fee or token security check; never submit the transaction."
59398
59738
  }
59399
59739
  ],
59400
59740
  rwa_perp_analysis: [
@@ -59751,10 +60091,8 @@ var TASK_TOOLSET_CATALOG = [
59751
60091
  "hyperliquid_get_outcome_meta",
59752
60092
  "hyperliquid_get_all_borrow_lend_reserve_states",
59753
60093
  "ccxt_fetch_option_chain",
59754
- "ccxt_fetch_cross_borrow_rates",
59755
60094
  "get_exchange_tickers",
59756
- "get_supported_currencies",
59757
- "get_coin_insights"
60095
+ "get_supported_currencies"
59758
60096
  ],
59759
60097
  stableFixtures: [
59760
60098
  {
@@ -59829,11 +60167,7 @@ var TASK_TOOLSET_CATALOG = [
59829
60167
  "get_contract_coin",
59830
60168
  "coingecko_get_onchain_token_top_traders",
59831
60169
  "get_solana_token_security",
59832
- "get_coin_supply_breakdown",
59833
- "get_coin_circulating_supply_chart",
59834
- "get_coin_circulating_supply_chart_range",
59835
- "get_coin_total_supply_chart",
59836
- "get_coin_total_supply_chart_range"
60170
+ "get_coin_supply_breakdown"
59837
60171
  ],
59838
60172
  stableFixtures: [
59839
60173
  {
@@ -59982,10 +60316,7 @@ var TASK_TOOLSET_CATALOG = [
59982
60316
  "alchemy_solana_get_latest_non_voting_signatures",
59983
60317
  "alchemy_simulate_asset_changes",
59984
60318
  "alchemy_simulate_execution",
59985
- "alchemy_simulate_asset_changes_bundle",
59986
- "alchemy_simulate_execution_bundle",
59987
60319
  "simulate_evm_transaction",
59988
- "goplus_simulate_solana_transaction",
59989
60320
  "defillama_get_hacks"
59990
60321
  ],
59991
60322
  fallbackTools: [
@@ -60105,8 +60436,6 @@ var TASK_TOOLSET_CATALOG = [
60105
60436
  "defillama_get_bridge_aggregator_volumes",
60106
60437
  "defillama_get_bridge_aggregator_volumes_by_chain",
60107
60438
  "get_dex_volumes",
60108
- "defillama_get_derivatives_volumes",
60109
- "defillama_get_derivatives_volume",
60110
60439
  "moralis_get_supported_defi_protocols",
60111
60440
  "moralis_get_wallet_defi_positions"
60112
60441
  ],
@@ -60118,12 +60447,7 @@ var TASK_TOOLSET_CATALOG = [
60118
60447
  "get_chains_tvl_history",
60119
60448
  "get_stablecoin_chains",
60120
60449
  "stablecoin_data_by_id",
60121
- "get_fees_overview",
60122
- "defillama_get_derivatives_volumes_by_chain",
60123
- "defillama_get_categories",
60124
- "defillama_get_oracles",
60125
- "defillama_get_forks",
60126
- "defillama_get_entities"
60450
+ "get_fees_overview"
60127
60451
  ],
60128
60452
  stableFixtures: [
60129
60453
  {
@@ -60309,12 +60633,10 @@ var TASK_TOOLSET_CATALOG = [
60309
60633
  "moralis_get_sol_token_prices_batch",
60310
60634
  "moralis_get_token_analytics_timeseries",
60311
60635
  "moralis_get_sol_token_swaps",
60312
- "get_solana_token_security",
60313
- "goplus_simulate_solana_transaction"
60636
+ "get_solana_token_security"
60314
60637
  ],
60315
60638
  fallbackTools: [
60316
60639
  "get_token_top_holders",
60317
- "helius_get_wallet_identity",
60318
60640
  "helius_get_wallet_history",
60319
60641
  "helius_get_program_accounts_v2",
60320
60642
  "helius_get_parsed_transactions",
@@ -62263,7 +62585,6 @@ var HIVE_PROMPTS = [
62263
62585
  ];
62264
62586
 
62265
62587
  // src/services/unkey-service.ts
62266
- import { Unkey } from "@unkey/api";
62267
62588
  import { randomUUID as randomUUID4 } from "crypto";
62268
62589
  var _unkey = null;
62269
62590
  function getAuthBackendMode() {
@@ -62282,14 +62603,17 @@ function hasUnkeyCredentials() {
62282
62603
  function isUnkeyConfigured() {
62283
62604
  return getAuthBackendMode() !== "static" && hasUnkeyCredentials();
62284
62605
  }
62285
- function getUnkey() {
62606
+ async function getUnkey() {
62286
62607
  if (!_unkey) {
62287
62608
  if (!isUnkeyConfigured()) {
62288
62609
  throw new Error(
62289
62610
  "Unkey not configured. Set UNKEY_ROOT_KEY and UNKEY_API_ID."
62290
62611
  );
62291
62612
  }
62292
- _unkey = new Unkey({ rootKey: getRequiredEnvVar("UNKEY_ROOT_KEY") });
62613
+ const { Unkey: UnkeyClient } = await import("@unkey/api");
62614
+ _unkey ??= new UnkeyClient({
62615
+ rootKey: getRequiredEnvVar("UNKEY_ROOT_KEY")
62616
+ });
62293
62617
  }
62294
62618
  return _unkey;
62295
62619
  }
@@ -62322,7 +62646,8 @@ async function listAllUserKeysRaw(userId) {
62322
62646
  const all = [];
62323
62647
  let cursor;
62324
62648
  for (let page = 0; page < KEYS_MAX_PAGES; page += 1) {
62325
- const result2 = await getUnkey().apis.listKeys({
62649
+ const unkey = await getUnkey();
62650
+ const result2 = await unkey.apis.listKeys({
62326
62651
  apiId,
62327
62652
  externalId: userId,
62328
62653
  limit: KEYS_PAGE_LIMIT,
@@ -62396,7 +62721,8 @@ async function createApiKey(opts) {
62396
62721
  subject_signing_secret: subjectSigningSecret
62397
62722
  } : {}
62398
62723
  };
62399
- const result2 = await getUnkey().keys.createKey({
62724
+ const unkey = await getUnkey();
62725
+ const result2 = await unkey.keys.createKey({
62400
62726
  apiId: getApiId(),
62401
62727
  prefix: "hive_live",
62402
62728
  name: opts.name,
@@ -62429,7 +62755,8 @@ async function createApiKey(opts) {
62429
62755
  }
62430
62756
  async function verifyApiKey(rawKey, analyticsTags = []) {
62431
62757
  const tags = normalizeAnalyticsTags(analyticsTags);
62432
- const result2 = await getUnkey().keys.verifyKey({
62758
+ const unkey = await getUnkey();
62759
+ const result2 = await unkey.keys.verifyKey({
62433
62760
  key: rawKey,
62434
62761
  ...tags.length > 0 ? { tags } : {},
62435
62762
  ratelimits: [
@@ -62474,7 +62801,8 @@ async function listKeys(userId) {
62474
62801
  }));
62475
62802
  }
62476
62803
  async function revokeKey(keyId) {
62477
- await getUnkey().keys.updateKey({
62804
+ const unkey = await getUnkey();
62805
+ await unkey.keys.updateKey({
62478
62806
  keyId,
62479
62807
  enabled: false
62480
62808
  });
@@ -64701,7 +65029,11 @@ var GoPlusClient = class {
64701
65029
  };
64702
65030
 
64703
65031
  // src/tools/ccxt/ccxtClient.ts
64704
- import ccxt from "ccxt";
65032
+ var ccxtModule;
65033
+ function loadCcxt() {
65034
+ ccxtModule ??= import("ccxt").then((mod) => mod.default);
65035
+ return ccxtModule;
65036
+ }
64705
65037
  var GEO_BLOCKED_CODES = /* @__PURE__ */ new Set([451, 403]);
64706
65038
  var PUBLIC_BORROW_HISTORY_METHODS = /* @__PURE__ */ new Set([
64707
65039
  "fetchBorrowRateHistory",
@@ -64738,10 +65070,11 @@ var CCXTClient = class {
64738
65070
  *
64739
65071
  * @internal
64740
65072
  */
64741
- getExchange(exchangeId, options = {}) {
65073
+ async getExchange(exchangeId, options = {}) {
64742
65074
  if (!exchangeId || exchangeId.trim().length === 0) {
64743
65075
  throw new Error("Exchange ID is required");
64744
65076
  }
65077
+ const ccxt = await loadCcxt();
64745
65078
  const cacheKey2 = `${exchangeId}`;
64746
65079
  if (this.exchanges.has(cacheKey2)) {
64747
65080
  return this.exchanges.get(cacheKey2);
@@ -64973,7 +65306,7 @@ var CCXTClient = class {
64973
65306
  `${method} is only exposed for the public OKX borrow-history API (exchange: okx, myokx, or okxus). Hive does not accept exchange account credentials for private margin endpoints.`
64974
65307
  );
64975
65308
  }
64976
- const exchange = this.getExchange(exchangeId);
65309
+ const exchange = await this.getExchange(exchangeId);
64977
65310
  let result2;
64978
65311
  const hasCapability = exchange.has;
64979
65312
  if (hasCapability && hasCapability[method] !== true && hasCapability[method] !== "emulated") {
@@ -65357,7 +65690,7 @@ var CCXTClient = class {
65357
65690
  return result2;
65358
65691
  } catch (error) {
65359
65692
  try {
65360
- const exchange = this.getExchange(exchangeId);
65693
+ const exchange = await this.getExchange(exchangeId);
65361
65694
  const fallback = await this._tryPublicFallback(
65362
65695
  method,
65363
65696
  exchange,
@@ -65619,8 +65952,9 @@ var FULL_MODE_DEFAULT_ARGS = {
65619
65952
  user: HYPERLIQUID_USER,
65620
65953
  builder: HYPERLIQUID_USER,
65621
65954
  vault_address: HYPERLIQUID_HLP_VAULT,
65622
- // Spot token index 0 (USDC) — canonical 34-char zero tokenId.
65623
- token_id: "0x00000000000000000000000000000000",
65955
+ // USDC's real tokenId (spotMeta tokens[0]); the all-zero id is unknown to
65956
+ // Hyperliquid and answers 500.
65957
+ token_id: "0x6d1e7cde53ba9467b783cb7c530ce054",
65624
65958
  token: 0,
65625
65959
  // First HIP-4 outcome market id.
65626
65960
  outcome: 0
@@ -66124,9 +66458,11 @@ var TOOL_PROBE_ARGS = {
66124
66458
  network: "mainnet",
66125
66459
  input: `${ERC20_TRANSFER_SELECTOR}${"0".repeat(128)}`
66126
66460
  },
66461
+ // A plain zero-value transfer between EOAs: a call into USDC with empty
66462
+ // calldata reverts, and estimateGas reports a revert as an error.
66127
66463
  tenderly_node_estimate_gas: {
66128
66464
  network: "mainnet",
66129
- transaction: { from: ETH_WALLET, to: ETH_USDC, data: "0x" },
66465
+ transaction: { from: ETH_WALLET, to: MORALIS_EVM_WALLET, value: "0x0" },
66130
66466
  block_number: "latest"
66131
66467
  },
66132
66468
  tenderly_node_simulate_transaction: {
@@ -66149,10 +66485,16 @@ var TOOL_PROBE_ARGS = {
66149
66485
  network: "mainnet",
66150
66486
  data: "0x08c379a0"
66151
66487
  },
66488
+ // A complete ERC-20 Transfer log (from, to indexed; amount in data). The
66489
+ // signature topic alone with empty data is rejected as bad input.
66152
66490
  tenderly_decode_event: {
66153
66491
  network: "mainnet",
66154
- topics: [ERC20_TRANSFER_TOPIC],
66155
- data: "0x"
66492
+ topics: [
66493
+ ERC20_TRANSFER_TOPIC,
66494
+ "0x000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045",
66495
+ "0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
66496
+ ],
66497
+ data: "0x00000000000000000000000000000000000000000000000000000000000f4240"
66156
66498
  },
66157
66499
  tenderly_get_error_signatures: {
66158
66500
  network: "mainnet",
@@ -66445,9 +66787,10 @@ var TOOL_PROBE_ARGS = {
66445
66787
  page: 1,
66446
66788
  limit: 1
66447
66789
  },
66790
+ // DAS asset signatures are defined for compressed assets.
66448
66791
  alchemy_solana_get_asset_signatures: {
66449
66792
  network: "solana-mainnet",
66450
- id: SOL_HELIUS_ASSET,
66793
+ id: SOL_COMPRESSED_ASSET,
66451
66794
  page: 1,
66452
66795
  limit: 1
66453
66796
  },
@@ -66924,6 +67267,32 @@ function extractGoPlusAddressScanArgs(response) {
66924
67267
  );
66925
67268
  return requestId ? { request_id: requestId } : null;
66926
67269
  }
67270
+ function findFirstObjectWithKey(value, keys) {
67271
+ if (!value || typeof value !== "object") return null;
67272
+ if (Array.isArray(value)) {
67273
+ for (const item of value) {
67274
+ const found = findFirstObjectWithKey(item, keys);
67275
+ if (found) return found;
67276
+ }
67277
+ return null;
67278
+ }
67279
+ const obj = value;
67280
+ if (keys.some((key) => typeof obj[key] === "string")) return obj;
67281
+ for (const child of Object.values(obj)) {
67282
+ const found = findFirstObjectWithKey(child, keys);
67283
+ if (found) return found;
67284
+ }
67285
+ return null;
67286
+ }
67287
+ function firstString(value, keys) {
67288
+ const obj = findFirstObjectWithKey(value, keys);
67289
+ if (!obj) return void 0;
67290
+ for (const key of keys) {
67291
+ const candidate = obj[key];
67292
+ if (typeof candidate === "string" && candidate) return candidate;
67293
+ }
67294
+ return void 0;
67295
+ }
66927
67296
  function getCachedDynamicArgs(cacheKey2, resolver) {
66928
67297
  const cached = dynamicProbeArgCache.get(cacheKey2);
66929
67298
  if (cached) return cached;
@@ -66985,6 +67354,29 @@ async function getCcxtSettlementArgs(clients) {
66985
67354
  return { exchange: "okx", symbol, limit: 10 };
66986
67355
  });
66987
67356
  }
67357
+ var HIVE_FIXTURE_MISSING = "No Hive fixture";
67358
+ var HIVE_ID_FIXTURES = {
67359
+ hive_get_monitor: {
67360
+ listTool: "hive_list_monitors",
67361
+ field: "monitor_id",
67362
+ keys: ["monitor_id", "id"]
67363
+ },
67364
+ hive_get_latest_snapshot: {
67365
+ listTool: "hive_list_monitors",
67366
+ field: "monitor_id",
67367
+ keys: ["monitor_id", "id"]
67368
+ },
67369
+ hive_generate_monitor_report: {
67370
+ listTool: "hive_list_monitors",
67371
+ field: "monitor_id",
67372
+ keys: ["monitor_id", "id"]
67373
+ },
67374
+ hive_get_subject: {
67375
+ listTool: "hive_list_subjects",
67376
+ field: "subject_id",
67377
+ keys: ["subject_id", "id"]
67378
+ }
67379
+ };
66988
67380
  async function getEffectiveProbeArgs(toolName, provider, clients, args) {
66989
67381
  if (args) return args;
66990
67382
  if (toolName === "ccxt_fetch_option" || toolName === "ccxt_fetch_greeks") {
@@ -67021,7 +67413,28 @@ async function getEffectiveProbeArgs(toolName, provider, clients, args) {
67021
67413
  return fixture;
67022
67414
  }
67023
67415
  if (provider === "hive") {
67024
- return {};
67416
+ const idFixture = HIVE_ID_FIXTURES[toolName];
67417
+ if (!idFixture) return {};
67418
+ return getCachedDynamicArgs(`hive:${idFixture.listTool}`, async () => {
67419
+ const listEndpoint = getAllWrappedEndpoints().find(
67420
+ (endpoint) => endpoint.tool.name === idFixture.listTool
67421
+ );
67422
+ if (!listEndpoint) {
67423
+ throw new Error(`${HIVE_FIXTURE_MISSING}: ${idFixture.listTool} is not registered`);
67424
+ }
67425
+ const context = await getHiveCanarySubjectContext();
67426
+ const listed = await runWithSubjectContext(
67427
+ context,
67428
+ () => listEndpoint.handler(null, { limit: 1 })
67429
+ );
67430
+ const id = firstString(parseToolResponseJson(listed), idFixture.keys);
67431
+ if (!id) {
67432
+ throw new Error(
67433
+ `${HIVE_FIXTURE_MISSING}: the canary subject has no ${idFixture.field.replace("_id", "")} to read yet`
67434
+ );
67435
+ }
67436
+ return { [idFixture.field]: id };
67437
+ });
67025
67438
  }
67026
67439
  const toolFixture = TOOL_PROBE_ARGS[toolName];
67027
67440
  if (toolFixture) return toolFixture;
@@ -67118,6 +67531,14 @@ async function runEndpointProbe(endpoint, provider, clients, args, timeoutMs = P
67118
67531
  return { name: toolName, status: "passed", duration };
67119
67532
  } catch (err) {
67120
67533
  const errorMsg = err instanceof Error ? err.message : "Unknown error";
67534
+ if (errorMsg.startsWith(HIVE_FIXTURE_MISSING)) {
67535
+ return {
67536
+ name: toolName,
67537
+ status: "skipped",
67538
+ duration: Date.now() - start,
67539
+ error: errorMsg
67540
+ };
67541
+ }
67121
67542
  if (shouldRetryGoPlusRateLimit(provider, errorMsg, attempt, maxAttempts)) {
67122
67543
  await delay(GOPLUS_RATE_LIMIT_RETRY_DELAY_MS * attempt);
67123
67544
  continue;
@@ -70025,7 +70446,7 @@ function dynamicTools(endpoints, options = {}) {
70025
70446
  tool: {
70026
70447
  name: "get_api_endpoint_schema",
70027
70448
  title: "API Endpoint Schema",
70028
- description: "Returns the full input schema, operation type, and correct root invoker for any Hive tool by name. Call a category tool first to discover available tool names, then inspect this contract before execution.",
70449
+ description: "Returns the full input schema, operation type, and correct root invoker for any Hive tool by name. Tool names come from search_tools; inspect this contract before execution.",
70029
70450
  inputSchema: {
70030
70451
  ...zodToInputSchema2(getEndpointSchema),
70031
70452
  additionalProperties: true
@@ -70034,18 +70455,13 @@ function dynamicTools(endpoints, options = {}) {
70034
70455
  annotations: READ_ONLY_ANNOTATIONS
70035
70456
  },
70036
70457
  handler: async (_client, args) => {
70037
- if (!args) {
70038
- return errorResult6(
70039
- "No endpoint provided. Pass an 'endpoint' (or 'endpoint_name') parameter with the tool name."
70040
- );
70041
- }
70042
- const parsedEndpointArgs = getEndpointSchema.parse(args);
70458
+ const missingEndpoint = "Invalid arguments: no endpoint provided. Pass an 'endpoint' (or 'endpoint_name') parameter with one tool name as a string.";
70459
+ if (!args) return errorResult6(missingEndpoint);
70460
+ const parsedArgs = getEndpointSchema.safeParse(args);
70461
+ if (!parsedArgs.success) return errorResult6(missingEndpoint);
70462
+ const parsedEndpointArgs = parsedArgs.data;
70043
70463
  const requestedEndpoint = parsedEndpointArgs.endpoint ?? parsedEndpointArgs.endpoint_name ?? firstStringArg(args, ENDPOINT_NAME_ALIASES);
70044
- if (!requestedEndpoint) {
70045
- return errorResult6(
70046
- "No endpoint provided. Pass an 'endpoint' (or 'endpoint_name') parameter with the tool name."
70047
- );
70048
- }
70464
+ if (!requestedEndpoint) return errorResult6(missingEndpoint);
70049
70465
  const lookup = resolveEndpoint(endpoints, requestedEndpoint);
70050
70466
  const metaEndpoint = lookup.ok ? void 0 : [
70051
70467
  searchToolsTool,