@t2000/engine 0.7.5 → 0.7.7

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/README.md CHANGED
@@ -87,7 +87,7 @@ QueryEngine.submitMessage()
87
87
 
88
88
  ## Built-in Tools
89
89
 
90
- ### Read Tools (19 — parallel, auto-approved)
90
+ ### Read Tools (20 — parallel, auto-approved)
91
91
 
92
92
  | Tool | Description |
93
93
  |------|-------------|
@@ -96,6 +96,7 @@ QueryEngine.submitMessage()
96
96
  | `health_check` | Health factor with risk assessment |
97
97
  | `rates_info` | Current supply/borrow APYs |
98
98
  | `transaction_history` | Recent transaction log |
99
+ | `allowance_status` | Agent budget allowance and permissions |
99
100
  | `explain_tx` | Human-readable transaction explanation from digest |
100
101
  | `web_search` | Web search via Brave Search API |
101
102
  | `swap_quote` | Preview swap route, output amount, and price impact (no execution) |
package/dist/index.d.ts CHANGED
@@ -790,6 +790,7 @@ declare const balanceCheckTool: Tool<{}, {
790
790
  total: number;
791
791
  stables: number;
792
792
  holdings: any[];
793
+ saveableUsdc: number;
793
794
  }>;
794
795
 
795
796
  declare const savingsInfoTool: Tool<{}, SavingsResult>;
