@t2000/engine 0.51.1 → 0.53.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.
package/dist/index.d.ts CHANGED
@@ -247,6 +247,19 @@ interface GuardConfig {
247
247
  * quote requirement.
248
248
  */
249
249
  swapPreview?: boolean;
250
+ /**
251
+ * Root-cause fix for "user asks about a watched address (`0x40cd…`)
252
+ * and the LLM calls `balance_check` / `portfolio_analysis` /
253
+ * `transaction_history` without passing `address`, returning the
254
+ * signed-in user's own data instead". The default-to-self behavior is
255
+ * correct when no address is mentioned, but silently wrong when the
256
+ * user names a third-party wallet. When enabled (default), the guard
257
+ * inspects recent user messages for full Sui addresses and blocks
258
+ * any read tool that targets the user's own wallet (or omits
259
+ * `address`) when a different address was named. Disable only if the
260
+ * host has its own equivalent address-resolution layer.
261
+ */
262
+ addressScope?: boolean;
250
263
  }
251
264
  declare const DEFAULT_GUARD_CONFIG: GuardConfig;
252
265
  declare class BalanceTracker {
@@ -2020,10 +2033,10 @@ declare const ratesInfoTool: Tool<{
2020
2033
 
2021
2034
  declare const transactionHistoryTool: Tool<{
2022
2035
  action?: "send" | "swap" | "transaction" | "lending" | undefined;
2023
- date?: string | undefined;
2024
2036
  address?: string | undefined;
2025
- direction?: "out" | "in" | undefined;
2037
+ date?: string | undefined;
2026
2038
  limit?: number | undefined;
2039
+ direction?: "out" | "in" | undefined;
2027
2040
  counterparty?: string | undefined;
2028
2041
  minUsd?: number | undefined;
2029
2042
  assetSymbol?: string | undefined;
@@ -2179,8 +2192,8 @@ declare const voloStatsTool: Tool<{}, {
2179
2192
  }>;
2180
2193
 
2181
2194
  declare const saveContactTool: Tool<{
2182
- name: string;
2183
2195
  address: string;
2196
+ name: string;
2184
2197
  }, {
2185
2198
  saved: boolean;
2186
2199
  name: string;
@@ -2394,6 +2407,64 @@ interface WalletCoin {
2394
2407
  */
2395
2408
  declare function fetchWalletCoins(address: string, rpcUrl?: string): Promise<WalletCoin[]>;
2396
2409
 
2397
- declare const DEFAULT_SYSTEM_PROMPT = "You are Audric \u2014 a financial agent on Sui. Audric is exactly five products: Audric Passport (the trust layer \u2014 Google sign-in, non-custodial wallet, tap-to-confirm consent, sponsored gas \u2014 wraps every other product), Audric Intelligence (you \u2014 the 5-system brain: Agent Harness with 34 tools, Reasoning Engine with 9 guards and 7 skill recipes, Silent Profile, Chain Memory, AdviceLog), Audric Finance (manage money on Sui \u2014 Save via NAVI lending at 3-8% APY USDC, Credit via NAVI borrowing with health factor, Swap via Cetus aggregator across 20+ DEXs at 0.1% fee, Charts for yield/health/portfolio viz), Audric Pay (move money \u2014 send USDC, receive via payment links / invoices / QR; free, global, instant on Sui), and Audric Store (creator marketplace, ships Phase 5 \u2014 say \"coming soon\" if asked). Save, swap, borrow, repay, withdraw, charts \u2192 Audric Finance. Send, receive, payment-link, invoice, QR \u2192 Audric Pay. Your silent context (profile, memory, chain facts, advice log) shapes your replies but never surfaces as a notification \u2014 you act only when the user asks, and every write waits on their tap-to-confirm via Passport. You can also call 41 paid APIs (music, image, research, translation, weather, fulfilment) via MPP micropayments using the pay_api tool \u2014 this is an internal capability, not a promoted product, so only mention it when the user asks for something that needs it.\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 NAVI lending APYs, use rates_info; for VOLO liquid staking stats, use volo_stats; for spot token prices, use token_prices.\n- For protocol-level due diligence (TVL, fees, audits, safety) on Sui DeFi protocols, use protocol_deep_dive 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 or USDsui (critical)\n- save_deposit and borrow accept ONLY USDC or USDsui. No other token can be deposited or borrowed.\n- USDC is the canonical default. USDsui is permitted because it has a productive NAVI pool (often a higher APY than USDC). All other holdings (GOLD, SUI, USDT, USDe, ETH, NAVX, WAL) are NOT saveable.\n- When asked \"how much can I save?\":\n - Report saveableUsdc from balance_check (the user's USDC wallet balance \u2014 canonical saveable).\n - If the user also holds USDsui in their wallet, report that separately as \"USDsui (saveable): X.XX\". Do NOT roll the two together \u2014 the LLM must keep the per-asset distinction so the user can pick.\n- When the user says \"save 10 USDC\" \u2192 call save_deposit with asset=\"USDC\". When they say \"save 10 USDsui\" \u2192 call with asset=\"USDsui\". Never silently substitute.\n- When the user says \"save 10\" (no asset) \u2192 call balance_check first and ask which stable they want, OR pick whichever they hold more of with a one-line explanation.\n- \"Best stable to save right now?\" \u2192 call rates_info to compare USDC vs USDsui APY on NAVI; let the user pick.\n- NEVER say a non-saveable token (GOLD, SUI, USDT, etc.) is \"in savings\" or \"earning APY in savings\". Wallet holdings \u2260 savings positions, even for stables we don't accept.\n- If user wants to save a non-saveable token, tell them to swap to USDC or USDsui first. Do NOT auto-chain swap + deposit.\n- Repay symmetry: a USDsui debt MUST be repaid with USDsui (and USDC debt with USDC). When calling repay_debt, pass asset=\"USDsui\" if the borrow is USDsui. If the user asks \"repay my debt\" and savings_info shows borrows in BOTH stables, list both and ask which to repay first. If the user holds the wrong stable, tell them to swap manually \u2014 do NOT auto-chain swap + repay.\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\": token_prices \u2192 calculate amount \u2192 swap_execute.\n- \"Best yield on SUI\": compare rates_info (NAVI lending) + volo_stats (vSUI liquid staking).\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 only accepts USDC or USDsui.\n- \"Is protocol X safe?\" / \"Tell me about NAVI\": protocol_deep_dive with the slug.\n- \"Full account report\" / \"account summary\" / \"give me everything\" / \"complete overview\": triggers the `account_report` recipe \u2014 when the recipe block appears, follow EVERY step including all six tool calls. Each step renders a distinct rich card; skipping a step means a missing card.\n\n## Safety\n- Never encourage risky financial behavior.\n- Warn when health factor < 1.5.\n- All amounts in USDC unless stated otherwise.";
2410
+ /**
2411
+ * Resolve the audric API base URL from the engine's env shim, falling
2412
+ * back to `process.env`. Returns `null` when no override is configured —
2413
+ * callers MUST treat this as "use in-engine fallback path".
2414
+ *
2415
+ * Lookup order (first defined wins):
2416
+ * 1. `env.T2000_AUDRIC_API` — canonical override
2417
+ * 2. `process.env.T2000_AUDRIC_API` — same, picked up directly
2418
+ * 3. `env.AUDRIC_INTERNAL_API_URL` — legacy alias from audric host
2419
+ * 4. `process.env.AUDRIC_INTERNAL_API_URL`
2420
+ * 5. `process.env.NEXT_PUBLIC_APP_URL` — last-ditch host hint
2421
+ */
2422
+ declare function getAudricApiBase(env?: Record<string, string>): string | null;
2423
+ interface AudricPortfolioResult {
2424
+ /** Wallet half — directly compatible with the existing `AddressPortfolio` shape. */
2425
+ portfolio: AddressPortfolio;
2426
+ /** NAVI lending positions, normalized to the engine's `ServerPositionData`. */
2427
+ positions: ServerPositionData;
2428
+ /** Net worth derived audric-side (`wallet + savings - borrows`). */
2429
+ netWorthUsd: number;
2430
+ /** `savings * savingsRate / 365`, capped at 0. */
2431
+ estimatedDailyYield: number;
2432
+ /** Per-symbol balance map — convenient for adapters that already used `WalletBalances`. */
2433
+ walletAllocations: Record<string, number>;
2434
+ }
2435
+ /**
2436
+ * Fetch the canonical portfolio snapshot from audric. Returns `null` if
2437
+ * audric isn't configured for this runtime, or if the request fails for
2438
+ * any reason — callers MUST fall back to the in-engine BlockVision +
2439
+ * NAVI path on `null`.
2440
+ */
2441
+ declare function fetchAudricPortfolio(address: string, env?: Record<string, string>, signal?: AbortSignal): Promise<AudricPortfolioResult | null>;
2442
+ interface AudricHistoryRecord {
2443
+ digest: string;
2444
+ action: string;
2445
+ label?: string;
2446
+ direction?: 'in' | 'out';
2447
+ amount?: number;
2448
+ asset?: string;
2449
+ /** Counterparty address (only set for transfers with a clear recipient). */
2450
+ recipient?: string;
2451
+ timestamp: number;
2452
+ date?: string;
2453
+ gasCost?: number;
2454
+ }
2455
+ /**
2456
+ * Fetch the canonical transaction history list from audric. Same fall
2457
+ * back contract as `fetchAudricPortfolio` — `null` means "use in-engine
2458
+ * Sui-RPC path". Audric's `/api/history` already merges `FromAddress` +
2459
+ * `ToAddress`, dedupes by digest, and parses Move calls via
2460
+ * `@t2000/sdk`'s shared parser, so the wire shape is a 1:1 match for the
2461
+ * engine's existing `TxRecord` once we rename `counterparty` →
2462
+ * `recipient`.
2463
+ */
2464
+ declare function fetchAudricHistory(address: string, opts: {
2465
+ limit?: number;
2466
+ }, env?: Record<string, string>, signal?: AbortSignal): Promise<AudricHistoryRecord[] | null>;
2467
+
2468
+ declare const DEFAULT_SYSTEM_PROMPT = "You are Audric \u2014 a financial agent on Sui. Audric is exactly five products: Audric Passport (the trust layer \u2014 Google sign-in, non-custodial wallet, tap-to-confirm consent, sponsored gas \u2014 wraps every other product), Audric Intelligence (you \u2014 the 5-system brain: Agent Harness with 34 tools, Reasoning Engine with 9 guards and 7 skill recipes, Silent Profile, Chain Memory, AdviceLog), Audric Finance (manage money on Sui \u2014 Save via NAVI lending at 3-8% APY USDC, Credit via NAVI borrowing with health factor, Swap via Cetus aggregator across 20+ DEXs at 0.1% fee, Charts for yield/health/portfolio viz), Audric Pay (move money \u2014 send USDC, receive via payment links / invoices / QR; free, global, instant on Sui), and Audric Store (creator marketplace, ships Phase 5 \u2014 say \"coming soon\" if asked). Save, swap, borrow, repay, withdraw, charts \u2192 Audric Finance. Send, receive, payment-link, invoice, QR \u2192 Audric Pay. Your silent context (profile, memory, chain facts, advice log) shapes your replies but never surfaces as a notification \u2014 you act only when the user asks, and every write waits on their tap-to-confirm via Passport. You can also call 41 paid APIs (music, image, research, translation, weather, fulfilment) via MPP micropayments using the pay_api tool \u2014 this is an internal capability, not a promoted product, so only mention it when the user asks for something that needs it.\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- 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## Caption rules (after tool calls)\n- **When a canvas was rendered (`render_canvas` was called, or any tool that auto-renders a card like balance_check / portfolio_analysis / savings_info / health_check / transaction_history): the canvas IS the answer.** Your chat message must NOT restate wallet, savings, debt, holdings, or net-worth numbers \u2014 they are already on screen. Add at most ONE sentence of context, advice, or next step (e.g. \"Your USDC is idle \u2014 consider depositing for ~4.5% APY\"), or say nothing.\n- **When NO canvas was rendered:** lead with the result and quote the actual numbers from the tool. One sentence.\n- **NEVER describe a position as \"no\", \"none\", \"minimal\", \"zero\", or \"inactive\" if the tool result contains a positive value for that field.** The tool result is the source of truth \u2014 never your interior summary. If the canvas shows $100 in savings, you cannot say \"no active savings\" in the caption.\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 NAVI lending APYs, use rates_info; for VOLO liquid staking stats, use volo_stats; for spot token prices, use token_prices.\n- For protocol-level due diligence (TVL, fees, audits, safety) on Sui DeFi protocols, use protocol_deep_dive 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 or USDsui (critical)\n- save_deposit and borrow accept ONLY USDC or USDsui. No other token can be deposited or borrowed.\n- USDC is the canonical default. USDsui is permitted because it has a productive NAVI pool (often a higher APY than USDC). All other holdings (GOLD, SUI, USDT, USDe, ETH, NAVX, WAL) are NOT saveable.\n- When asked \"how much can I save?\":\n - Report saveableUsdc from balance_check (the user's USDC wallet balance \u2014 canonical saveable).\n - If the user also holds USDsui in their wallet, report that separately as \"USDsui (saveable): X.XX\". Do NOT roll the two together \u2014 the LLM must keep the per-asset distinction so the user can pick.\n- When the user says \"save 10 USDC\" \u2192 call save_deposit with asset=\"USDC\". When they say \"save 10 USDsui\" \u2192 call with asset=\"USDsui\". Never silently substitute.\n- When the user says \"save 10\" (no asset) \u2192 call balance_check first and ask which stable they want, OR pick whichever they hold more of with a one-line explanation.\n- \"Best stable to save right now?\" \u2192 call rates_info to compare USDC vs USDsui APY on NAVI; let the user pick.\n- NEVER say a non-saveable token (GOLD, SUI, USDT, etc.) is \"in savings\" or \"earning APY in savings\". Wallet holdings \u2260 savings positions, even for stables we don't accept.\n- If user wants to save a non-saveable token, tell them to swap to USDC or USDsui first. Do NOT auto-chain swap + deposit.\n- Repay symmetry: a USDsui debt MUST be repaid with USDsui (and USDC debt with USDC). When calling repay_debt, pass asset=\"USDsui\" if the borrow is USDsui. If the user asks \"repay my debt\" and savings_info shows borrows in BOTH stables, list both and ask which to repay first. If the user holds the wrong stable, tell them to swap manually \u2014 do NOT auto-chain swap + repay.\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\": token_prices \u2192 calculate amount \u2192 swap_execute.\n- \"Best yield on SUI\": compare rates_info (NAVI lending) + volo_stats (vSUI liquid staking).\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 only accepts USDC or USDsui.\n- \"Is protocol X safe?\" / \"Tell me about NAVI\": protocol_deep_dive with the slug.\n- \"Full account report\" / \"account summary\" / \"give me everything\" / \"complete overview\": triggers the `account_report` recipe \u2014 when the recipe block appears, follow EVERY step including all six tool calls. Each step renders a distinct rich card; skipping a step means a missing card.\n\n## Safety\n- Never encourage risky financial behavior.\n- Warn when health factor < 1.5.\n- All amounts in USDC unless stated otherwise.";
2398
2469
 
2399
- export { type AddressPortfolio, AnthropicProvider, type AnthropicProviderConfig, type BalancePrices, type BalanceResult, BalanceTracker, type BuildToolOptions, CANVAS_TEMPLATES, type CanvasTemplate, type ChatParams, type CompactOptions, type ContentBlock, ContextBudget, type ContextBudgetConfig, type ConversationState, type ConversationStateStore, type CostSnapshot, CostTracker, type CostTrackerConfig, DEFAULT_GUARD_CONFIG, DEFAULT_PERMISSION_CONFIG, DEFAULT_SYSTEM_PROMPT, EarlyToolDispatcher, type EngineConfig, type EngineEvent, type GuardCheckResult, type GuardConfig, type GuardEvent, type GuardInjection, type GuardResult, type GuardRunnerState, type GuardTier, type GuardVerdict, 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 OutputConfig, PERMISSION_PRESETS, type PendingAction, type PendingActionModifiableField, type PendingReward, type PendingToolCall, type PermissionLevel, type PermissionOperation, type PermissionResponse, type PermissionRule, type PortfolioCoin, type PositionEntry, type PreflightResult, type ProtocolStats, type ProviderEvent, QueryEngine, READ_TOOLS, type RatesResult, type Recipe, type RecipePrerequisite, RecipeRegistry, type RecipeStep, type RecipeStepOnError, RetryTracker, type SSEEvent, type SavingsResult, type ServerPositionData, type SessionData, type SessionStore, type StateType, type StopReason, type SuiCoinBalance, type SystemBlock, type SystemPrompt, TOOL_FLAGS, TOOL_MODIFIABLE_FIELDS, type ThinkingConfig, type ThinkingEffort, type Tool, type ToolChoice, type ToolContext, type ToolDefinition, type ToolFlags, type ToolJsonSchema, type ToolResult, TxMutex, type UserFinancialProfile, type UserPermissionConfig, WRITE_TOOLS, type WalletCoin, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, applyToolFlags, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, claimRewardsTool, classifyEffort, clearPortfolioCache, clearPortfolioCacheFor, clearPriceMapCache, compactMessages, createGuardRunnerState, engineToSSE, estimateTokens, explainTxTool, extractConversationText, extractMcpText, fetchAddressPortfolio, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findTool, getDefaultTools, getMcpManager, getModifiableFields, getToolFlags, getWalletAddress, guardArtifactPreview, guardStaleData, hasNaviMcp, healthCheckTool, loadRecipes, microcompact, mppServicesTool, parseMcpJson, parseRecipe, parseSSE, payApiTool, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, registerEngineTools, renderCanvasTool, repayDebtTool, requireAgent, resolvePermissionTier, resolveUsdValue, runGuards, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, spendingAnalyticsTool, swapExecuteTool, swapQuoteTool, tokenPricesTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
2470
+ export { type AddressPortfolio, AnthropicProvider, type AnthropicProviderConfig, type AudricHistoryRecord, type AudricPortfolioResult, type BalancePrices, type BalanceResult, BalanceTracker, type BuildToolOptions, CANVAS_TEMPLATES, type CanvasTemplate, type ChatParams, type CompactOptions, type ContentBlock, ContextBudget, type ContextBudgetConfig, type ConversationState, type ConversationStateStore, type CostSnapshot, CostTracker, type CostTrackerConfig, DEFAULT_GUARD_CONFIG, DEFAULT_PERMISSION_CONFIG, DEFAULT_SYSTEM_PROMPT, EarlyToolDispatcher, type EngineConfig, type EngineEvent, type GuardCheckResult, type GuardConfig, type GuardEvent, type GuardInjection, type GuardResult, type GuardRunnerState, type GuardTier, type GuardVerdict, 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 OutputConfig, PERMISSION_PRESETS, type PendingAction, type PendingActionModifiableField, type PendingReward, type PendingToolCall, type PermissionLevel, type PermissionOperation, type PermissionResponse, type PermissionRule, type PortfolioCoin, type PositionEntry, type PreflightResult, type ProtocolStats, type ProviderEvent, QueryEngine, READ_TOOLS, type RatesResult, type Recipe, type RecipePrerequisite, RecipeRegistry, type RecipeStep, type RecipeStepOnError, RetryTracker, type SSEEvent, type SavingsResult, type ServerPositionData, type SessionData, type SessionStore, type StateType, type StopReason, type SuiCoinBalance, type SystemBlock, type SystemPrompt, TOOL_FLAGS, TOOL_MODIFIABLE_FIELDS, type ThinkingConfig, type ThinkingEffort, type Tool, type ToolChoice, type ToolContext, type ToolDefinition, type ToolFlags, type ToolJsonSchema, type ToolResult, TxMutex, type UserFinancialProfile, type UserPermissionConfig, WRITE_TOOLS, type WalletCoin, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, applyToolFlags, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, claimRewardsTool, classifyEffort, clearPortfolioCache, clearPortfolioCacheFor, clearPriceMapCache, compactMessages, createGuardRunnerState, engineToSSE, estimateTokens, explainTxTool, extractConversationText, extractMcpText, fetchAddressPortfolio, fetchAudricHistory, fetchAudricPortfolio, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findTool, getAudricApiBase, getDefaultTools, getMcpManager, getModifiableFields, getToolFlags, getWalletAddress, guardArtifactPreview, guardStaleData, hasNaviMcp, healthCheckTool, loadRecipes, microcompact, mppServicesTool, parseMcpJson, parseRecipe, parseSSE, payApiTool, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, registerEngineTools, renderCanvasTool, repayDebtTool, requireAgent, resolvePermissionTier, resolveUsdValue, runGuards, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, spendingAnalyticsTool, swapExecuteTool, swapQuoteTool, tokenPricesTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
package/dist/index.js CHANGED
@@ -1101,6 +1101,92 @@ function clearPriceMapCache() {
1101
1101
  priceMapCache = null;
1102
1102
  }
1103
1103
 
1104
+ // src/audric-api.ts
1105
+ var FETCH_TIMEOUT_MS = 6e3;
1106
+ function getAudricApiBase(env) {
1107
+ const fromEnv = env?.T2000_AUDRIC_API ?? env?.AUDRIC_INTERNAL_API_URL ?? null;
1108
+ if (fromEnv && fromEnv.trim().length > 0) return fromEnv.replace(/\/$/, "");
1109
+ const fromProcess = process.env.T2000_AUDRIC_API ?? process.env.AUDRIC_INTERNAL_API_URL ?? process.env.NEXT_PUBLIC_APP_URL ?? null;
1110
+ if (fromProcess && fromProcess.trim().length > 0) return fromProcess.replace(/\/$/, "");
1111
+ return null;
1112
+ }
1113
+ async function fetchAudricPortfolio(address, env, signal) {
1114
+ const base = getAudricApiBase(env);
1115
+ if (!base) return null;
1116
+ try {
1117
+ const res = await fetch(
1118
+ `${base}/api/portfolio?address=${encodeURIComponent(address)}`,
1119
+ { signal: signal ?? AbortSignal.timeout(FETCH_TIMEOUT_MS) }
1120
+ );
1121
+ if (!res.ok) {
1122
+ console.warn(`[audric-api] portfolio ${address.slice(0, 10)} \u2192 HTTP ${res.status}`);
1123
+ return null;
1124
+ }
1125
+ const json = await res.json();
1126
+ const portfolio = {
1127
+ coins: Array.isArray(json.wallet) ? json.wallet : [],
1128
+ totalUsd: json.walletValueUsd ?? 0,
1129
+ pricedAt: json.pricedAt ?? Date.now(),
1130
+ source: json.source ?? "blockvision"
1131
+ };
1132
+ const positions = {
1133
+ savings: json.positions?.savings ?? 0,
1134
+ borrows: json.positions?.borrows ?? 0,
1135
+ savingsRate: json.positions?.savingsRate ?? 0,
1136
+ healthFactor: json.positions?.healthFactor ?? null,
1137
+ maxBorrow: json.positions?.maxBorrow ?? 0,
1138
+ pendingRewards: json.positions?.pendingRewards ?? 0,
1139
+ supplies: json.positions?.supplies ?? [],
1140
+ // The engine type calls this `borrows_detail`; audric's wire shape
1141
+ // calls it `borrowsDetail`. Normalize on the engine side so
1142
+ // downstream tools can keep their existing field names.
1143
+ borrows_detail: json.positions?.borrowsDetail ?? []
1144
+ };
1145
+ return {
1146
+ portfolio,
1147
+ positions,
1148
+ netWorthUsd: json.netWorthUsd ?? portfolio.totalUsd + positions.savings - positions.borrows,
1149
+ estimatedDailyYield: json.estimatedDailyYield ?? 0,
1150
+ walletAllocations: json.walletAllocations ?? {}
1151
+ };
1152
+ } catch (err) {
1153
+ console.warn(`[audric-api] portfolio ${address.slice(0, 10)} fetch failed:`, err);
1154
+ return null;
1155
+ }
1156
+ }
1157
+ async function fetchAudricHistory(address, opts, env, signal) {
1158
+ const base = getAudricApiBase(env);
1159
+ if (!base) return null;
1160
+ const params = new URLSearchParams({ address });
1161
+ if (opts.limit != null) params.set("limit", String(opts.limit));
1162
+ try {
1163
+ const res = await fetch(`${base}/api/history?${params}`, {
1164
+ signal: signal ?? AbortSignal.timeout(FETCH_TIMEOUT_MS)
1165
+ });
1166
+ if (!res.ok) {
1167
+ console.warn(`[audric-api] history ${address.slice(0, 10)} \u2192 HTTP ${res.status}`);
1168
+ return null;
1169
+ }
1170
+ const json = await res.json();
1171
+ const items = Array.isArray(json.items) ? json.items : [];
1172
+ return items.map((item) => ({
1173
+ digest: item.digest,
1174
+ action: item.action,
1175
+ label: item.label,
1176
+ direction: item.direction,
1177
+ amount: item.amount,
1178
+ asset: item.asset,
1179
+ recipient: item.counterparty,
1180
+ timestamp: item.timestamp,
1181
+ date: item.timestamp > 0 ? new Date(item.timestamp).toISOString() : void 0,
1182
+ gasCost: item.gasCost
1183
+ }));
1184
+ } catch (err) {
1185
+ console.warn(`[audric-api] history ${address.slice(0, 10)} fetch failed:`, err);
1186
+ return null;
1187
+ }
1188
+ }
1189
+
1104
1190
  // src/tools/balance.ts
1105
1191
  var GAS_RESERVE_SUI2 = 0.05;
1106
1192
  var SUI_ADDRESS_REGEX = /^0x[a-fA-F0-9]{1,64}$/;
@@ -1186,8 +1272,15 @@ var balanceCheckTool = buildTool({
1186
1272
  const address = targetAddress;
1187
1273
  const mgr = getMcpManager(context);
1188
1274
  const hasPositionFetcher = !!context.positionFetcher;
1275
+ const audricPortfolio = await fetchAudricPortfolio(
1276
+ address,
1277
+ context.env,
1278
+ context.signal
1279
+ );
1280
+ const usingAudricSnapshot = audricPortfolio !== null;
1281
+ const audric = audricPortfolio;
1189
1282
  const [portfolio, positions, rewards, serverPositions, defiPortfolio] = await Promise.all([
1190
- loadPortfolio(
1283
+ usingAudricSnapshot ? Promise.resolve(audric.portfolio) : loadPortfolio(
1191
1284
  address,
1192
1285
  context.blockvisionApiKey,
1193
1286
  context.suiRpcUrl,
@@ -1202,7 +1295,7 @@ var balanceCheckTool = buildTool({
1202
1295
  };
1203
1296
  return fallback;
1204
1297
  }),
1205
- hasPositionFetcher ? Promise.resolve(null) : callNavi(mgr, NaviTools.GET_POSITIONS, {
1298
+ usingAudricSnapshot || hasPositionFetcher ? Promise.resolve(null) : callNavi(mgr, NaviTools.GET_POSITIONS, {
1206
1299
  address,
1207
1300
  protocols: "navi",
1208
1301
  format: "json"
@@ -1210,11 +1303,11 @@ var balanceCheckTool = buildTool({
1210
1303
  console.warn("[balance_check] NAVI GET_POSITIONS failed:", err);
1211
1304
  return null;
1212
1305
  }),
1213
- hasPositionFetcher ? Promise.resolve(null) : callNavi(mgr, NaviTools.GET_AVAILABLE_REWARDS, { address }).catch((err) => {
1306
+ usingAudricSnapshot || hasPositionFetcher ? Promise.resolve(null) : callNavi(mgr, NaviTools.GET_AVAILABLE_REWARDS, { address }).catch((err) => {
1214
1307
  console.warn("[balance_check] NAVI GET_AVAILABLE_REWARDS failed:", err);
1215
1308
  return null;
1216
1309
  }),
1217
- hasPositionFetcher ? context.positionFetcher(address).catch((err) => {
1310
+ usingAudricSnapshot ? Promise.resolve(audric.positions) : hasPositionFetcher ? context.positionFetcher(address).catch((err) => {
1218
1311
  console.warn("[balance_check] positionFetcher failed:", err);
1219
1312
  return null;
1220
1313
  }) : Promise.resolve(null),
@@ -2051,9 +2144,34 @@ var transactionHistoryTool = buildTool({
2051
2144
  displayText: `${filtered2.length} recent transaction(s)`
2052
2145
  };
2053
2146
  }
2054
- if (!targetAddress || !context.suiRpcUrl) {
2147
+ if (!targetAddress) {
2055
2148
  throw new Error("Transaction history requires a wallet address");
2056
2149
  }
2150
+ if (!input.date) {
2151
+ const audricRecords = await fetchAudricHistory(
2152
+ targetAddress,
2153
+ { limit: Math.max(limit * 4, 50) },
2154
+ context.env,
2155
+ context.signal
2156
+ );
2157
+ if (audricRecords) {
2158
+ const cutoffMs2 = Date.now() - DEFAULT_LOOKBACK_DAYS * 864e5;
2159
+ const recent2 = audricRecords.filter((r) => r.timestamp >= cutoffMs2);
2160
+ const filtered2 = finalize(recent2);
2161
+ return {
2162
+ data: {
2163
+ transactions: filtered2,
2164
+ count: filtered2.length,
2165
+ ...filterMeta,
2166
+ lookbackDays: DEFAULT_LOOKBACK_DAYS
2167
+ },
2168
+ displayText: `${filtered2.length} transaction(s) in the last ${DEFAULT_LOOKBACK_DAYS} days`
2169
+ };
2170
+ }
2171
+ }
2172
+ if (!context.suiRpcUrl) {
2173
+ throw new Error("Transaction history requires a Sui RPC URL when audric API is unavailable");
2174
+ }
2057
2175
  if (input.date) {
2058
2176
  const records2 = await queryHistoryByDate(
2059
2177
  context.suiRpcUrl,
@@ -3019,9 +3137,14 @@ var portfolioAnalysisTool = buildTool({
3019
3137
  throw new Error("No wallet address provided. Sign in first.");
3020
3138
  }
3021
3139
  const DUST_USD = 0.01;
3140
+ const audricSnapshot = await fetchAudricPortfolio(
3141
+ address,
3142
+ context.env,
3143
+ context.signal
3144
+ );
3022
3145
  const apiUrl = context.env?.AUDRIC_INTERNAL_API_URL;
3023
3146
  const [portfolio, positions, weekHistResult] = await Promise.all([
3024
- (async () => {
3147
+ audricSnapshot ? Promise.resolve(audricSnapshot.portfolio) : (async () => {
3025
3148
  if (context.portfolioCache) {
3026
3149
  const hit = context.portfolioCache.get(address);
3027
3150
  if (hit) return hit;
@@ -3035,15 +3158,14 @@ var portfolioAnalysisTool = buildTool({
3035
3158
  return fresh;
3036
3159
  })().catch((err) => {
3037
3160
  console.warn("[portfolio_analysis] portfolio fetch failed:", err);
3038
- const empty = {
3161
+ return {
3039
3162
  coins: [],
3040
3163
  totalUsd: 0,
3041
3164
  pricedAt: Date.now(),
3042
3165
  source: "sui-rpc-degraded"
3043
3166
  };
3044
- return empty;
3045
3167
  }),
3046
- context.positionFetcher ? context.positionFetcher(address).catch((err) => {
3168
+ audricSnapshot ? Promise.resolve(audricSnapshot.positions) : context.positionFetcher ? context.positionFetcher(address).catch((err) => {
3047
3169
  console.warn("[portfolio_analysis] positionFetcher failed:", err);
3048
3170
  return null;
3049
3171
  }) : Promise.resolve(null),
@@ -4104,10 +4226,14 @@ var DEFAULT_SYSTEM_PROMPT = `You are Audric \u2014 a financial agent on Sui. Aud
4104
4226
  ## Response rules
4105
4227
  - 1-2 sentences max. No bullet lists unless asked. No preambles.
4106
4228
  - Never say "Would you like me to...", "Sure!", "Great question!", "Absolutely!" \u2014 just do it or say you can't.
4107
- - Lead with the result. After tool calls, state the outcome with real numbers. Done.
4108
4229
  - Present amounts as $1,234.56 and rates as X.XX% APY.
4109
4230
  - Show top 3 results unless asked for more. Summarize totals in one line.
4110
4231
 
4232
+ ## Caption rules (after tool calls)
4233
+ - **When a canvas was rendered (\`render_canvas\` was called, or any tool that auto-renders a card like balance_check / portfolio_analysis / savings_info / health_check / transaction_history): the canvas IS the answer.** Your chat message must NOT restate wallet, savings, debt, holdings, or net-worth numbers \u2014 they are already on screen. Add at most ONE sentence of context, advice, or next step (e.g. "Your USDC is idle \u2014 consider depositing for ~4.5% APY"), or say nothing.
4234
+ - **When NO canvas was rendered:** lead with the result and quote the actual numbers from the tool. One sentence.
4235
+ - **NEVER describe a position as "no", "none", "minimal", "zero", or "inactive" if the tool result contains a positive value for that field.** The tool result is the source of truth \u2014 never your interior summary. If the canvas shows $100 in savings, you cannot say "no active savings" in the caption.
4236
+
4111
4237
  ## Execution rule
4112
4238
  Only 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.
4113
4239
 
@@ -4223,7 +4349,8 @@ var DEFAULT_GUARD_CONFIG = {
4223
4349
  inputValidation: true,
4224
4350
  addressSource: true,
4225
4351
  assetIntent: true,
4226
- swapPreview: true
4352
+ swapPreview: true,
4353
+ addressScope: true
4227
4354
  };
4228
4355
  var BalanceTracker = class {
4229
4356
  lastBalanceAt = 0;
@@ -4528,6 +4655,48 @@ function guardAddressSource(tool, call, userText, contacts, walletAddress) {
4528
4655
  message: `Safety check failed: the recipient address "${rawTo}" was not provided by the user (no saved contact matches, address is not the user's own wallet, and it does not appear verbatim in the user's recent messages). For safety, addresses must be supplied directly by the user \u2014 never reconstructed from memory or partial recall. Ask the user to paste the destination address again exactly.`
4529
4656
  };
4530
4657
  }
4658
+ var READ_TOOLS_WITH_ADDRESS_PARAM = /* @__PURE__ */ new Set([
4659
+ "balance_check",
4660
+ "portfolio_analysis",
4661
+ "transaction_history",
4662
+ "savings_info",
4663
+ "health_check",
4664
+ "spending_analytics",
4665
+ "yield_summary",
4666
+ "activity_summary",
4667
+ "explain_tx"
4668
+ ]);
4669
+ var SUI_ADDRESS_IN_TEXT_REGEX = /0x[a-fA-F0-9]{60,64}/g;
4670
+ function guardAddressScope(tool, call, userText, walletAddress) {
4671
+ if (!READ_TOOLS_WITH_ADDRESS_PARAM.has(tool.name)) {
4672
+ return { verdict: "pass", gate: "address_scope", tier: "safety" };
4673
+ }
4674
+ const matches = userText.match(SUI_ADDRESS_IN_TEXT_REGEX);
4675
+ if (!matches || matches.length === 0) {
4676
+ return { verdict: "pass", gate: "address_scope", tier: "safety" };
4677
+ }
4678
+ const ownWallet = walletAddress ? normalizeAddress(walletAddress) : null;
4679
+ const thirdPartyAddresses = Array.from(
4680
+ new Set(matches.map(normalizeAddress).filter((a) => a !== ownWallet))
4681
+ );
4682
+ if (thirdPartyAddresses.length === 0) {
4683
+ return { verdict: "pass", gate: "address_scope", tier: "safety" };
4684
+ }
4685
+ const input = call.input;
4686
+ const callAddress = typeof input.address === "string" && input.address.length > 0 ? normalizeAddress(input.address) : null;
4687
+ if (callAddress && thirdPartyAddresses.includes(callAddress)) {
4688
+ return { verdict: "pass", gate: "address_scope", tier: "safety" };
4689
+ }
4690
+ const target = thirdPartyAddresses[0];
4691
+ const omittedHint = callAddress ? `with address: "${callAddress}"` : "without an `address` field (which defaults to the signed-in user)";
4692
+ const mentionedHint = thirdPartyAddresses.length === 1 ? `address ${target}` : `${thirdPartyAddresses.length} third-party addresses (first: ${target})`;
4693
+ return {
4694
+ verdict: "block",
4695
+ gate: "address_scope",
4696
+ tier: "safety",
4697
+ message: `Address-scope mismatch: the user's recent messages mention ${mentionedHint} but ${tool.name} was called ${omittedHint}. Re-issue ${tool.name} with \`address: "${target}"\` to inspect the wallet the user actually asked about. Never default to the signed-in user when the user named a different wallet.`
4698
+ };
4699
+ }
4531
4700
  function guardArtifactPreview(result) {
4532
4701
  if (!result || typeof result !== "object") return null;
4533
4702
  const r = result;
@@ -4611,6 +4780,16 @@ function runGuards(tool, call, state, config, conversationContext, onGuardFired,
4611
4780
  if (config.assetIntent !== false) {
4612
4781
  results.push(guardAssetIntent(tool, call, conversationContext.recentUserText));
4613
4782
  }
4783
+ if (config.addressScope !== false) {
4784
+ results.push(
4785
+ guardAddressScope(
4786
+ tool,
4787
+ call,
4788
+ conversationContext.recentUserText,
4789
+ identity?.walletAddress
4790
+ )
4791
+ );
4792
+ }
4614
4793
  if (config.swapPreview !== false) {
4615
4794
  results.push(guardSwapPreview(tool, call, state.swapQuoteTracker));
4616
4795
  }
@@ -6267,8 +6446,20 @@ function validateHistory(messages) {
6267
6446
  merged.push({ role: msg.role, content: [...msg.content] });
6268
6447
  }
6269
6448
  }
6270
- while (merged.length > 0 && merged[0].role !== "user") {
6271
- merged.shift();
6449
+ while (merged.length > 0) {
6450
+ if (merged[0].role !== "user") {
6451
+ merged.shift();
6452
+ continue;
6453
+ }
6454
+ const cleaned = merged[0].content.filter((b) => b.type !== "tool_result");
6455
+ if (cleaned.length === 0) {
6456
+ merged.shift();
6457
+ continue;
6458
+ }
6459
+ if (cleaned.length !== merged[0].content.length) {
6460
+ merged[0] = { role: "user", content: cleaned };
6461
+ }
6462
+ break;
6272
6463
  }
6273
6464
  return merged;
6274
6465
  }
@@ -7363,6 +7554,6 @@ function sanitizeAnthropicMessages(messages) {
7363
7554
  return merged;
7364
7555
  }
7365
7556
 
7366
- export { AnthropicProvider, BalanceTracker, CANVAS_TEMPLATES, ContextBudget, CostTracker, DEFAULT_GUARD_CONFIG, DEFAULT_PERMISSION_CONFIG, DEFAULT_SYSTEM_PROMPT, EarlyToolDispatcher, McpClientManager, McpResponseCache, MemorySessionStore, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_SERVER_NAME, NaviTools, PERMISSION_PRESETS, QueryEngine, READ_TOOLS, RecipeRegistry, RetryTracker, TOOL_FLAGS, TOOL_MODIFIABLE_FIELDS, TxMutex, WRITE_TOOLS, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, applyToolFlags, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, claimRewardsTool, classifyEffort, clearPortfolioCache, clearPortfolioCacheFor, clearPriceMapCache, compactMessages, createGuardRunnerState, engineToSSE, estimateTokens, explainTxTool, extractConversationText, extractMcpText, fetchAddressPortfolio, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findTool, getDefaultTools, getMcpManager, getModifiableFields, getToolFlags, getWalletAddress, guardArtifactPreview, guardStaleData, hasNaviMcp, healthCheckTool, loadRecipes, microcompact, mppServicesTool, parseMcpJson, parseRecipe, parseSSE, payApiTool, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, registerEngineTools, renderCanvasTool, repayDebtTool, requireAgent, resolvePermissionTier, resolveUsdValue, runGuards, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, spendingAnalyticsTool, swapExecuteTool, swapQuoteTool, tokenPricesTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
7557
+ export { AnthropicProvider, BalanceTracker, CANVAS_TEMPLATES, ContextBudget, CostTracker, DEFAULT_GUARD_CONFIG, DEFAULT_PERMISSION_CONFIG, DEFAULT_SYSTEM_PROMPT, EarlyToolDispatcher, McpClientManager, McpResponseCache, MemorySessionStore, NAVI_MCP_CONFIG, NAVI_MCP_URL, NAVI_SERVER_NAME, NaviTools, PERMISSION_PRESETS, QueryEngine, READ_TOOLS, RecipeRegistry, RetryTracker, TOOL_FLAGS, TOOL_MODIFIABLE_FIELDS, TxMutex, WRITE_TOOLS, activitySummaryTool, adaptAllMcpTools, adaptAllServerTools, adaptMcpTool, applyToolFlags, balanceCheckTool, borrowTool, budgetToolResult, buildCachedSystemPrompt, buildMcpTools, buildProactivenessInstructions, buildProfileContext, buildSelfEvaluationInstruction, buildStateContext, buildTool, claimRewardsTool, classifyEffort, clearPortfolioCache, clearPortfolioCacheFor, clearPriceMapCache, compactMessages, createGuardRunnerState, engineToSSE, estimateTokens, explainTxTool, extractConversationText, extractMcpText, fetchAddressPortfolio, fetchAudricHistory, fetchAudricPortfolio, fetchAvailableRewards, fetchBalance, fetchHealthFactor, fetchPositions, fetchProtocolStats, fetchRates, fetchSavings, fetchTokenPrices, fetchWalletCoins, findTool, getAudricApiBase, getDefaultTools, getMcpManager, getModifiableFields, getToolFlags, getWalletAddress, guardArtifactPreview, guardStaleData, hasNaviMcp, healthCheckTool, loadRecipes, microcompact, mppServicesTool, parseMcpJson, parseRecipe, parseSSE, payApiTool, portfolioAnalysisTool, protocolDeepDiveTool, ratesInfoTool, registerEngineTools, renderCanvasTool, repayDebtTool, requireAgent, resolvePermissionTier, resolveUsdValue, runGuards, runTools, saveContactTool, saveDepositTool, savingsInfoTool, sendTransferTool, serializeSSE, spendingAnalyticsTool, swapExecuteTool, swapQuoteTool, tokenPricesTool, toolNameToOperation, toolsToDefinitions, transactionHistoryTool, transformBalance, transformHealthFactor, transformPositions, transformRates, transformRewards, transformSavings, updateGuardStateAfterToolResult, validateHistory, voloStakeTool, voloStatsTool, voloUnstakeTool, webSearchTool, withdrawTool, yieldSummaryTool };
7367
7558
  //# sourceMappingURL=index.js.map
7368
7559
  //# sourceMappingURL=index.js.map