@t2000/engine 0.6.2 → 0.6.4
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 +3 -1
- package/dist/index.js +82 -29
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1050,7 +1050,8 @@ interface ProtocolProfile {
|
|
|
1050
1050
|
mcap: number | null;
|
|
1051
1051
|
fees24h: number | null;
|
|
1052
1052
|
revenue24h: number | null;
|
|
1053
|
-
|
|
1053
|
+
auditCount: number;
|
|
1054
|
+
auditLinks: string[];
|
|
1054
1055
|
url: string;
|
|
1055
1056
|
twitter: string | null;
|
|
1056
1057
|
riskFactors: string[];
|
|
@@ -1063,6 +1064,7 @@ declare const protocolDeepDiveTool: Tool<{
|
|
|
1063
1064
|
declare const defillamaYieldPoolsTool: Tool<{
|
|
1064
1065
|
limit?: number | undefined;
|
|
1065
1066
|
chain?: string | undefined;
|
|
1067
|
+
project?: string | undefined;
|
|
1066
1068
|
minTvl?: number | undefined;
|
|
1067
1069
|
}, {
|
|
1068
1070
|
pool: string;
|
package/dist/index.js
CHANGED
|
@@ -245,6 +245,9 @@ var NaviTools = {
|
|
|
245
245
|
};
|
|
246
246
|
|
|
247
247
|
// src/tools/utils.ts
|
|
248
|
+
function hasAgent(context) {
|
|
249
|
+
return !!context.agent;
|
|
250
|
+
}
|
|
248
251
|
function requireAgent(context) {
|
|
249
252
|
if (!context.agent) {
|
|
250
253
|
throw new Error(
|
|
@@ -258,6 +261,11 @@ function hasNaviMcp(context) {
|
|
|
258
261
|
const mgr = context.mcpManager;
|
|
259
262
|
return mgr.isConnected(NAVI_SERVER_NAME);
|
|
260
263
|
}
|
|
264
|
+
function hasNaviMcpGlobal(context) {
|
|
265
|
+
if (!context.mcpManager) return false;
|
|
266
|
+
const mgr = context.mcpManager;
|
|
267
|
+
return mgr.isConnected(NAVI_SERVER_NAME);
|
|
268
|
+
}
|
|
261
269
|
function getMcpManager(context) {
|
|
262
270
|
return context.mcpManager;
|
|
263
271
|
}
|
|
@@ -845,29 +853,43 @@ var healthCheckTool = buildTool({
|
|
|
845
853
|
};
|
|
846
854
|
}
|
|
847
855
|
});
|
|
856
|
+
var YIELDS_API = "https://yields.llama.fi";
|
|
848
857
|
function formatRatesSummary(rates) {
|
|
849
858
|
return Object.entries(rates).map(([asset, r]) => `${asset}: Save ${(r.saveApy * 100).toFixed(2)}% / Borrow ${(r.borrowApy * 100).toFixed(2)}%`).join(", ");
|
|
850
859
|
}
|
|
860
|
+
async function fetchRatesFromDefiLlama() {
|
|
861
|
+
const res = await fetch(`${YIELDS_API}/pools`, { signal: AbortSignal.timeout(15e3) });
|
|
862
|
+
if (!res.ok) throw new Error(`DefiLlama API error: HTTP ${res.status}`);
|
|
863
|
+
const data = await res.json();
|
|
864
|
+
const naviPools = (data.data ?? []).filter(
|
|
865
|
+
(p) => p.chain === "Sui" && p.project === "navi-lending" && p.tvlUsd > 1e4
|
|
866
|
+
);
|
|
867
|
+
const result = {};
|
|
868
|
+
for (const pool of naviPools) {
|
|
869
|
+
const saveApy = (pool.apy ?? 0) / 100;
|
|
870
|
+
const borrowApy = pool.apyBorrow != null ? Math.abs(pool.apyBorrow) / 100 : 0;
|
|
871
|
+
result[pool.symbol] = { saveApy, borrowApy };
|
|
872
|
+
}
|
|
873
|
+
return result;
|
|
874
|
+
}
|
|
851
875
|
var ratesInfoTool = buildTool({
|
|
852
876
|
name: "rates_info",
|
|
853
|
-
description: "Get current lending/
|
|
877
|
+
description: "Get current NAVI Protocol lending/savings rates (APY) for supported assets on Sui. Returns save APY and borrow APY per asset.",
|
|
854
878
|
inputSchema: z.object({}),
|
|
855
879
|
jsonSchema: { type: "object", properties: {}, required: [] },
|
|
856
880
|
isReadOnly: true,
|
|
857
881
|
async call(_input, context) {
|
|
858
|
-
if (
|
|
882
|
+
if (hasNaviMcpGlobal(context)) {
|
|
859
883
|
const rates2 = await fetchRates(getMcpManager(context));
|
|
860
|
-
return {
|
|
861
|
-
data: rates2,
|
|
862
|
-
displayText: formatRatesSummary(rates2)
|
|
863
|
-
};
|
|
884
|
+
return { data: rates2, displayText: formatRatesSummary(rates2) };
|
|
864
885
|
}
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
data:
|
|
869
|
-
|
|
870
|
-
|
|
886
|
+
if (hasAgent(context)) {
|
|
887
|
+
const agent = requireAgent(context);
|
|
888
|
+
const rates2 = await agent.rates();
|
|
889
|
+
return { data: rates2, displayText: formatRatesSummary(rates2) };
|
|
890
|
+
}
|
|
891
|
+
const rates = await fetchRatesFromDefiLlama();
|
|
892
|
+
return { data: rates, displayText: formatRatesSummary(rates) };
|
|
871
893
|
}
|
|
872
894
|
});
|
|
873
895
|
var SUI_TYPE = "0x2::sui::SUI";
|
|
@@ -1784,9 +1806,32 @@ ${insightLines}`
|
|
|
1784
1806
|
}
|
|
1785
1807
|
});
|
|
1786
1808
|
var LLAMA_API = "https://api.llama.fi";
|
|
1809
|
+
var SLUG_ALIASES = {
|
|
1810
|
+
"navi": "navi-lending",
|
|
1811
|
+
"navi-protocol": "navi-lending",
|
|
1812
|
+
"scallop": "scallop-lend"
|
|
1813
|
+
};
|
|
1787
1814
|
var inputSchema4 = z.object({
|
|
1788
|
-
protocol: z.string().describe('Protocol slug (e.g. "navi-
|
|
1815
|
+
protocol: z.string().describe('Protocol slug (e.g. "navi-lending", "cetus", "scallop-lend")')
|
|
1789
1816
|
});
|
|
1817
|
+
function extractCurrentTvl(proto) {
|
|
1818
|
+
const chainTvls = proto.currentChainTvls;
|
|
1819
|
+
if (chainTvls && typeof chainTvls === "object") {
|
|
1820
|
+
return Object.values(chainTvls).filter((v) => typeof v === "number" && v > 0).reduce((sum, v) => sum + v, 0);
|
|
1821
|
+
}
|
|
1822
|
+
if (Array.isArray(proto.tvl) && proto.tvl.length > 0) {
|
|
1823
|
+
const last = proto.tvl[proto.tvl.length - 1];
|
|
1824
|
+
return last.totalLiquidityUSD ?? 0;
|
|
1825
|
+
}
|
|
1826
|
+
if (typeof proto.tvl === "number") return proto.tvl;
|
|
1827
|
+
return 0;
|
|
1828
|
+
}
|
|
1829
|
+
function fmtTvl(tvl) {
|
|
1830
|
+
if (tvl >= 1e9) return `$${(tvl / 1e9).toFixed(2)}B`;
|
|
1831
|
+
if (tvl >= 1e6) return `$${(tvl / 1e6).toFixed(1)}M`;
|
|
1832
|
+
if (tvl >= 1e3) return `$${(tvl / 1e3).toFixed(0)}K`;
|
|
1833
|
+
return `$${tvl.toFixed(0)}`;
|
|
1834
|
+
}
|
|
1790
1835
|
var protocolDeepDiveTool = buildTool({
|
|
1791
1836
|
name: "protocol_deep_dive",
|
|
1792
1837
|
description: 'Get a comprehensive safety and financial profile of a DeFi protocol. Includes TVL trends, revenue, audit status, and risk assessment. Use when users ask "is X safe?" or "tell me about protocol Y".',
|
|
@@ -1794,13 +1839,14 @@ var protocolDeepDiveTool = buildTool({
|
|
|
1794
1839
|
jsonSchema: {
|
|
1795
1840
|
type: "object",
|
|
1796
1841
|
properties: {
|
|
1797
|
-
protocol: { type: "string", description: 'Protocol slug (e.g. "navi-
|
|
1842
|
+
protocol: { type: "string", description: 'Protocol slug (e.g. "navi-lending", "cetus")' }
|
|
1798
1843
|
},
|
|
1799
1844
|
required: ["protocol"]
|
|
1800
1845
|
},
|
|
1801
1846
|
isReadOnly: true,
|
|
1802
1847
|
async call(input) {
|
|
1803
|
-
|
|
1848
|
+
let slug = input.protocol.toLowerCase().replace(/\s+/g, "-");
|
|
1849
|
+
slug = SLUG_ALIASES[slug] ?? slug;
|
|
1804
1850
|
const [protocolRes, feesRes] = await Promise.allSettled([
|
|
1805
1851
|
fetch(`${LLAMA_API}/protocol/${slug}`, { signal: AbortSignal.timeout(1e4) }).then((r) => {
|
|
1806
1852
|
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
|
@@ -1815,14 +1861,15 @@ var protocolDeepDiveTool = buildTool({
|
|
|
1815
1861
|
throw new Error(`Protocol "${slug}" not found on DefiLlama.`);
|
|
1816
1862
|
}
|
|
1817
1863
|
const proto = protocolRes.value;
|
|
1818
|
-
const tvl =
|
|
1864
|
+
const tvl = extractCurrentTvl(proto);
|
|
1819
1865
|
const tvlChange1d = Number(proto.change_1d ?? 0);
|
|
1820
1866
|
const tvlChange7d = Number(proto.change_7d ?? 0);
|
|
1821
1867
|
const tvlChange30d = Number(proto.change_1m ?? 0);
|
|
1822
|
-
const chains = proto.chains
|
|
1868
|
+
const chains = Array.isArray(proto.chains) ? proto.chains : [];
|
|
1823
1869
|
const category = proto.category ?? "Unknown";
|
|
1824
|
-
const
|
|
1825
|
-
const
|
|
1870
|
+
const auditCount = Number(proto.audits) || 0;
|
|
1871
|
+
const auditLinks = Array.isArray(proto.audit_links) ? proto.audit_links : [];
|
|
1872
|
+
const hasAudits = auditCount > 0 || auditLinks.length > 0;
|
|
1826
1873
|
let fees24h = null;
|
|
1827
1874
|
let revenue24h = null;
|
|
1828
1875
|
if (feesRes.status === "fulfilled" && feesRes.value) {
|
|
@@ -1832,13 +1879,13 @@ var protocolDeepDiveTool = buildTool({
|
|
|
1832
1879
|
}
|
|
1833
1880
|
const riskFactors = [];
|
|
1834
1881
|
if (tvl < 1e6) riskFactors.push("TVL under $1M \u2014 low liquidity risk");
|
|
1835
|
-
if (tvl < 1e7) riskFactors.push("TVL under $10M \u2014 moderate liquidity");
|
|
1882
|
+
else if (tvl < 1e7) riskFactors.push("TVL under $10M \u2014 moderate liquidity");
|
|
1836
1883
|
if (tvlChange7d < -15) riskFactors.push(`TVL dropped ${tvlChange7d.toFixed(1)}% in 7 days`);
|
|
1837
1884
|
if (chains.length === 1) riskFactors.push("Single-chain deployment");
|
|
1838
|
-
if (!
|
|
1839
|
-
|
|
1885
|
+
if (!hasAudits) riskFactors.push("No published audits found");
|
|
1886
|
+
else riskFactors.push(`${auditCount || auditLinks.length} audit(s) on file`);
|
|
1840
1887
|
let safetyScore;
|
|
1841
|
-
if (tvl > 1e8 &&
|
|
1888
|
+
if (tvl > 1e8 && hasAudits && tvlChange7d > -10) {
|
|
1842
1889
|
safetyScore = "High \u2014 established protocol with audits and significant TVL";
|
|
1843
1890
|
} else if (tvl > 1e7 && tvlChange7d > -20) {
|
|
1844
1891
|
safetyScore = "Moderate \u2014 decent TVL, use with caution";
|
|
@@ -1857,18 +1904,18 @@ var protocolDeepDiveTool = buildTool({
|
|
|
1857
1904
|
mcap: proto.mcap ? Number(proto.mcap) : null,
|
|
1858
1905
|
fees24h,
|
|
1859
1906
|
revenue24h,
|
|
1860
|
-
|
|
1907
|
+
auditCount,
|
|
1908
|
+
auditLinks,
|
|
1861
1909
|
url: proto.url ?? "",
|
|
1862
1910
|
twitter: proto.twitter ?? null,
|
|
1863
1911
|
riskFactors,
|
|
1864
1912
|
safetyScore
|
|
1865
1913
|
};
|
|
1866
|
-
const tvlStr = tvl > 1e9 ? `$${(tvl / 1e9).toFixed(2)}B` : `$${(tvl / 1e6).toFixed(1)}M`;
|
|
1867
1914
|
const feesStr = fees24h != null ? ` | Fees 24h: $${fees24h.toLocaleString()}` : "";
|
|
1868
1915
|
return {
|
|
1869
1916
|
data: result,
|
|
1870
1917
|
displayText: `**${result.name}** (${category})
|
|
1871
|
-
TVL: ${
|
|
1918
|
+
TVL: ${fmtTvl(tvl)} (7d: ${tvlChange7d > 0 ? "+" : ""}${tvlChange7d.toFixed(1)}%)${feesStr}
|
|
1872
1919
|
Chains: ${chains.join(", ")}
|
|
1873
1920
|
Safety: ${safetyScore}
|
|
1874
1921
|
Risks: ${riskFactors.join("; ")}`
|
|
@@ -1876,7 +1923,7 @@ Risks: ${riskFactors.join("; ")}`
|
|
|
1876
1923
|
}
|
|
1877
1924
|
});
|
|
1878
1925
|
var LLAMA_API2 = "https://api.llama.fi";
|
|
1879
|
-
var
|
|
1926
|
+
var YIELDS_API2 = "https://yields.llama.fi";
|
|
1880
1927
|
var COINS_API = "https://coins.llama.fi";
|
|
1881
1928
|
var CACHE_TTL3 = 6e4;
|
|
1882
1929
|
var apiCache = /* @__PURE__ */ new Map();
|
|
@@ -1897,9 +1944,10 @@ function fmtToolTvl(tvl) {
|
|
|
1897
1944
|
}
|
|
1898
1945
|
var defillamaYieldPoolsTool = buildTool({
|
|
1899
1946
|
name: "defillama_yield_pools",
|
|
1900
|
-
description: 'Get top DeFi yield pools across
|
|
1947
|
+
description: 'Get top DeFi yield pools across protocols. Filter by chain (e.g. "Sui"), project (e.g. "navi-lending"), and minimum TVL. For NAVI lending rates, use project "navi-lending".',
|
|
1901
1948
|
inputSchema: z.object({
|
|
1902
1949
|
chain: z.string().optional().describe('Filter by chain name (e.g. "Sui", "Ethereum")'),
|
|
1950
|
+
project: z.string().optional().describe('Filter by protocol project name (e.g. "navi-lending", "cetus-clmm")'),
|
|
1903
1951
|
limit: z.number().min(1).max(20).optional().describe("Max results (default 5)"),
|
|
1904
1952
|
minTvl: z.number().optional().describe("Minimum TVL in USD to filter out small/risky pools (default 100000)")
|
|
1905
1953
|
}),
|
|
@@ -1907,6 +1955,7 @@ var defillamaYieldPoolsTool = buildTool({
|
|
|
1907
1955
|
type: "object",
|
|
1908
1956
|
properties: {
|
|
1909
1957
|
chain: { type: "string", description: "Filter by chain name" },
|
|
1958
|
+
project: { type: "string", description: 'Filter by protocol project name (e.g. "navi-lending")' },
|
|
1910
1959
|
limit: { type: "number", description: "Max results (default 5)" },
|
|
1911
1960
|
minTvl: { type: "number", description: "Minimum TVL in USD (default 100000)" }
|
|
1912
1961
|
},
|
|
@@ -1914,12 +1963,16 @@ var defillamaYieldPoolsTool = buildTool({
|
|
|
1914
1963
|
},
|
|
1915
1964
|
isReadOnly: true,
|
|
1916
1965
|
async call(input) {
|
|
1917
|
-
const data = await cachedFetch(`${
|
|
1966
|
+
const data = await cachedFetch(`${YIELDS_API2}/pools`);
|
|
1918
1967
|
let pools = data.data ?? [];
|
|
1919
1968
|
if (input.chain) {
|
|
1920
1969
|
const chain = input.chain.toLowerCase();
|
|
1921
1970
|
pools = pools.filter((p) => p.chain.toLowerCase() === chain);
|
|
1922
1971
|
}
|
|
1972
|
+
if (input.project) {
|
|
1973
|
+
const project = input.project.toLowerCase();
|
|
1974
|
+
pools = pools.filter((p) => p.project.toLowerCase() === project);
|
|
1975
|
+
}
|
|
1923
1976
|
const minTvl = input.minTvl ?? 1e5;
|
|
1924
1977
|
pools = pools.filter((p) => p.tvlUsd >= minTvl);
|
|
1925
1978
|
pools.sort((a, b) => b.apy - a.apy);
|