@@ -849,6 +850,7 @@ declare const withdrawTool: Tool<{
849
850
  declare const sendTransferTool: Tool<{
850
851
  amount: number;
851
852
  to: string;
853
+ memo?: string | undefined;
852
854
  }, {
853
855
  success: boolean;
854
856
  tx: string;
@@ -858,6 +860,7 @@ declare const sendTransferTool: Tool<{
858
860
  gasCost: number;
859
861
  gasMethod: _t2000_sdk.GasMethod;
860
862
  balance: _t2000_sdk.BalanceResponse;
863
+ memo: string | null;
861
864
  }>;
862
865
 
863
866
  declare const borrowTool: Tool<{
@@ -1175,6 +1178,6 @@ declare function fetchWalletCoins(address: string, rpcUrl?: string): Promise<Wal
1175
1178
  declare function fetchTokenPrices(coinTypes: string[]): Promise<Record<string, number>>;
1176
1179
  declare function clearPriceCache(): void;
1177
1180
 
1178
- declare const DEFAULT_SYSTEM_PROMPT = "You are a financial agent on Sui. You manage money and access paid APIs via MPP micropayments.\n\n## Response rules\n- 1-2 sentences max. No bullet lists unless asked. No preambles.\n- Never say \"Would you like me to...\", \"Sure!\", \"Great question!\", \"Absolutely!\" \u2014 just do it or say you can't.\n- Lead with the result. After tool calls, state the outcome with real numbers. Done.\n- Present amounts as $1,234.56 and rates as X.XX% APY.\n- Show top 3 results unless asked for more. Summarize totals in one line.\n\n## Execution rule\nOnly offer to execute actions you have tools for. If you retrieved a quote, data, or information but have no tool to act on it, give the user the result and tell them where to execute manually \u2014 in one sentence. Never say \"Would you like me to proceed?\" unless you have a tool that can actually proceed.\n\n## Before acting\n- ALWAYS call a read tool first before any write tool \u2014 balance_check before save/send/borrow, savings_info before withdraw.\n- Show real numbers from tools \u2014 never fabricate rates, amounts, or balances.\n- When user says \"all\" or an imprecise amount, call the read tool first to get the exact number.\n\n## Tool usage\n- Use tools proactively \u2014 don't refuse requests you can handle.\n- For real-world questions (weather, search, news, prices), use pay_api. Tell the user the cost first.\n- For broad market data (yields across protocols, token prices, TVL, protocol comparisons), use defillama_* tools.\n- To discover Sui protocols, use defillama_sui_protocols first, then defillama_protocol_info with the slug.\n- Run multiple read-only tools in parallel when you need several data points.\n- If a tool errors, say what went wrong and what to try instead. One sentence.\n\n## Multi-step flows\n- \"How much X for Y?\": swap_quote first, then swap_execute if user confirms.\n- \"Swap then save\": swap_execute \u2192 balance_check \u2192 save_deposit. Confirm each step.\n- \"Buy $X of token\": defillama_token_prices \u2192 calculate amount \u2192 swap_execute.\n- \"Best yield on SUI\": compare rates_info (NAVI lending) + defillama_yield_pools (broader) + volo_stats.\n- save_deposit: USDC only. To save other tokens, swap to USDC first.\n- withdraw supports legacy positions: USDC, USDe, USDsui, SUI. Pass asset param to withdraw a specific token.\n- \"Deposit SUI to earn yield\": volo_stake for SUI liquid staking. save_deposit is USDC only.\n- \"What protocols are on Sui?\": defillama_sui_protocols \u2192 defillama_protocol_info for details.\n\n## Safety\n- Never encourage risky financial behavior.\n- Warn when health factor < 1.5.\n- All amounts in USDC unless stated otherwise.";
1181
+ declare const DEFAULT_SYSTEM_PROMPT = "You are a financial agent on Sui. You manage money and access paid APIs via MPP micropayments.\n\n## Response rules\n- 1-2 sentences max. No bullet lists unless asked. No preambles.\n- Never say \"Would you like me to...\", \"Sure!\", \"Great question!\", \"Absolutely!\" \u2014 just do it or say you can't.\n- Lead with the result. After tool calls, state the outcome with real numbers. Done.\n- Present amounts as $1,234.56 and rates as X.XX% APY.\n- Show top 3 results unless asked for more. Summarize totals in one line.\n\n## Execution rule\nOnly offer to execute actions you have tools for. If you retrieved a quote, data, or information but have no tool to act on it, give the user the result and tell them where to execute manually \u2014 in one sentence. Never say \"Would you like me to proceed?\" unless you have a tool that can actually proceed.\n\n## Before acting\n- ALWAYS call a read tool first before any write tool \u2014 balance_check before save/send/borrow, savings_info before withdraw.\n- Show real numbers from tools \u2014 never fabricate rates, amounts, or balances.\n- When user says \"all\" or an imprecise amount, call the read tool first to get the exact number.\n\n## Tool usage\n- Use tools proactively \u2014 don't refuse requests you can handle.\n- For real-world questions (weather, search, news, prices), use pay_api. Tell the user the cost first.\n- For broad market data (yields across protocols, token prices, TVL, protocol comparisons), use defillama_* tools.\n- To discover Sui protocols, use defillama_sui_protocols first, then defillama_protocol_info with the slug.\n- Run multiple read-only tools in parallel when you need several data points.\n- If a tool errors, say what went wrong and what to try instead. One sentence.\n\n## Savings = USDC only (critical)\n- save_deposit accepts ONLY USDC. No other token can be deposited into savings.\n- When asked \"how much can I save?\", report only the user's USDC wallet balance (saveableUsdc field from balance_check). Other tokens like GOLD, SUI, USDT are NOT saveable and NOT savings positions \u2014 they are just wallet holdings.\n- NEVER say a non-USDC token is \"in savings\" or \"earning APY in savings\" unless it appears in the savings_info positions list. Wallet holdings \u2260 savings.\n- If user wants to save non-USDC tokens, tell them to swap to USDC first. Do NOT auto-chain swap + deposit.\n\n## Multi-step flows\n- \"How much X for Y?\": swap_quote first, then swap_execute if user confirms.\n- \"Swap then save\": swap_execute \u2192 balance_check \u2192 save_deposit. Confirm each step.\n- \"Buy $X of token\": defillama_token_prices \u2192 calculate amount \u2192 swap_execute.\n- \"Best yield on SUI\": compare rates_info (NAVI lending) + defillama_yield_pools (broader) + volo_stats.\n- withdraw supports legacy positions: USDC, USDe, USDsui, SUI. Pass asset param to withdraw a specific token.\n- \"Deposit SUI to earn yield\": volo_stake for SUI liquid staking. save_deposit is USDC only.\n- \"What protocols are on Sui?\": defillama_sui_protocols \u2192 defillama_protocol_info for details.\n\n## Safety\n- Never encourage risky financial behavior.\n- Warn when health factor < 1.5.\n- All amounts in USDC unless stated otherwise.";
1179
1182
 
1180
1183
  export { AnthropicProvider, type AnthropicProviderConfig, type BalancePrices, type BalanceResult, type BuildToolOptions, type ChatParams, type CompactOptions, type ContentBlock, type CostSnapshot, CostTracker, type CostTrackerConfig, DEFAULT_SYSTEM_PROMPT, type EngineConfig, type EngineEvent, type HealthFactorResult, type LLMProvider, type McpCallResult, McpClientManager, McpResponseCache, type McpServerConfig, type McpServerConnection, type McpToolAdapterConfig, type McpToolDescriptor, MemorySessionStore, type Message, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_SERVER_NAME, type NaviRawCoin, type NaviRawHealthFactor, type NaviRawPool, type NaviRawPosition, type NaviRawPositionsResponse, type NaviRawProtocolStats, type NaviRawRewardsResponse, type NaviReadOptions, NaviTools, type PendingAction, type PendingReward, type PendingToolCall, type PermissionLevel, type PermissionResponse, type PositionEntry, type ProtocolStats, type ProviderEvent, QueryEngine, READ_TOOLS, type RatesResult, type SSEEvent, type SavingsResult, type ServerPositionData, type SessionData, type SessionStore, type StopReason, type SuiCoinBalance, type Tool, type ToolChoice, type ToolContext, type ToolDefinition, type ToolJsonSchema, type ToolResult, TxMutex, WRITE_TOOLS, type WalletCoin, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, balanceCheckTool, borrowTool, buildMcpTools, buildTool, claimRewardsTool, clearPriceCache, compactMessages, defillamaChainTvlTool, defillamaPriceChangeTool, defillamaProtocolFeesTool, defillamaProtocolInfoTool, defillamaSuiProtocolsTool, defillamaTokenPricesTool, defillamaYieldPoolsTool, engineToSSE, estimateTokens, explainTxTool, extractMcpText, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findTool, getDefaultTools, getMcpManager, getWalletAddress, hasNaviMcp, healthCheckTool, mppServicesTool, parseMcpJson, parseSSE, payApiTool, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, registerEngineTools, repayDebtTool, requireAgent, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, swapExecuteTool, swapQuoteTool, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool };
package/dist/index.js CHANGED
@@ -480,7 +480,7 @@ async function callNavi(manager, tool, args = {}) {
480
480
  }
481
481
  var balanceCheckTool = buildTool({
482
482
  name: "balance_check",
483
- description: "Get the user's full balance breakdown: available USDC, savings deposits, outstanding debt, pending rewards, gas reserve, and total net worth.",
483
+ description: "Get the user's full balance breakdown. Returns wallet holdings (tokens the user owns \u2014 NOT savings), NAVI savings deposits (USDC deposited into NAVI Protocol earning yield), outstanding debt, pending rewards, gas reserve, total net worth, and saveableUsdc (only USDC can be deposited into savings). IMPORTANT: wallet holdings like GOLD, SUI, USDT are NOT savings positions \u2014 they are just tokens sitting in the wallet.",
484
484
  inputSchema: z.object({}),
485
485
  jsonSchema: { type: "object", properties: {}, required: [] },
486
486
  isReadOnly: true,
@@ -578,6 +578,8 @@ var balanceCheckTool = buildTool({
578
578
  pendingRewardsUsd = rewardEntries.reduce((sum, r) => sum + r.valueUsd, 0);
579
579
  }
580
580
  const visibleHoldings = holdings.filter((h) => h.usdValue >= 0.01).sort((a, b) => b.usdValue - a.usdValue);
581
+ const usdcHolding2 = holdings.find((h) => h.symbol === "USDC");
582
+ const saveableUsdc = usdcHolding2 ? usdcHolding2.balance : 0;
581
583
  const bal = {
582
584
  available: availableUsd,
583
585
  savings,
@@ -586,11 +588,13 @@ var balanceCheckTool = buildTool({
586
588
  gasReserve: gasReserveUsd2,
587
589
  total: availableUsd + savings + gasReserveUsd2 + pendingRewardsUsd - debt,
588
590
  stables: stablesUsd,
589
- holdings: visibleHoldings
591
+ holdings: visibleHoldings,
592
+ saveableUsdc
590
593
  };
594
+ const holdingsList = visibleHoldings.map((h) => `${h.symbol}: ${h.balance < 1 ? h.balance.toFixed(6) : h.balance.toFixed(2)} ($${h.usdValue.toFixed(2)})`).join(", ");
591
595
  return {
592
596
  data: bal,
593
- displayText: `Balance: $${bal.total.toFixed(2)} (Available: $${bal.available.toFixed(2)}, Savings: $${bal.savings.toFixed(2)})`
597
+ displayText: `Balance: $${bal.total.toFixed(2)} total. Wallet holdings (NOT savings): ${holdingsList || "none"}. NAVI savings deposits: $${bal.savings.toFixed(2)}. Saveable USDC (only USDC can be saved): ${saveableUsdc.toFixed(2)} USDC.`
594
598
  };
595
599
  }
596
600
  const agent = requireAgent(context);
@@ -599,6 +603,8 @@ var balanceCheckTool = buildTool({
599
603
  const stablesTotal = typeof balance.stables === "number" ? balance.stables : Object.values(balance.stables).reduce((a, b) => a + b, 0);
600
604
  const sdkHoldings = balance.holdings;
601
605
  const holdingsArr = Array.isArray(sdkHoldings) ? sdkHoldings : [];
606
+ const usdcHolding = holdingsArr.find((h) => h.symbol === "USDC");
607
+ const sdkSaveableUsdc = usdcHolding ? usdcHolding.balance ?? 0 : 0;
602
608
  return {
603
609
  data: {
604
610
  available: balance.available,
@@ -608,9 +614,10 @@ var balanceCheckTool = buildTool({
608
614
  gasReserve: gasReserveUsd,
609
615
  total: balance.total,
610
616
  stables: stablesTotal,
611
- holdings: holdingsArr
617
+ holdings: holdingsArr,
618
+ saveableUsdc: sdkSaveableUsdc
612
619
  },
613
- displayText: `Balance: $${balance.total.toFixed(2)} (Available: $${balance.available.toFixed(2)}, Savings: $${balance.savings.toFixed(2)})`
620
+ displayText: `Balance: $${balance.total.toFixed(2)} total. Wallet: $${balance.available.toFixed(2)} available. NAVI savings deposits: $${balance.savings.toFixed(2)}. Saveable USDC (only USDC can be saved): ${sdkSaveableUsdc.toFixed(2)} USDC.`
614
621
  };
615
622
  }
616
623
  });
@@ -1128,7 +1135,8 @@ var sendTransferTool = buildTool({
1128
1135
  description: "Send USDC to another Sui address or contact name. Validates the address, checks balance, and executes the on-chain transfer. Returns tx hash, gas cost, and updated balance.",
1129
1136
  inputSchema: z.object({
1130
1137
  to: z.string().min(1),
1131
- amount: z.number().positive()
1138
+ amount: z.number().positive(),
1139
+ memo: z.string().optional()
1132
1140
  }),
1133
1141
  jsonSchema: {
1134
1142
  type: "object",
@@ -1140,6 +1148,10 @@ var sendTransferTool = buildTool({
1140
1148
  amount: {
1141
1149
  type: "number",
1142
1150
  description: "Amount in USD to send"
1151
+ },
1152
+ memo: {
1153
+ type: "string",
1154
+ description: "Optional note attached to the transfer (shown in transaction receipt)"
1143
1155
  }
1144
1156
  },
1145
1157
  required: ["to", "amount"]
@@ -1158,7 +1170,8 @@ var sendTransferTool = buildTool({
1158
1170
  contactName: result.contactName,
1159
1171
  gasCost: result.gasCost,
1160
1172
  gasMethod: result.gasMethod,
1161
- balance: result.balance
1173
+ balance: result.balance,
1174
+ memo: input.memo ?? null
1162
1175
  },
1163
1176
  displayText: `Sent $${result.amount.toFixed(2)} to ${result.contactName ?? result.to.slice(0, 10)}\u2026 (tx: ${result.tx.slice(0, 8)}\u2026)`
1164
1177
  };
@@ -1288,7 +1301,15 @@ var payApiTool = buildTool({
1288
1301
 
1289
1302
  Use mpp_services tool first to discover available services and get the correct endpoint URL, required body parameters, and pricing. Then call this tool with the full URL and JSON body.
1290
1303
 
1291
- Always use POST. Construct the URL from the gateway base + service path. Pass parameters as a JSON string in body.`,
1304
+ Always use POST. Construct the URL from the gateway base + service path. Pass parameters as a JSON string in body.
1305
+
1306
+ CRITICAL \u2014 non-retryable errors: If the result contains "doNotRetry": true or "paymentConfirmed": true, the user has ALREADY been charged. NEVER call pay_api again for the same request. Report the error to the user.
1307
+
1308
+ Lob (postcards/letters) \u2014 MULTI-STEP, NEVER skip:
1309
+ 1. Generate design image FIRST via fal/fal-ai/flux/dev ($0.03). Show the image to the user as markdown ![design](url).
1310
+ 2. Ask the user to confirm before mailing ("Here's the design. Print and mail for $1.00?").
1311
+ 3. ONLY after user confirms: call lob/v1/postcards with the image URL in the front HTML (<img src="URL" style="width:100%;height:100%;object-fit:cover"/>).
1312
+ Always use ISO-3166 country codes (GB not UK, US not USA). A return address ("from") is added automatically \u2014 do not include one.`,
1292
1313
  inputSchema: z.object({
1293
1314
  url: z.string().url(),
1294
1315
  method: z.enum(["GET", "POST", "PUT", "DELETE"]).optional(),
@@ -1964,6 +1985,56 @@ Risks: ${riskFactors.join("; ")}`
1964
1985
  };
1965
1986
  }
1966
1987
  });
1988
+ var allowanceStatusTool = buildTool({
1989
+ name: "allowance_status",
1990
+ description: "Check the agent spending allowance status: whether it is enabled, the daily USDC limit, amount spent today, remaining budget, which service categories are permitted, and when the budget resets. Use this when the user asks about their agent budget, spending limits, or autonomous transaction permissions.",
1991
+ inputSchema: z.object({}),
1992
+ jsonSchema: { type: "object", properties: {}, required: [] },
1993
+ isReadOnly: true,
1994
+ async call(_input, context) {
1995
+ if (!context.env?.ALLOWANCE_API_URL || !context.walletAddress) {
1996
+ return {
1997
+ data: {
1998
+ enabled: false,
1999
+ dailyLimit: 0,
2000
+ spent: 0,
2001
+ remaining: 0,
2002
+ permissions: [],
2003
+ resetsAt: null
2004
+ },
2005
+ displayText: "Agent allowance is not configured."
2006
+ };
2007
+ }
2008
+ const disabledResult = {
2009
+ data: {
2010
+ enabled: false,
2011
+ dailyLimit: 0,
2012
+ spent: 0,
2013
+ remaining: 0,
2014
+ permissions: [],
2015
+ resetsAt: null
2016
+ },
2017
+ displayText: "Unable to fetch allowance status."
2018
+ };
2019
+ let allowance;
2020
+ try {
2021
+ const url = `${context.env.ALLOWANCE_API_URL}/api/allowance/${context.walletAddress}`;
2022
+ const res = await fetch(url, {
2023
+ signal: context.signal,
2024
+ headers: context.env.AUDRIC_INTERNAL_KEY ? { "x-internal-key": context.env.AUDRIC_INTERNAL_KEY } : void 0
2025
+ });
2026
+ if (!res.ok) return disabledResult;
2027
+ allowance = await res.json();
2028
+ } catch {
2029
+ return disabledResult;
2030
+ }
2031
+ const statusText = allowance.enabled ? `Allowance active: $${allowance.spent.toFixed(2)} / $${allowance.dailyLimit.toFixed(2)} used today. ${allowance.permissions.length} service categories enabled.` : "Agent allowance is disabled.";
2032
+ return {
2033
+ data: allowance,
2034
+ displayText: statusText
2035
+ };
2036
+ }
2037
+ });
1967
2038
  var LLAMA_API2 = "https://api.llama.fi";
1968
2039
  var YIELDS_API2 = "https://yields.llama.fi";
1969
2040
  var COINS_API = "https://coins.llama.fi";
@@ -2266,7 +2337,8 @@ var READ_TOOLS = [
2266
2337
  defillamaPriceChangeTool,
2267
2338
  defillamaChainTvlTool,
2268
2339
  defillamaProtocolFeesTool,
2269
- defillamaSuiProtocolsTool
2340
+ defillamaSuiProtocolsTool,
2341
+ allowanceStatusTool
2270
2342
  ];
2271
2343
  var WRITE_TOOLS = [
2272
2344
  saveDepositTool,
@@ -2311,12 +2383,17 @@ Only offer to execute actions you have tools for. If you retrieved a quote, data
2311
2383
  - Run multiple read-only tools in parallel when you need several data points.
2312
2384
  - If a tool errors, say what went wrong and what to try instead. One sentence.
2313
2385
 
2386
+ ## Savings = USDC only (critical)
2387
+ - save_deposit accepts ONLY USDC. No other token can be deposited into savings.
2388
+ - When asked "how much can I save?", report only the user's USDC wallet balance (saveableUsdc field from balance_check). Other tokens like GOLD, SUI, USDT are NOT saveable and NOT savings positions \u2014 they are just wallet holdings.
2389
+ - NEVER say a non-USDC token is "in savings" or "earning APY in savings" unless it appears in the savings_info positions list. Wallet holdings \u2260 savings.
2390
+ - If user wants to save non-USDC tokens, tell them to swap to USDC first. Do NOT auto-chain swap + deposit.
2391
+
2314
2392
  ## Multi-step flows
2315
2393
  - "How much X for Y?": swap_quote first, then swap_execute if user confirms.
2316
2394
  - "Swap then save": swap_execute \u2192 balance_check \u2192 save_deposit. Confirm each step.
2317
2395
  - "Buy $X of token": defillama_token_prices \u2192 calculate amount \u2192 swap_execute.
2318
2396
  - "Best yield on SUI": compare rates_info (NAVI lending) + defillama_yield_pools (broader) + volo_stats.
2319
- - save_deposit: USDC only. To save other tokens, swap to USDC first.
2320
2397
  - withdraw supports legacy positions: USDC, USDe, USDsui, SUI. Pass asset param to withdraw a specific token.
2321
2398
  - "Deposit SUI to earn yield": volo_stake for SUI liquid staking. save_deposit is USDC only.
2322
2399
  - "What protocols are on Sui?": defillama_sui_protocols \u2192 defillama_protocol_info for details.