@t2000/engine 0.46.5 → 0.46.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +14 -1
- package/dist/index.js +189 -27
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1644,12 +1644,23 @@ declare const healthCheckTool: Tool<{}, {
|
|
|
1644
1644
|
status: string;
|
|
1645
1645
|
}>;
|
|
1646
1646
|
|
|
1647
|
-
|
|
1647
|
+
type RateMap = Record<string, {
|
|
1648
|
+
saveApy: number;
|
|
1649
|
+
borrowApy: number;
|
|
1650
|
+
}>;
|
|
1651
|
+
declare const ratesInfoTool: Tool<{
|
|
1652
|
+
assets?: string[] | undefined;
|
|
1653
|
+
stableOnly?: boolean | undefined;
|
|
1654
|
+
topN?: number | undefined;
|
|
1655
|
+
}, RateMap>;
|
|
1648
1656
|
|
|
1649
1657
|
declare const transactionHistoryTool: Tool<{
|
|
1650
1658
|
action?: "send" | "swap" | "transaction" | "lending" | undefined;
|
|
1651
1659
|
date?: string | undefined;
|
|
1660
|
+
direction?: "out" | "in" | undefined;
|
|
1652
1661
|
limit?: number | undefined;
|
|
1662
|
+
minUsd?: number | undefined;
|
|
1663
|
+
assetSymbol?: string | undefined;
|
|
1653
1664
|
}, Record<string, unknown>>;
|
|
1654
1665
|
|
|
1655
1666
|
declare const saveDepositTool: Tool<{
|
|
@@ -1743,6 +1754,7 @@ declare const payApiTool: Tool<{
|
|
|
1743
1754
|
declare const mppServicesTool: Tool<{
|
|
1744
1755
|
query?: string | undefined;
|
|
1745
1756
|
category?: string | undefined;
|
|
1757
|
+
mode?: "summary" | "full" | undefined;
|
|
1746
1758
|
}, Record<string, unknown>>;
|
|
1747
1759
|
|
|
1748
1760
|
declare const swapExecuteTool: Tool<{
|
|
@@ -1930,6 +1942,7 @@ declare const activitySummaryTool: Tool<{
|
|
|
1930
1942
|
}, ActivitySummary>;
|
|
1931
1943
|
|
|
1932
1944
|
declare const defillamaYieldPoolsTool: Tool<{
|
|
1945
|
+
stableOnly?: boolean | undefined;
|
|
1933
1946
|
limit?: number | undefined;
|
|
1934
1947
|
chain?: string | undefined;
|
|
1935
1948
|
project?: string | undefined;
|
package/dist/index.js
CHANGED
|
@@ -977,6 +977,36 @@ var healthCheckTool = buildTool({
|
|
|
977
977
|
}
|
|
978
978
|
});
|
|
979
979
|
var YIELDS_API = "https://yields.llama.fi";
|
|
980
|
+
var STABLECOIN_SYMBOLS2 = /* @__PURE__ */ new Set([
|
|
981
|
+
"usdc",
|
|
982
|
+
"wusdc",
|
|
983
|
+
"usdt",
|
|
984
|
+
"wusdt",
|
|
985
|
+
"suiusdt",
|
|
986
|
+
"usdy",
|
|
987
|
+
"usdsui",
|
|
988
|
+
"usde",
|
|
989
|
+
"ausd",
|
|
990
|
+
"fdusd",
|
|
991
|
+
"buck"
|
|
992
|
+
]);
|
|
993
|
+
function isStable(symbol) {
|
|
994
|
+
return STABLECOIN_SYMBOLS2.has(symbol.toLowerCase());
|
|
995
|
+
}
|
|
996
|
+
function applyFilters(rates, opts) {
|
|
997
|
+
let entries = Object.entries(rates);
|
|
998
|
+
if (opts.assets && opts.assets.length) {
|
|
999
|
+
const wanted = new Set(opts.assets.map((a) => a.toLowerCase()));
|
|
1000
|
+
entries = entries.filter(([sym]) => wanted.has(sym.toLowerCase()));
|
|
1001
|
+
} else if (opts.stableOnly) {
|
|
1002
|
+
entries = entries.filter(([sym]) => isStable(sym));
|
|
1003
|
+
}
|
|
1004
|
+
entries.sort(([, a], [, b]) => b.saveApy - a.saveApy);
|
|
1005
|
+
if (opts.topN && opts.topN > 0) {
|
|
1006
|
+
entries = entries.slice(0, opts.topN);
|
|
1007
|
+
}
|
|
1008
|
+
return Object.fromEntries(entries);
|
|
1009
|
+
}
|
|
980
1010
|
function formatRatesSummary(rates) {
|
|
981
1011
|
return Object.entries(rates).map(([asset, r]) => `${asset}: Save ${(r.saveApy * 100).toFixed(2)}% / Borrow ${(r.borrowApy * 100).toFixed(2)}%`).join(", ");
|
|
982
1012
|
}
|
|
@@ -997,22 +1027,52 @@ async function fetchRatesFromDefiLlama() {
|
|
|
997
1027
|
}
|
|
998
1028
|
var ratesInfoTool = buildTool({
|
|
999
1029
|
name: "rates_info",
|
|
1000
|
-
description:
|
|
1001
|
-
inputSchema: z.object({
|
|
1002
|
-
|
|
1030
|
+
description: 'NAVI Protocol lending markets ONLY (single-sided save/borrow, no impermanent-loss risk). Use this for stablecoin and bluechip lending yields. Renders a rich rates card. Filter args: `assets` (specific symbols like ["USDC"]), `stableOnly` (true to show only USD-pegged assets), `topN` (max rows in card, default 8, max 50). Do NOT call defillama_yield_pools in the same turn \u2014 that tool is for LP/farming pools with IL risk, not lending.',
|
|
1031
|
+
inputSchema: z.object({
|
|
1032
|
+
assets: z.array(z.string()).optional().describe('Filter to specific asset symbols (e.g. ["USDC"], ["USDC","USDT","USDSUI"]). Case-insensitive.'),
|
|
1033
|
+
stableOnly: z.boolean().optional().describe("When true, return only stablecoin markets (USDC, USDT, USDSUI, USDY, suiUSDT, etc.). Ignored when `assets` is supplied."),
|
|
1034
|
+
topN: z.number().int().min(1).max(50).optional().describe("Cap the number of rows in the card (default 8). Use 50 to render the full NAVI catalog.")
|
|
1035
|
+
}),
|
|
1036
|
+
jsonSchema: {
|
|
1037
|
+
type: "object",
|
|
1038
|
+
properties: {
|
|
1039
|
+
assets: {
|
|
1040
|
+
type: "array",
|
|
1041
|
+
items: { type: "string" },
|
|
1042
|
+
description: "Filter to specific asset symbols (case-insensitive)."
|
|
1043
|
+
},
|
|
1044
|
+
stableOnly: {
|
|
1045
|
+
type: "boolean",
|
|
1046
|
+
description: "When true, return only stablecoin markets. Ignored when `assets` is supplied."
|
|
1047
|
+
},
|
|
1048
|
+
topN: {
|
|
1049
|
+
type: "number",
|
|
1050
|
+
description: "Cap the number of rows in the card (default 8, max 50)."
|
|
1051
|
+
}
|
|
1052
|
+
},
|
|
1053
|
+
required: []
|
|
1054
|
+
},
|
|
1003
1055
|
isReadOnly: true,
|
|
1004
|
-
async call(
|
|
1056
|
+
async call(input, context) {
|
|
1057
|
+
const opts = {
|
|
1058
|
+
assets: input.assets,
|
|
1059
|
+
stableOnly: input.stableOnly,
|
|
1060
|
+
topN: input.topN ?? 8
|
|
1061
|
+
};
|
|
1005
1062
|
if (hasNaviMcpGlobal(context)) {
|
|
1006
|
-
const
|
|
1007
|
-
|
|
1063
|
+
const all2 = await fetchRates(getMcpManager(context));
|
|
1064
|
+
const filtered2 = applyFilters(all2, opts);
|
|
1065
|
+
return { data: filtered2, displayText: formatRatesSummary(filtered2) };
|
|
1008
1066
|
}
|
|
1009
1067
|
if (hasAgent(context)) {
|
|
1010
1068
|
const agent = requireAgent(context);
|
|
1011
|
-
const
|
|
1012
|
-
|
|
1069
|
+
const all2 = await agent.rates();
|
|
1070
|
+
const filtered2 = applyFilters(all2, opts);
|
|
1071
|
+
return { data: filtered2, displayText: formatRatesSummary(filtered2) };
|
|
1013
1072
|
}
|
|
1014
|
-
const
|
|
1015
|
-
|
|
1073
|
+
const all = await fetchRatesFromDefiLlama();
|
|
1074
|
+
const filtered = applyFilters(all, opts);
|
|
1075
|
+
return { data: filtered, displayText: formatRatesSummary(filtered) };
|
|
1016
1076
|
}
|
|
1017
1077
|
});
|
|
1018
1078
|
function parseRpcTx(tx, address) {
|
|
@@ -1114,11 +1174,14 @@ var HISTORY_ACTIONS = ["send", "lending", "swap", "transaction"];
|
|
|
1114
1174
|
var DEFAULT_LOOKBACK_DAYS = 30;
|
|
1115
1175
|
var transactionHistoryTool = buildTool({
|
|
1116
1176
|
name: "transaction_history",
|
|
1117
|
-
description:
|
|
1177
|
+
description: 'Retrieve recent transaction history (last 30 days by default): sends, saves, withdrawals, borrows, repayments, swaps, and rewards claims. Renders a rich transaction card. Filter args: `date` (YYYY-MM-DD), `action` (send/lending/swap), `minUsd` (minimum amount in USD \u2014 use this for "transactions over $X" instead of post-filtering), `assetSymbol` (e.g. "USDC", "SUI"), `direction` ("in" or "out"). The card itself respects all filters \u2014 never re-list the rows in narration.',
|
|
1118
1178
|
inputSchema: z.object({
|
|
1119
1179
|
limit: z.number().int().min(1).max(50).optional(),
|
|
1120
1180
|
date: z.string().optional().describe("Specific date to search for transactions (YYYY-MM-DD format). Paginates back to find that day."),
|
|
1121
|
-
action: z.enum(HISTORY_ACTIONS).optional().describe("Filter by action: send, lending, swap, or transaction.")
|
|
1181
|
+
action: z.enum(HISTORY_ACTIONS).optional().describe("Filter by action: send, lending, swap, or transaction."),
|
|
1182
|
+
minUsd: z.number().min(0).optional().describe('Minimum transaction amount in USD. Use this for "transactions over $X" \u2014 the amount is converted to USD using the asset price snapshot.'),
|
|
1183
|
+
assetSymbol: z.string().optional().describe('Filter to a single asset symbol (case-insensitive, e.g. "USDC", "SUI", "LOFI"). Matches `tx.asset` exactly.'),
|
|
1184
|
+
direction: z.enum(["in", "out"]).optional().describe('Filter by user-side balance flow: "in" = received, "out" = spent.')
|
|
1122
1185
|
}),
|
|
1123
1186
|
jsonSchema: {
|
|
1124
1187
|
type: "object",
|
|
@@ -1135,6 +1198,19 @@ var transactionHistoryTool = buildTool({
|
|
|
1135
1198
|
type: "string",
|
|
1136
1199
|
enum: [...HISTORY_ACTIONS],
|
|
1137
1200
|
description: "Filter results by action category: send, lending, swap, or transaction."
|
|
1201
|
+
},
|
|
1202
|
+
minUsd: {
|
|
1203
|
+
type: "number",
|
|
1204
|
+
description: 'Minimum transaction amount in USD. Use this for "transactions over $X" queries.'
|
|
1205
|
+
},
|
|
1206
|
+
assetSymbol: {
|
|
1207
|
+
type: "string",
|
|
1208
|
+
description: 'Filter to a single asset symbol (case-insensitive, e.g. "USDC", "SUI").'
|
|
1209
|
+
},
|
|
1210
|
+
direction: {
|
|
1211
|
+
type: "string",
|
|
1212
|
+
enum: ["in", "out"],
|
|
1213
|
+
description: 'Filter by direction of user balance change: "in" = received, "out" = spent.'
|
|
1138
1214
|
}
|
|
1139
1215
|
}
|
|
1140
1216
|
},
|
|
@@ -1183,17 +1259,48 @@ var transactionHistoryTool = buildTool({
|
|
|
1183
1259
|
async call(input, context) {
|
|
1184
1260
|
const limit = input.limit ?? 10;
|
|
1185
1261
|
const action = input.action;
|
|
1262
|
+
const assetSymbol = input.assetSymbol?.toLowerCase();
|
|
1263
|
+
const direction = input.direction;
|
|
1264
|
+
const minUsd = input.minUsd;
|
|
1265
|
+
const prices = context.tokenPrices;
|
|
1266
|
+
const priceFor = (sym) => {
|
|
1267
|
+
if (!sym || !prices) return void 0;
|
|
1268
|
+
return prices[sym.toUpperCase()] ?? prices[sym.toLowerCase()] ?? prices[sym];
|
|
1269
|
+
};
|
|
1186
1270
|
const finalize = (records2) => {
|
|
1187
1271
|
let scoped = records2;
|
|
1188
1272
|
if (action) scoped = scoped.filter((r) => r.action === action);
|
|
1273
|
+
if (assetSymbol) {
|
|
1274
|
+
scoped = scoped.filter((r) => r.asset?.toLowerCase() === assetSymbol);
|
|
1275
|
+
}
|
|
1276
|
+
if (direction) {
|
|
1277
|
+
scoped = scoped.filter((r) => r.direction === direction);
|
|
1278
|
+
}
|
|
1279
|
+
if (minUsd != null && minUsd > 0) {
|
|
1280
|
+
scoped = scoped.filter((r) => {
|
|
1281
|
+
if (r.amount == null) return false;
|
|
1282
|
+
const sym = r.asset?.toUpperCase() ?? "";
|
|
1283
|
+
const isStableLike = sym === "USDC" || sym === "USDT" || sym === "WUSDC" || sym === "WUSDT" || sym === "SUIUSDT" || sym === "USDY" || sym === "USDSUI" || sym === "USDE" || sym === "AUSD" || sym === "FDUSD" || sym === "BUCK";
|
|
1284
|
+
const usd = isStableLike ? r.amount : (priceFor(sym) ?? 0) * r.amount;
|
|
1285
|
+
if (!isStableLike && priceFor(sym) == null) return true;
|
|
1286
|
+
return usd >= minUsd;
|
|
1287
|
+
});
|
|
1288
|
+
}
|
|
1189
1289
|
return scoped.slice(0, limit);
|
|
1190
1290
|
};
|
|
1291
|
+
const filterMeta = {
|
|
1292
|
+
date: input.date ?? null,
|
|
1293
|
+
action: action ?? null,
|
|
1294
|
+
minUsd: minUsd ?? null,
|
|
1295
|
+
assetSymbol: input.assetSymbol ?? null,
|
|
1296
|
+
direction: direction ?? null
|
|
1297
|
+
};
|
|
1191
1298
|
if (context.agent) {
|
|
1192
1299
|
const agent = requireAgent(context);
|
|
1193
1300
|
const records2 = await agent.history({ limit: input.date ? limit : Math.max(limit * 4, 50) });
|
|
1194
1301
|
const filtered2 = finalize(records2);
|
|
1195
1302
|
return {
|
|
1196
|
-
data: { transactions: filtered2, count: filtered2.length,
|
|
1303
|
+
data: { transactions: filtered2, count: filtered2.length, ...filterMeta },
|
|
1197
1304
|
displayText: `${filtered2.length} recent transaction(s)`
|
|
1198
1305
|
};
|
|
1199
1306
|
}
|
|
@@ -1210,7 +1317,7 @@ var transactionHistoryTool = buildTool({
|
|
|
1210
1317
|
const filtered2 = finalize(records2);
|
|
1211
1318
|
const dateLabel = new Date(input.date).toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" });
|
|
1212
1319
|
return {
|
|
1213
|
-
data: { transactions: filtered2, count: filtered2.length,
|
|
1320
|
+
data: { transactions: filtered2, count: filtered2.length, ...filterMeta },
|
|
1214
1321
|
displayText: filtered2.length > 0 ? `${filtered2.length} transaction(s) on ${dateLabel}` : `No transactions found on ${dateLabel}`
|
|
1215
1322
|
};
|
|
1216
1323
|
}
|
|
@@ -1226,8 +1333,7 @@ var transactionHistoryTool = buildTool({
|
|
|
1226
1333
|
data: {
|
|
1227
1334
|
transactions: filtered,
|
|
1228
1335
|
count: filtered.length,
|
|
1229
|
-
|
|
1230
|
-
action: action ?? null,
|
|
1336
|
+
...filterMeta,
|
|
1231
1337
|
lookbackDays: DEFAULT_LOOKBACK_DAYS
|
|
1232
1338
|
},
|
|
1233
1339
|
displayText: `${filtered.length} transaction(s) in the last ${DEFAULT_LOOKBACK_DAYS} days`
|
|
@@ -1610,10 +1716,11 @@ function matchesQuery(service, q) {
|
|
|
1610
1716
|
}
|
|
1611
1717
|
var mppServicesTool = buildTool({
|
|
1612
1718
|
name: "mpp_services",
|
|
1613
|
-
description:
|
|
1719
|
+
description: 'Discover available MPP gateway services. Returns service names, descriptions, endpoints with required parameters, and pricing. Use BEFORE calling pay_api. Modes: pass `query` for keyword search, `category` to filter by category, or `mode: "full"` to fetch the ENTIRE catalog in one card (for "show me all MPP services" / "full catalog" requests \u2014 never enumerate per category in a loop). Calling with no args returns a category summary so you can narrow.',
|
|
1614
1720
|
inputSchema: z.object({
|
|
1615
1721
|
query: z.string().optional().describe('Filter by keyword (e.g. "postcard", "translate", "weather").'),
|
|
1616
|
-
category: z.string().optional().describe('Filter by category exactly (e.g. "weather", "image"). See category summary returned when called without filters.')
|
|
1722
|
+
category: z.string().optional().describe('Filter by category exactly (e.g. "weather", "image"). See category summary returned when called without filters.'),
|
|
1723
|
+
mode: z.enum(["summary", "full"]).optional().describe('"full" returns the entire catalog in a single card \u2014 use this for "show me all MPP services" / "full catalog" requests instead of looping per category. Default is "summary" (category counts only when no filter is supplied).')
|
|
1617
1724
|
}),
|
|
1618
1725
|
jsonSchema: {
|
|
1619
1726
|
type: "object",
|
|
@@ -1625,14 +1732,40 @@ var mppServicesTool = buildTool({
|
|
|
1625
1732
|
category: {
|
|
1626
1733
|
type: "string",
|
|
1627
1734
|
description: 'Filter by category exactly (e.g. "weather", "image").'
|
|
1735
|
+
},
|
|
1736
|
+
mode: {
|
|
1737
|
+
type: "string",
|
|
1738
|
+
enum: ["summary", "full"],
|
|
1739
|
+
description: '"full" returns the entire catalog in one card. Use for "show me all" requests.'
|
|
1628
1740
|
}
|
|
1629
1741
|
},
|
|
1630
1742
|
required: []
|
|
1631
1743
|
},
|
|
1632
1744
|
isReadOnly: true,
|
|
1633
|
-
|
|
1745
|
+
// [v0.46.6] Bumped to fit the full catalog (~40 services) in one
|
|
1746
|
+
// shot when `mode: 'full'` is used. The summarizeOnTruncate path
|
|
1747
|
+
// still applies if the catalog ever exceeds the budget.
|
|
1748
|
+
maxResultSizeChars: 12e3,
|
|
1634
1749
|
async call(input) {
|
|
1635
1750
|
const catalog = await fetchCatalog();
|
|
1751
|
+
if (input.mode === "full") {
|
|
1752
|
+
const services2 = catalog.map((s) => ({
|
|
1753
|
+
id: s.id,
|
|
1754
|
+
name: s.name,
|
|
1755
|
+
description: s.description,
|
|
1756
|
+
categories: s.categories,
|
|
1757
|
+
endpoints: s.endpoints.map((e) => ({
|
|
1758
|
+
url: `${MPP_GATEWAY2}/${s.id}${e.path}`,
|
|
1759
|
+
method: e.method,
|
|
1760
|
+
description: e.description,
|
|
1761
|
+
price: `$${e.price}`
|
|
1762
|
+
}))
|
|
1763
|
+
}));
|
|
1764
|
+
return {
|
|
1765
|
+
data: { services: services2, total: services2.length, mode: "full" },
|
|
1766
|
+
displayText: `Full MPP catalog: ${services2.length} services.`
|
|
1767
|
+
};
|
|
1768
|
+
}
|
|
1636
1769
|
if (!input.query && !input.category) {
|
|
1637
1770
|
const counts = /* @__PURE__ */ new Map();
|
|
1638
1771
|
for (const svc of catalog) {
|
|
@@ -1644,13 +1777,14 @@ var mppServicesTool = buildTool({
|
|
|
1644
1777
|
return {
|
|
1645
1778
|
data: {
|
|
1646
1779
|
_refine: {
|
|
1647
|
-
reason:
|
|
1648
|
-
suggestedParams: { category: categories[0]?.category ?? "weather" }
|
|
1780
|
+
reason: 'MPP catalog has many services \u2014 pick a category, supply a query, or pass mode:"full" to fetch everything.',
|
|
1781
|
+
suggestedParams: { category: categories[0]?.category ?? "weather" },
|
|
1782
|
+
allModes: ["summary", "full"]
|
|
1649
1783
|
},
|
|
1650
1784
|
categories,
|
|
1651
1785
|
totalServices: catalog.length
|
|
1652
1786
|
},
|
|
1653
|
-
displayText: `${catalog.length} services across ${categories.length} categories. Re-call with a category or
|
|
1787
|
+
displayText: `${catalog.length} services across ${categories.length} categories. Re-call with a category, query, or mode:"full".`
|
|
1654
1788
|
};
|
|
1655
1789
|
}
|
|
1656
1790
|
let filtered = catalog;
|
|
@@ -2933,22 +3067,44 @@ function fmtToolTvl(tvl) {
|
|
|
2933
3067
|
if (tvl >= 1e3) return `$${(tvl / 1e3).toFixed(0)}K`;
|
|
2934
3068
|
return `$${tvl}`;
|
|
2935
3069
|
}
|
|
3070
|
+
var POOL_STABLE_LEGS = /* @__PURE__ */ new Set([
|
|
3071
|
+
"USDC",
|
|
3072
|
+
"WUSDC",
|
|
3073
|
+
"USDT",
|
|
3074
|
+
"WUSDT",
|
|
3075
|
+
"SUIUSDT",
|
|
3076
|
+
"USDY",
|
|
3077
|
+
"USDSUI",
|
|
3078
|
+
"USDE",
|
|
3079
|
+
"AUSD",
|
|
3080
|
+
"FDUSD",
|
|
3081
|
+
"BUCK",
|
|
3082
|
+
"DAI",
|
|
3083
|
+
"LUSD",
|
|
3084
|
+
"FRAX",
|
|
3085
|
+
"GUSD",
|
|
3086
|
+
"PYUSD",
|
|
3087
|
+
"USDS",
|
|
3088
|
+
"CRVUSD"
|
|
3089
|
+
]);
|
|
2936
3090
|
var defillamaYieldPoolsTool = buildTool({
|
|
2937
3091
|
name: "defillama_yield_pools",
|
|
2938
|
-
description: '
|
|
3092
|
+
description: 'Cross-protocol LP / vault yields with IMPERMANENT-LOSS RISK (Cetus, Bluefin, Full Sail, etc.). ONLY call when the user explicitly asks about LP pools, DeFi farming, or "higher yield with more risk". For safe single-sided lending yields (USDC save, NAVI, etc.) use rates_info instead \u2014 NEVER both in the same turn. Filter by chain (e.g. "Sui"), project, and minimum TVL.',
|
|
2939
3093
|
inputSchema: z.object({
|
|
2940
3094
|
chain: z.string().optional().describe('Filter by chain name (e.g. "Sui", "Ethereum")'),
|
|
2941
|
-
project: z.string().optional().describe('Filter by protocol project name (e.g. "
|
|
3095
|
+
project: z.string().optional().describe('Filter by protocol project name (e.g. "cetus-clmm", "bluefin-spot")'),
|
|
2942
3096
|
limit: z.number().min(1).max(20).optional().describe("Max results (default 5)"),
|
|
2943
|
-
minTvl: z.number().optional().describe("Minimum TVL in USD to filter out small/risky pools (default 100000)")
|
|
3097
|
+
minTvl: z.number().optional().describe("Minimum TVL in USD to filter out small/risky pools (default 100000)"),
|
|
3098
|
+
stableOnly: z.boolean().optional().describe('When true, only return pools where every leg is a stablecoin (USDC, USDT, USDSUI, etc.). Use this for "show stablecoin yield options" \u2014 keeps volatile-pair LPs (WAL-SUI, DEEP-SUI) out.')
|
|
2944
3099
|
}),
|
|
2945
3100
|
jsonSchema: {
|
|
2946
3101
|
type: "object",
|
|
2947
3102
|
properties: {
|
|
2948
3103
|
chain: { type: "string", description: "Filter by chain name" },
|
|
2949
|
-
project: { type: "string", description: 'Filter by protocol project name (e.g. "
|
|
3104
|
+
project: { type: "string", description: 'Filter by protocol project name (e.g. "cetus-clmm")' },
|
|
2950
3105
|
limit: { type: "number", description: "Max results (default 5)" },
|
|
2951
|
-
minTvl: { type: "number", description: "Minimum TVL in USD (default 100000)" }
|
|
3106
|
+
minTvl: { type: "number", description: "Minimum TVL in USD (default 100000)" },
|
|
3107
|
+
stableOnly: { type: "boolean", description: "When true, only return all-stablecoin pools." }
|
|
2952
3108
|
},
|
|
2953
3109
|
required: []
|
|
2954
3110
|
},
|
|
@@ -2984,6 +3140,12 @@ var defillamaYieldPoolsTool = buildTool({
|
|
|
2984
3140
|
}
|
|
2985
3141
|
const minTvl = input.minTvl ?? 1e5;
|
|
2986
3142
|
pools = pools.filter((p) => p.tvlUsd >= minTvl);
|
|
3143
|
+
if (input.stableOnly) {
|
|
3144
|
+
pools = pools.filter((p) => {
|
|
3145
|
+
const legs = p.symbol.split("-");
|
|
3146
|
+
return legs.every((leg) => POOL_STABLE_LEGS.has(leg.trim().toUpperCase()));
|
|
3147
|
+
});
|
|
3148
|
+
}
|
|
2987
3149
|
pools.sort((a, b) => b.apy - a.apy);
|
|
2988
3150
|
const limit = input.limit ?? 5;
|
|
2989
3151
|
const top = pools.slice(0, limit);
|