@t2000/cli 2.2.0 → 2.4.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.
|
@@ -140539,7 +140539,88 @@ function registerSafetyTools(server, agent) {
|
|
|
140539
140539
|
);
|
|
140540
140540
|
}
|
|
140541
140541
|
init_zod();
|
|
140542
|
-
|
|
140542
|
+
var cachedSkills = null;
|
|
140543
|
+
function getBakedSkills() {
|
|
140544
|
+
if (cachedSkills) return cachedSkills;
|
|
140545
|
+
const raw = '[{"name":"t2000-account-report","description":"Render a complete account snapshot \u2014 wallet, savings, debt, recent activity, yield, and portfolio allocation, plus a short headline. Use when asked for a full report, account summary, \\"everything about my account\\", or \\"show me the full picture\\". Multi-tool orchestration \u2014 no single CLI command covers all six dimensions.","body":"# t2000: Account Report\\n\\n## Purpose\\nRender a complete account snapshot across six dimensions \u2014 wallet, savings,\\ndebt, recent activity, yield, portfolio allocation \u2014 followed by a 2\u20133\\nsentence headline. This is a **multi-tool orchestration**, not a single CLI\\ncommand. The right call sequence depends on the consumer:\\n\\n| Consumer | Call pattern |\\n|---|---|\\n| **MCP / Cursor / Claude Desktop** | `t2000_overview` covers wallet + savings + debt + health + earnings + rewards in one call. Add `t2000_history` (limit: 20) and `t2000_positions` if you also want activity and per-position APYs. |\\n| **CLI** | `t2000 balance --show-limits` + `t2000 positions` + `t2000 history --limit 20` |\\n| **Engine (audric/web)** | 6 parallel read tools \u2014 one per rendered card (see below). Calling fewer tools = missing cards. |\\n\\n## Engine orchestration (audric/web)\\n\\nWhen called inside the Audric chat agent, each read tool renders a\\ncanvas card. **Skipping a tool = missing card.** Always emit all six\\ntool_use blocks in parallel in the same assistant turn:\\n\\n| Tool | Card | Purpose |\\n|---|---|---|\\n| `balance_check` | BALANCE CHECK | Wallet, savings, debt, total |\\n| `savings_info` | SAVINGS INFO | Per-position breakdown, supply/borrow APY, daily earnings |\\n| `health_check` | HEALTH CHECK | Health factor, supplied, borrowed, max borrow, liquidation threshold |\\n| `activity_summary` | ACTIVITY SUMMARY | Monthly tx breakdown by category |\\n| `yield_summary` | YIELD SUMMARY | Today / week / month / all-time earnings, projected yearly |\\n| `portfolio_analysis` | PORTFOLIO ANALYSIS | Allocation %, week change, insights |\\n\\nAfter all six cards render, write a **2\u20133 sentence headline** that:\\n- Leads with net worth and weekly change.\\n- Mentions health factor in one phrase.\\n- Ends with the single most actionable insight (idle USDC, debt repayment, rate gap, etc).\\n- Does **NOT** narrate the cards\' contents \u2014 they render themselves.\\n- Does **NOT** list asset percentages, APYs, or savings positions in prose.\\n\\nMax 3 sentences total.\\n\\n## CLI quick command (no canvas)\\n\\nFor terminal users who just want the numbers in their shell:\\n\\n```bash\\nt2000 balance --show-limits\\nt2000 positions\\nt2000 history --limit 20\\n```\\n\\nThese three commands cover wallet + per-position APYs + recent activity.\\nFor a one-shot machine-parseable version, add `--json` to each.\\n\\n## Notes\\n\\n- This skill orchestrates **read-only** tools \u2014 no signatures, no on-chain writes.\\n- For a workflow-shaped advisor brief on top of this snapshot (recommendations, USDC APY gap, rebalance suggestion), use the `financial-report` MCP prompt \u2014 it composes this skill plus advisor framing.\\n- If the user holds non-USDC tokens, the portfolio card surfaces them but does not flag them as \\"saveable\\" \u2014 see `t2000-save` for the USDC/USDsui save-eligibility rule."},{"name":"t2000-borrow","description":"Borrow USDC or USDsui against savings collateral. Use when asked to borrow, take a loan, get credit, leverage savings, or access funds without withdrawing from savings. A 0.05% protocol fee applies. Only accepts USDC or USDsui. Always validates projected health factor before signing \u2014 refuses if HF would drop below 1.5.","body":"# t2000: Borrow USDC or USDsui\\n\\n## Purpose\\nTake a collateralized loan using savings deposits as collateral.\\nBorrowed funds go to the available balance. A 0.05% protocol fee applies.\\nUSDsui is permitted as a strategic exception (v0.51.0+) alongside USDC \u2014\\nboth have NAVI lending pools.\\n\\n## Command\\n```bash\\nt2000 borrow <amount> [--asset USDC|USDsui]\\n\\n# Examples:\\nt2000 borrow 40 # 40 USDC (default)\\nt2000 borrow 100 --asset USDsui # 100 USDsui\\n```\\n\\n`--asset` defaults to USDC when omitted.\\n\\n## Pre-borrow safety check (always runs)\\n\\nBefore broadcasting the borrow transaction, t2000 evaluates the projected\\nhealth factor and routes the user through one of three paths:\\n\\n| Projected HF after borrow | What happens |\\n|---|---|\\n| **< 1.5** | **Refuse** \u2014 borrow blocked with `HEALTH_FACTOR_TOO_LOW`. Error includes `maxBorrow` (the largest amount that keeps HF \u2265 1.5). Suggest: repay existing debt OR add more collateral. |\\n| **1.5 \u2013 2.0** | **Warn** \u2014 surface the projected HF and require explicit user confirmation. Always state: borrow amount, projected HF, current borrow APY. Do NOT silently proceed. |\\n| **> 2.0** | **Proceed** \u2014 borrow is well-collateralized, no extra confirmation needed beyond the standard signing flow. |\\n\\nAlways state to the user: **borrow amount**, **interest rate**, and\\n**projected health factor** before signing.\\n\\n## Engine orchestration (audric/web)\\n\\nWhen called inside the Audric chat agent:\\n\\n1. Call `health_check` first to get current HF and `maxBorrow`.\\n2. Compute projected HF: `(supplied \xD7 liquidationThreshold) / (borrowed + amountUsd)`.\\n3. Apply the table above \u2014 refuse / warn / proceed.\\n4. On user confirmation, emit `borrow({ amount, asset })` as the write tool_use.\\n\\nBorrows are always **single-write** \u2014 never bundle with another write in a\\nPayment Intent. The user must consciously accept the debt.\\n\\n## Fees\\n\\n- Protocol fee: 0.05% of the borrow amount\\n\\n## Output\\n\\n```\\n\u2713 Borrowed $XX.XX <asset>\\n Health Factor: X.XX\\n Borrow APY: X.XX%\\n Tx: https://suiscan.xyz/mainnet/tx/0x...\\n```\\n\\n## Error handling\\n\\n- `NO_COLLATERAL` \u2014 no savings deposited to borrow against. Use `t2000 save` first.\\n- `HEALTH_FACTOR_TOO_LOW` \u2014 borrow would drop HF below 1.5. Error data includes `maxBorrow`. Suggest: repay debt or add collateral.\\n- `UNSUPPORTED_ASSET` \u2014 asset is not USDC or USDsui. Other tokens cannot be borrowed (NAVI doesn\'t have pools for them).\\n\\n## Repayment symmetry (important)\\n\\n**A USDsui borrow MUST be repaid with USDsui.** A USDC borrow MUST be repaid\\nwith USDC. The SDK fetches the matching coin type per borrow asset. If the\\nuser holds only the wrong stable, tell them to swap manually first \u2014 never\\nauto-chain swap + repay. See `t2000-repay` for the repay flow.\\n\\n## What\'s NOT permitted\\n\\n- Borrowing in any asset other than USDC or USDsui (no SUI, GOLD, USDT, ETH borrows \u2014 NAVI doesn\'t have lending pools for those).\\n- Borrowing without a savings position (collateral first).\\n- Borrowing that drops HF below 1.5 (always refused; safety-critical)."},{"name":"t2000-check-balance","description":"Check the t2000 agent wallet balance on Sui. Use when asked about wallet balance, how much USDC is available, savings balance, gas reserve, or total funds. Also use before any send or borrow operation to confirm sufficient funds exist.","body":"# t2000: Check Balance\\n\\n## Purpose\\nFetch the current balance across all accounts: available USDC,\\nsavings (NAVI), gas reserve (SUI), and total value.\\n\\n## Commands\\n```bash\\nt2000 balance # human-readable summary\\nt2000 balance --show-limits # includes maxWithdraw, maxBorrow, healthFactor\\nt2000 balance --json # machine-parseable JSON (works on all commands)\\n```\\n\\n## Output (default)\\n```\\nAvailable: $150.00 (checking \u2014 spendable)\\nSavings: $2,000.00 (earning 5.10% APY)\\nGas: 0.50 SUI (~$0.50)\\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\\nTotal: $2,150.50\\nEarning ~$0.27/day\\n```\\n\\n## Output (--show-limits)\\nAppends to the above:\\n```\\nLimits:\\n Max withdraw: $XX.XX\\n Max borrow: $XX.XX\\n Health factor: X.XX (\u221E if no active loan)\\n```\\n\\n## Notes\\n- `gasReserve.usdEquiv` is an estimate at current SUI price; it fluctuates\\n- If balance shows $0.00 available and wallet was just created, fund it first\\n via Coinbase Onramp or a direct USDC transfer to the wallet address\\n- `--json` is a global flag that works on all t2000 commands, not just balance"},{"name":"t2000-contacts","description":"Manage contacts \u2014 save a name-to-address mapping so the user can send money by name instead of pasting raw Sui addresses. Use when asked to add, remove, or list contacts, or to look up a saved address.","body":"# t2000: Contacts\\n\\n## Purpose\\nLet users send money by name instead of raw addresses. Contacts are stored\\nlocally in `~/.t2000/contacts.json` \u2014 no blockchain lookups, no network calls.\\n\\n## Commands\\n\\n```bash\\n# List all contacts\\nt2000 contacts\\n\\n# Add or update a contact\\nt2000 contacts add <name> <address>\\n\\n# Remove a contact\\nt2000 contacts remove <name>\\n```\\n\\n## Examples\\n\\n```bash\\nt2000 contacts add Tom 0x8b3e4f2a...\\n# \u2713 Added Tom (0x8b3e...f4a2)\\n\\nt2000 contacts add Tom 0xNEWADDRESS...\\n# \u2713 Updated Tom (0xNEWA...RESS)\\n\\nt2000 contacts remove Tom\\n# \u2713 Removed Tom\\n\\nt2000 contacts\\n# Contacts\\n# \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\\n# Tom 0x8b3e...f4a2\\n# Alice 0x40cd...3e62\\n```\\n\\n## Sending by name\\n\\nOnce a contact is saved, use the name directly in `t2000 send`:\\n\\n```bash\\nt2000 send 50 USDC to Tom\\n# \u2713 Sent $50.00 USDC \u2192 Tom (0x8b3e...f4a2)\\n```\\n\\n## Name rules\\n- Letters, numbers, underscores only\\n- Case-insensitive (Tom = tom = TOM)\\n- Max 32 characters\\n- Reserved names: `to`, `all`, `address`\\n- Cannot start with `0x`\\n\\n## No PIN required\\nContact commands are local file operations \u2014 no wallet access, no PIN prompt.\\n\\n## JSON mode\\nAll subcommands support `--json` for structured output:\\n\\n```bash\\nt2000 contacts --json\\nt2000 contacts add Tom 0x... --json\\nt2000 contacts remove Tom --json\\n```\\n\\n## Error handling\\n- `INVALID_CONTACT_NAME`: name violates naming rules\\n- `CONTACT_NOT_FOUND`: name not in contacts when sending\\n- `INVALID_ADDRESS`: address provided to `add` is not a valid Sui address"},{"name":"t2000-engine","description":"Use the @t2000/engine package to build conversational AI agents with financial capabilities. Use when asked to set up QueryEngine, build custom tools, configure LLM providers, handle streaming events, or integrate with MCP servers. Powers the Audric consumer product.","body":"# t2000: Agent Engine\\n\\n## Purpose\\nBuild conversational AI agents with financial capabilities on Sui.\\n`@t2000/engine` provides QueryEngine, 12 financial tools, LLM orchestration,\\nMCP client/server integration, streaming, sessions, and cost tracking.\\n\\n## Quick Start\\n```typescript\\nimport { QueryEngine, AnthropicProvider, getDefaultTools } from \'@t2000/engine\';\\nimport { T2000 } from \'@t2000/sdk\';\\n\\nconst agent = await T2000.create({ pin: process.env.T2000_PIN });\\n\\nconst engine = new QueryEngine({\\n provider: new AnthropicProvider({ apiKey: process.env.ANTHROPIC_API_KEY }),\\n agent,\\n tools: getDefaultTools(),\\n});\\n\\nfor await (const event of engine.submitMessage(\'What is my balance?\')) {\\n if (event.type === \'text_delta\') process.stdout.write(event.text);\\n}\\n```\\n\\n## Building Custom Tools\\n```typescript\\nimport { z } from \'zod\';\\nimport { buildTool } from \'@t2000/engine\';\\n\\nconst myTool = buildTool({\\n name: \'my_tool\',\\n description: \'Tool description for the LLM\',\\n inputSchema: z.object({ query: z.string() }),\\n isReadOnly: true,\\n permissionLevel: \'auto\',\\n async call(input, context) {\\n return { data: { result: input.query }, displayText: `Result: ${input.query}` };\\n },\\n});\\n```\\n\\n## Permission Levels\\n| Level | Behavior | Use for |\\n|-------|----------|---------|\\n| `auto` | Executes immediately | Read-only queries |\\n| `confirm` | Yields `pending_action`, client executes and resumes | Financial writes |\\n| `explicit` | Never auto-dispatched by LLM | Dangerous operations |\\n\\n## Event Types\\n```typescript\\n// Handle events from engine.submitMessage()\\nfor await (const event of engine.submitMessage(prompt)) {\\n switch (event.type) {\\n case \'text_delta\': // LLM text chunk\\n case \'tool_start\': // Tool execution beginning\\n case \'tool_result\': // Tool execution complete\\n case \'pending_action\': // Write tool needs approval \u2192 client executes, then resumes\\n case \'turn_complete\': // Conversation turn finished\\n case \'usage\': // Token usage report\\n case \'error\': // Unrecoverable error\\n }\\n}\\n```\\n\\n## MCP Client (consume external MCPs)\\n```typescript\\nimport { McpClientManager, NAVI_MCP_CONFIG } from \'@t2000/engine\';\\n\\nconst mcpManager = new McpClientManager();\\nawait mcpManager.connect(NAVI_MCP_CONFIG);\\n\\n// Read tools auto-use MCP when available, SDK as fallback\\nconst engine = new QueryEngine({\\n provider,\\n agent,\\n mcpManager,\\n walletAddress: \'0x...\',\\n tools: getDefaultTools(),\\n});\\n```\\n\\n## MCP Server (expose tools to AI clients)\\n```typescript\\nimport { registerEngineTools, getDefaultTools } from \'@t2000/engine\';\\nimport { McpServer } from \'@modelcontextprotocol/sdk/server/mcp.js\';\\n\\nconst server = new McpServer({ name: \'audric\', version: \'0.1.0\' });\\nregisterEngineTools(server, getDefaultTools());\\n// Tools exposed as audric_balance_check, audric_save_deposit, etc.\\n```\\n\\n## SSE Streaming (web apps)\\n```typescript\\n// [v2.2.0 / SPEC 37 v0.7a Phase 5 Slice A] `engineToSSE` removed \u2014\\n// iterate EngineEvent raw and call serializeSSE per event. Audric chat +\\n// resume routes have used this pattern since v1.4.2 (Spec G3). Hosts that\\n// want the SPEC 21.1 routing/quoting/etc \u2192 stream_state choreography wrap\\n// with `withStreamState` directly.\\nimport { serializeSSE, withStreamState } from \'@t2000/engine\';\\n\\nfor await (const event of withStreamState(engine.submitMessage(prompt))) {\\n const wireBytes = event.type === \'error\'\\n ? serializeSSE({ type: \'error\', message: event.error.message })\\n : serializeSSE(event);\\n // Send wireBytes to client via SSE\\n}\\n// Write tools yield pending_action \u2192 client executes on-chain \u2192 POST /api/engine/resume\\n```\\n\\n## Built-in Tools (12)\\n\\n### Read (parallel, auto-approved)\\n`balance_check`, `savings_info`, `health_check`, `rates_info`, `transaction_history`\\n\\n### Write (serial, confirmation required)\\n`save_deposit`, `withdraw`, `send_transfer`, `borrow`, `repay_debt`, `claim_rewards`, `pay_api`\\n\\n## Configuration\\n```typescript\\nnew QueryEngine({\\n provider: new AnthropicProvider({ apiKey }), // Required\\n agent, // T2000 SDK instance\\n mcpManager, // McpClientManager for MCP-first reads\\n walletAddress, // Sui address for MCP reads\\n tools: getDefaultTools(),\\n systemPrompt, // Override default Audric prompt\\n model: \'claude-sonnet-4-20250514\',\\n maxTurns: 10,\\n maxTokens: 4096,\\n costTracker: { budgetLimitUsd: 1.0 },\\n});\\n```\\n\\n## Key Imports\\n```typescript\\n// Core\\nimport { QueryEngine, AnthropicProvider, getDefaultTools } from \'@t2000/engine\';\\n// Tools\\nimport { buildTool, READ_TOOLS, WRITE_TOOLS } from \'@t2000/engine\';\\n// Streaming (`engineToSSE` removed in v2.2.0 \u2014 see \\"SSE Streaming\\" above)\\nimport { serializeSSE, parseSSE, withStreamState } from \'@t2000/engine\';\\n// Sessions\\nimport { MemorySessionStore } from \'@t2000/engine\';\\n// Cost\\nimport { CostTracker } from \'@t2000/engine\';\\n// MCP\\nimport { McpClientManager, NAVI_MCP_CONFIG, buildMcpTools, registerEngineTools } from \'@t2000/engine\';\\n```"},{"name":"t2000-mcp","description":"Connect a t2000 agent bank account to Claude Desktop, Cursor, Cline, Continue, or any MCP-compatible client. Use when asked to set up MCP, paste an MCP server config, install @t2000/mcp, or troubleshoot why the MCP server \\"doesn\'t do anything\\" when run from a terminal. Provides 29 tools and 14 prompts over stdio.","body":"# t2000: MCP Server\\n\\n## Purpose\\nExpose a t2000 agent bank account (Sui wallet + DeFi positions) to any\\nMCP-compatible AI client over stdio. **29 tools, 14 prompts**, safeguard\\nenforced. No global install required \u2014 the recommended path uses `npx`\\nso the AI client always pulls the latest published version.\\n\\n## \u26A0\uFE0F The most common confusion\\n\\n**`npx @t2000/mcp` is NOT a command you run from a terminal to \\"use\\" the\\nMCP server.** It is a JSON-RPC server that listens silently on `stdin`.\\nIf you run it manually it will appear to hang \u2014 that\'s correct behavior.\\nIt is meant to be launched as a subprocess by an AI client (Claude\\nDesktop, Cursor, etc.) which speaks JSON-RPC to it over `stdin`/`stdout`.\\n\\nThe JSON snippets below go into your **AI client\'s MCP settings file**,\\nnot into a shell.\\n\\n## Setup\\n\\n### 1. Create a wallet + safeguards (one-time, in a terminal)\\n\\n```bash\\n# Install CLI long enough to bootstrap a wallet and set safety limits\\nnpx @t2000/cli init\\nnpx @t2000/cli config set maxPerTx 100\\nnpx @t2000/cli config set maxDailySend 500\\n\\n# Create a session so MCP can reuse the saved PIN\\nnpx @t2000/cli balance\\n```\\n\\nThe MCP server **refuses to start** until `maxPerTx` and `maxDailySend`\\nare configured. This is intentional.\\n\\n### 2. Add the MCP server to your AI client\\n\\nRecommended config (auto-updates on every launch, no global install):\\n\\n```json\\n{\\n \\"mcpServers\\": {\\n \\"t2000\\": {\\n \\"command\\": \\"npx\\",\\n \\"args\\": [\\"-y\\", \\"@t2000/mcp@latest\\"]\\n }\\n }\\n}\\n```\\n\\nAlternative (if `@t2000/cli` is already installed globally):\\n\\n```json\\n{\\n \\"mcpServers\\": {\\n \\"t2000\\": {\\n \\"command\\": \\"t2000\\",\\n \\"args\\": [\\"mcp\\"]\\n }\\n }\\n}\\n```\\n\\n### 3. Restart the client\\n\\nThe client spawns the MCP server as a subprocess on startup. You should\\nsee `t2000_*` tools appear in the tool list.\\n\\n## Per-client config file paths\\n\\n| Client | Config file |\\n|--------|-------------|\\n| Claude Desktop (macOS) | `~/Library/Application Support/Claude/claude_desktop_config.json` |\\n| Claude Desktop (Windows) | `%APPDATA%\\\\Claude\\\\claude_desktop_config.json` |\\n| Cursor | Settings \u2192 MCP \u2192 Add new MCP server (or `~/.cursor/mcp.json`) |\\n| Cline | VSCode settings \u2192 `cline.mcpServers` |\\n| Continue | `~/.continue/config.json` under `mcpServers` |\\n\\n## Verification (optional, before wiring into a client)\\n\\nConfirm the server responds to a real MCP `initialize` request:\\n\\n```bash\\nprintf \'%s\\\\n\' \\\\\\n \'{\\"jsonrpc\\":\\"2.0\\",\\"id\\":1,\\"method\\":\\"initialize\\",\\"params\\":{\\"protocolVersion\\":\\"2024-11-05\\",\\"capabilities\\":{},\\"clientInfo\\":{\\"name\\":\\"test\\",\\"version\\":\\"1.0\\"}}}\' \\\\\\n | npx -y @t2000/mcp@latest\\n```\\n\\nYou should see a JSON response containing `\\"serverInfo\\":{\\"name\\":\\"t2000\\"...}`\\nand exit. If you see that, the server is healthy and ready to be launched\\nby a client.\\n\\n## Available Tools (29)\\n\\n### Read-only (15)\\n| Tool | Description |\\n|------|-------------|\\n| `t2000_overview` | Complete account snapshot in one call |\\n| `t2000_balance` | Current balance |\\n| `t2000_address` | Wallet address |\\n| `t2000_positions` | Lending positions |\\n| `t2000_rates` | Best interest rates per asset |\\n| `t2000_all_rates` | Per-protocol rate comparison |\\n| `t2000_health` | Health factor |\\n| `t2000_history` | Transaction history |\\n| `t2000_earnings` | Yield earnings |\\n| `t2000_fund_status` | Savings fund status |\\n| `t2000_pending_rewards` | Pending protocol rewards |\\n| `t2000_deposit_info` | Deposit instructions |\\n| `t2000_receive` | Generate payment request with address, nonce, and Payment Kit URI (`sui:pay?\u2026`) |\\n| `t2000_services` | List all MPP services and endpoints |\\n| `t2000_contacts` | List saved contacts |\\n\\n### State-changing (12)\\nAll support `dryRun: true` for previews without signing.\\n\\n| Tool | Description |\\n|------|-------------|\\n| `t2000_send` | Send USDC |\\n| `t2000_save` | Deposit to savings |\\n| `t2000_withdraw` | Withdraw from savings |\\n| `t2000_borrow` | Borrow against collateral |\\n| `t2000_repay` | Repay debt |\\n| `t2000_claim_rewards` | Claim pending protocol rewards |\\n| `t2000_pay` | Pay for and call any MPP API service with USDC |\\n| `t2000_swap` | Execute a token swap via Cetus Aggregator |\\n| `t2000_stake` | Stake SUI for vSUI via VOLO liquid staking |\\n| `t2000_unstake` | Unstake vSUI and redeem SUI |\\n| `t2000_contact_add` | Save a contact name \u2192 address |\\n| `t2000_contact_remove` | Remove a saved contact |\\n\\n### Safety (2)\\n| Tool | Description |\\n|------|-------------|\\n| `t2000_config` | View/set limits |\\n| `t2000_lock` | Emergency freeze |\\n\\n## Prompts (14)\\n| Prompt | Description |\\n|--------|-------------|\\n| `financial-report` | Full financial summary |\\n| `optimize-yield` | Yield optimization analysis |\\n| `send-money` | Guided send with preview |\\n| `budget-check` | Can I afford $X? |\\n| `savings-strategy` | Recommend how much to save and where |\\n| `what-if` | Scenario planning \u2014 model impact before acting |\\n| `sweep` | Route idle funds to optimal earning positions |\\n| `risk-check` | Health factor, concentration, liquidation risk |\\n| `weekly-recap` | Week in review \u2014 activity, yield |\\n| `claim-rewards` | Check and claim pending protocol rewards |\\n| `safeguards` | Review safety settings \u2014 limits, lock, PIN-protected operations |\\n| `onboarding` | New user setup \u2014 deposit, first save, explore features |\\n| `emergency` | Lock account, assess damage, recovery guidance |\\n| `optimize-all` | One-shot full optimization \u2014 sweep, compare APYs, claim rewards |\\n\\n## Troubleshooting\\n\\n| Symptom | Cause | Fix |\\n|---------|-------|-----|\\n| `npx @t2000/mcp` \\"hangs\\" with no output | Working as designed \u2014 server is waiting for JSON-RPC on stdin | Don\'t run it manually; let the AI client launch it |\\n| Server exits with `Safeguards not configured` | `maxPerTx` / `maxDailySend` not set | Run `npx @t2000/cli config set maxPerTx 100 && ... maxDailySend 500` |\\n| Client shows no `t2000_*` tools after restart | Wrong config path, or stale npx cache | Verify with the `printf | npx ...` test above; clear cache with `rm -rf ~/.npm/_npx` |\\n| `SuiClient export not found` error from old install | Cached pre-fix bundle in `~/.npm/_npx` | `rm -rf ~/.npm/_npx` then restart the client |\\n\\n## Engine MCP Adapter (Audric)\\n\\n`@t2000/engine` can also expose its financial tools as MCP tools, enabling\\nAudric to serve as an MCP server alongside `@t2000/mcp`:\\n\\n```typescript\\nimport { registerEngineTools, getDefaultTools } from \'@t2000/engine\';\\nimport { McpServer } from \'@modelcontextprotocol/sdk/server/mcp.js\';\\n\\nconst server = new McpServer({ name: \'audric\', version: \'0.1.0\' });\\nregisterEngineTools(server, getDefaultTools());\\n// Exposes: audric_balance_check, audric_save_deposit, etc.\\n```\\n\\nEngine tools use `audric_` prefix to avoid collisions with `t2000_` prefixed\\ntools from `@t2000/mcp`. The engine adapter includes permission-level metadata\\nand supports the full confirmation flow.\\n\\n## Security\\n- Safeguard gate: server refuses to start without configured limits\\n- `unlock` is CLI-only \u2014 AI cannot circumvent a locked agent\\n- `dryRun: true` previews operations before signing\\n- Local-only stdio transport \u2014 key never leaves the machine"},{"name":"t2000-pay","description":"Pay for an MPP-protected API service using the t2000 wallet. Use when asked to call an AI model, search the web, generate images, send email, buy gift cards, send physical mail, check weather, execute code, or any task that requires a paid API. Handles the full MPP 402 challenge automatically. Use t2000_services to discover all available services first.","body":"# t2000: Pay for MPP API Service\\n\\n## Status\\nActive \u2014 requires `t2000` CLI with `@suimpp/mpp` installed.\\n\\n## Purpose\\nMake a paid HTTP request to any MPP-protected endpoint. Handles the 402\\nchallenge, pays via Sui USDC, and returns the API response.\\n\\n## Service Discovery\\nBefore calling `t2000 pay`, discover available services:\\n```bash\\n# CLI\\nt2000 pay https://mpp.t2000.ai/api/services\\n\\n# MCP\\nt2000_services\\n```\\n\\nAll services are hosted at `https://mpp.t2000.ai/`.\\n\\n## Command\\n```bash\\nt2000 pay <url> [options]\\n```\\n\\n## Options\\n| Option | Description | Default |\\n|--------|-------------|---------|\\n| `--method <method>` | HTTP method (GET, POST, PUT) | POST |\\n| `--data <json>` | Request body for POST/PUT | \u2014 |\\n| `--max-price <amount>` | Max USDC per request | $1.00 |\\n| `--header <key=value>` | Additional HTTP header (repeatable) | \u2014 |\\n| `--timeout <seconds>` | Request timeout in seconds | 30 |\\n| `--dry-run` | Show what would be paid without paying | \u2014 |\\n\\n## Available Services (40 services, 88 endpoints)\\n\\n> For the live, canonical list use `t2000_services` (MCP) or GET `https://mpp.t2000.ai/api/services`.\\n> The table below is a quick reference.\\n\\n### AI Models\\n| Service | Endpoint | Price |\\n|---------|----------|-------|\\n| OpenAI Chat | `/openai/v1/chat/completions` | $0.01 |\\n| OpenAI Embeddings | `/openai/v1/embeddings` | $0.005 |\\n| OpenAI Audio Transcription | `/openai/v1/audio/transcriptions` | $0.01 |\\n| OpenAI Text-to-Speech | `/openai/v1/audio/speech` | $0.02 |\\n| Anthropic | `/anthropic/v1/messages` | $0.01 |\\n| Google Gemini Flash | `/gemini/v1beta/models/gemini-2.5-flash` | $0.005 |\\n| Google Gemini Pro | `/gemini/v1beta/models/gemini-2.5-pro` | $0.01 |\\n| Google Gemini Embeddings | `/gemini/v1beta/models/embedding-001` | $0.005 |\\n| DeepSeek | `/deepseek/v1/chat/completions` | $0.005 |\\n| Groq Chat | `/groq/v1/chat/completions` | $0.005 |\\n| Groq Audio Transcription | `/groq/v1/audio/transcriptions` | $0.005 |\\n| Together AI Chat | `/together/v1/chat/completions` | $0.005 |\\n| Together AI Embeddings | `/together/v1/embeddings` | $0.005 |\\n| Perplexity | `/perplexity/v1/chat/completions` | $0.01 |\\n| Mistral Chat | `/mistral/v1/chat/completions` | $0.005 |\\n| Mistral Embeddings | `/mistral/v1/embeddings` | $0.005 |\\n| Cohere Chat | `/cohere/v1/chat` | $0.005 |\\n| Cohere Embed | `/cohere/v1/embed` | $0.005 |\\n| Cohere Rerank | `/cohere/v1/rerank` | $0.005 |\\n\\n### Media & Generation\\n| Service | Endpoint | Price |\\n|---------|----------|-------|\\n| OpenAI DALL-E | `/openai/v1/images/generations` | $0.05 |\\n| Fal.ai Flux Dev | `/fal/fal-ai/flux/dev` | $0.03 |\\n| Fal.ai Flux Pro | `/fal/fal-ai/flux-pro` | $0.05 |\\n| Fal.ai Flux Realism | `/fal/fal-ai/flux-realism` | $0.05 |\\n| Fal.ai Recraft 20B | `/fal/fal-ai/recraft-20b` | $0.05 |\\n| Fal.ai Whisper | `/fal/fal-ai/whisper` | $0.01 |\\n| Together AI Images | `/together/v1/images/generations` | $0.03 |\\n| ElevenLabs TTS | `/elevenlabs/v1/text-to-speech/:voiceId` | $0.05 |\\n| ElevenLabs SFX | `/elevenlabs/v1/sound-generation` | $0.05 |\\n| Replicate (any model) | `/replicate/v1/predictions` | $0.02 |\\n| Replicate (check status) | `/replicate/v1/predictions/status` | $0.005 |\\n| Stability AI (generate) | `/stability/v1/generate` | $0.03 |\\n| Stability AI (edit) | `/stability/v1/edit` | $0.03 |\\n| AssemblyAI (transcribe) | `/assemblyai/v1/transcribe` | $0.02 |\\n| AssemblyAI (get result) | `/assemblyai/v1/result` | $0.005 |\\n\\n### Search\\n| Service | Endpoint | Price |\\n|---------|----------|-------|\\n| Brave Web Search | `/brave/v1/web/search` | $0.005 |\\n| Brave Image Search | `/brave/v1/images/search` | $0.005 |\\n| Brave News Search | `/brave/v1/news/search` | $0.005 |\\n| Brave Video Search | `/brave/v1/videos/search` | $0.005 |\\n| Brave Summarizer | `/brave/v1/summarizer/search` | $0.01 |\\n| Exa (semantic search) | `/exa/v1/search` | $0.01 |\\n| Exa (content extract) | `/exa/v1/contents` | $0.01 |\\n| Serper (Google search) | `/serper/v1/search` | $0.005 |\\n| Serper (image search) | `/serper/v1/images` | $0.005 |\\n| SerpAPI (Google search) | `/serpapi/v1/search` | $0.01 |\\n| SerpAPI (Google Flights) | `/serpapi/v1/flights` | $0.01 |\\n| SerpAPI (locations) | `/serpapi/v1/locations` | $0.005 |\\n| NewsAPI (headlines) | `/newsapi/v1/headlines` | $0.005 |\\n| NewsAPI (article search) | `/newsapi/v1/search` | $0.005 |\\n\\n### Data\\n| Service | Endpoint | Price |\\n|---------|----------|-------|\\n| OpenWeather Current | `/openweather/v1/weather` | $0.005 |\\n| OpenWeather Forecast | `/openweather/v1/forecast` | $0.005 |\\n| Google Maps Geocode | `/googlemaps/v1/geocode` | $0.01 |\\n| Google Maps Places | `/googlemaps/v1/places` | $0.01 |\\n| Google Maps Directions | `/googlemaps/v1/directions` | $0.01 |\\n| CoinGecko (price) | `/coingecko/v1/price` | $0.005 |\\n| CoinGecko (markets) | `/coingecko/v1/markets` | $0.005 |\\n| CoinGecko (trending) | `/coingecko/v1/trending` | $0.005 |\\n| Alpha Vantage (quote) | `/alphavantage/v1/quote` | $0.005 |\\n| Alpha Vantage (daily) | `/alphavantage/v1/daily` | $0.005 |\\n| Alpha Vantage (search) | `/alphavantage/v1/search` | $0.005 |\\n\\n### Web & Documents\\n| Service | Endpoint | Price |\\n|---------|----------|-------|\\n| Firecrawl Scrape | `/firecrawl/v1/scrape` | $0.01 |\\n| Firecrawl Crawl | `/firecrawl/v1/crawl` | $0.02 |\\n| Firecrawl Map | `/firecrawl/v1/map` | $0.01 |\\n| Firecrawl Extract | `/firecrawl/v1/extract` | $0.02 |\\n| Jina Reader | `/jina/v1/read` | $0.005 |\\n| ScreenshotOne | `/screenshot/v1/capture` | $0.01 |\\n| PDFShift (HTML to PDF) | `/pdfshift/v1/convert` | $0.01 |\\n| QR Code | `/qrcode/v1/generate` | $0.005 |\\n\\n### Translation\\n| Service | Endpoint | Price |\\n|---------|----------|-------|\\n| DeepL (translate) | `/deepl/v1/translate` | $0.005 |\\n| Google Translate | `/translate/v1/translate` | $0.005 |\\n| Google Detect Language | `/translate/v1/detect` | $0.005 |\\n\\n### Intelligence\\n| Service | Endpoint | Price |\\n|---------|----------|-------|\\n| Hunter.io (domain search) | `/hunter/v1/search` | $0.02 |\\n| Hunter.io (verify email) | `/hunter/v1/verify` | $0.02 |\\n| IPinfo (IP lookup) | `/ipinfo/v1/lookup` | $0.005 |\\n\\n### Tools & Compute\\n| Service | Endpoint | Price |\\n|---------|----------|-------|\\n| Judge0 Code Exec | `/judge0/v1/submissions` | $0.005 |\\n| Judge0 Languages | `/judge0/v1/languages` | $0.005 |\\n| Resend Email | `/resend/v1/emails` | $0.005 |\\n| Resend Batch Email | `/resend/v1/emails/batch` | $0.01 |\\n\\n### Commerce\\n| Service | Endpoint | Price |\\n|---------|----------|-------|\\n| Lob Postcards | `/lob/v1/postcards` | $1.00 |\\n| Lob Letters | `/lob/v1/letters` | $1.50 |\\n| Lob Address Verify | `/lob/v1/verify` | $0.01 |\\n| Printful (browse) | `/printful/v1/products` | $0.005 |\\n| Printful (estimate) | `/printful/v1/estimate` | $0.005 |\\n| Printful (order) | `/printful/v1/order` | dynamic |\\n\\n### Messaging\\n| Service | Endpoint | Price |\\n|---------|----------|-------|\\n| Pushover | `/pushover/v1/push` | $0.005 |\\n\\n### Security\\n| Service | Endpoint | Price |\\n|---------|----------|-------|\\n| VirusTotal (URL/file scan) | `/virustotal/v1/scan` | $0.01 |\\n\\n### Finance\\n| Service | Endpoint | Price |\\n|---------|----------|-------|\\n| ExchangeRate (rates) | `/exchangerate/v1/rates` | $0.005 |\\n| ExchangeRate (convert) | `/exchangerate/v1/convert` | $0.005 |\\n\\n### Utility\\n| Service | Endpoint | Price |\\n|---------|----------|-------|\\n| Short.io (URL shortener) | `/shortio/v1/shorten` | $0.005 |\\n\\n## Example Commands\\n\\n### Ask an AI model\\n```bash\\nt2000 pay https://mpp.t2000.ai/openai/v1/chat/completions \\\\\\n --data \'{\\"model\\":\\"gpt-4o\\",\\"messages\\":[{\\"role\\":\\"user\\",\\"content\\":\\"Explain quantum computing in 3 sentences\\"}]}\'\\n```\\n\\n### Search the web\\n```bash\\nt2000 pay https://mpp.t2000.ai/brave/v1/web/search \\\\\\n --data \'{\\"q\\":\\"latest Sui blockchain news\\"}\'\\n```\\n\\n### Generate an image\\n```bash\\nt2000 pay https://mpp.t2000.ai/fal/fal-ai/flux/dev \\\\\\n --data \'{\\"prompt\\":\\"a futuristic city at sunset, cyberpunk style\\"}\'\\n```\\n\\n### Check weather\\n```bash\\nt2000 pay https://mpp.t2000.ai/openweather/v1/weather \\\\\\n --data \'{\\"q\\":\\"Tokyo\\"}\'\\n```\\n\\n### Send an email\\n```bash\\nt2000 pay https://mpp.t2000.ai/resend/v1/emails \\\\\\n --data \'{\\"from\\":\\"agent@t2000.ai\\",\\"to\\":\\"user@example.com\\",\\"subject\\":\\"Hello\\",\\"text\\":\\"Sent by an AI agent\\"}\'\\n```\\n\\n### Execute code\\n```bash\\nt2000 pay https://mpp.t2000.ai/judge0/v1/submissions \\\\\\n --data \'{\\"source_code\\":\\"print(42)\\",\\"language_id\\":71}\'\\n```\\n\\n### Send physical mail\\n```bash\\n# Send a postcard\\nt2000 pay https://mpp.t2000.ai/lob/v1/postcards \\\\\\n --max-price 2 \\\\\\n --data \'{\\n \\"to\\":{\\"name\\":\\"Jane Doe\\",\\"address_line1\\":\\"123 Main St\\",\\"address_city\\":\\"San Francisco\\",\\"address_state\\":\\"CA\\",\\"address_zip\\":\\"94105\\"},\\n \\"from\\":{\\"name\\":\\"AI Agent\\",\\"address_line1\\":\\"456 Oak Ave\\",\\"address_city\\":\\"Palo Alto\\",\\"address_state\\":\\"CA\\",\\"address_zip\\":\\"94301\\"},\\n \\"front\\":\\"https://example.com/front.png\\",\\n \\"back\\":\\"https://example.com/back.png\\",\\n \\"use_type\\":\\"operational\\"\\n }\'\\n\\n# Send a letter\\nt2000 pay https://mpp.t2000.ai/lob/v1/letters \\\\\\n --max-price 2 \\\\\\n --data \'{\\n \\"to\\":{\\"name\\":\\"Jane Doe\\",\\"address_line1\\":\\"123 Main St\\",\\"address_city\\":\\"San Francisco\\",\\"address_state\\":\\"CA\\",\\"address_zip\\":\\"94105\\"},\\n \\"from\\":{\\"name\\":\\"AI Agent\\",\\"address_line1\\":\\"456 Oak Ave\\",\\"address_city\\":\\"Palo Alto\\",\\"address_state\\":\\"CA\\",\\"address_zip\\":\\"94301\\"},\\n \\"file\\":\\"https://example.com/letter.pdf\\",\\n \\"use_type\\":\\"operational\\",\\n \\"color\\":false\\n }\'\\n\\n# Verify a US address\\nt2000 pay https://mpp.t2000.ai/lob/v1/verify \\\\\\n --data \'{\\"primary_line\\":\\"123 Main St\\",\\"city\\":\\"San Francisco\\",\\"state\\":\\"CA\\",\\"zip_code\\":\\"94105\\"}\'\\n```\\n\\n### Get directions\\n```bash\\nt2000 pay https://mpp.t2000.ai/googlemaps/v1/directions \\\\\\n --data \'{\\"origin\\":\\"San Francisco, CA\\",\\"destination\\":\\"Palo Alto, CA\\"}\'\\n```\\n\\n### Get crypto prices\\n```bash\\nt2000 pay https://mpp.t2000.ai/coingecko/v1/price \\\\\\n --data \'{\\"ids\\":\\"sui,bitcoin,ethereum\\",\\"vs_currencies\\":\\"usd\\"}\'\\n```\\n\\n### Get a stock quote\\n```bash\\nt2000 pay https://mpp.t2000.ai/alphavantage/v1/quote \\\\\\n --data \'{\\"symbol\\":\\"AAPL\\"}\'\\n```\\n\\n### Get breaking news\\n```bash\\nt2000 pay https://mpp.t2000.ai/newsapi/v1/headlines \\\\\\n --data \'{\\"country\\":\\"us\\",\\"category\\":\\"technology\\"}\'\\n```\\n\\n### Translate text\\n```bash\\nt2000 pay https://mpp.t2000.ai/deepl/v1/translate \\\\\\n --data \'{\\"text\\":[\\"Hello, how are you?\\"],\\"target_lang\\":\\"ES\\"}\'\\n```\\n\\n### Semantic search\\n```bash\\nt2000 pay https://mpp.t2000.ai/exa/v1/search \\\\\\n --data \'{\\"query\\":\\"best practices for AI agent payments\\",\\"numResults\\":5}\'\\n```\\n\\n### Read a URL as markdown\\n```bash\\nt2000 pay https://mpp.t2000.ai/jina/v1/read \\\\\\n --data \'{\\"url\\":\\"https://docs.sui.io/concepts/tokenomics\\"}\'\\n```\\n\\n### Google search (structured)\\n```bash\\nt2000 pay https://mpp.t2000.ai/serper/v1/search \\\\\\n --data \'{\\"q\\":\\"Sui blockchain TVL 2026\\"}\'\\n```\\n\\n### Screenshot a webpage\\n```bash\\nt2000 pay https://mpp.t2000.ai/screenshot/v1/capture \\\\\\n --data \'{\\"url\\":\\"https://example.com\\",\\"format\\":\\"png\\",\\"viewport_width\\":\\"1280\\"}\'\\n```\\n\\n### Generate a QR code\\n```bash\\nt2000 pay https://mpp.t2000.ai/qrcode/v1/generate \\\\\\n --data \'{\\"data\\":\\"https://t2000.ai\\",\\"size\\":\\"400x400\\"}\'\\n```\\n\\n### Convert HTML to PDF\\n```bash\\nt2000 pay https://mpp.t2000.ai/pdfshift/v1/convert \\\\\\n --data \'{\\"source\\":\\"https://t2000.ai/docs\\"}\'\\n```\\n\\n### Run a Replicate model\\n```bash\\nt2000 pay https://mpp.t2000.ai/replicate/v1/predictions \\\\\\n --data \'{\\"model\\":\\"meta/llama-3-70b-instruct\\",\\"input\\":{\\"prompt\\":\\"Explain DeFi in 3 sentences\\"}}\'\\n```\\n\\n### Find emails for a domain\\n```bash\\nt2000 pay https://mpp.t2000.ai/hunter/v1/search \\\\\\n --data \'{\\"domain\\":\\"mystenlabs.com\\"}\'\\n```\\n\\n### Look up an IP address\\n```bash\\nt2000 pay https://mpp.t2000.ai/ipinfo/v1/lookup \\\\\\n --data \'{\\"ip\\":\\"8.8.8.8\\"}\'\\n```\\n\\n### Order print-on-demand merchandise\\n```bash\\nt2000 pay https://mpp.t2000.ai/printful/v1/order \\\\\\n --max-price 30 \\\\\\n --data \'{\\"recipient\\":{\\"name\\":\\"Jane Doe\\",\\"address1\\":\\"123 Main St\\",\\"city\\":\\"SF\\",\\"state_code\\":\\"CA\\",\\"country_code\\":\\"US\\",\\"zip\\":\\"94105\\"},\\"items\\":[{\\"variant_id\\":4012,\\"quantity\\":1,\\"files\\":[{\\"url\\":\\"https://example.com/design.png\\"}]}]}\'\\n```\\n\\n### Search for flights\\n```bash\\nt2000 pay https://mpp.t2000.ai/serpapi/v1/flights \\\\\\n --data \'{\\"departure_id\\":\\"LAX\\",\\"arrival_id\\":\\"NRT\\",\\"outbound_date\\":\\"2026-05-01\\",\\"type\\":\\"2\\"}\'\\n```\\n\\n### Convert currency\\n```bash\\nt2000 pay https://mpp.t2000.ai/exchangerate/v1/convert \\\\\\n --data \'{\\"from\\":\\"USD\\",\\"to\\":\\"EUR\\",\\"amount\\":100}\'\\n```\\n\\n### Scan a URL for malware\\n```bash\\nt2000 pay https://mpp.t2000.ai/virustotal/v1/scan \\\\\\n --data \'{\\"url\\":\\"https://suspicious-site.com\\"}\'\\n```\\n\\n### Shorten a URL\\n```bash\\nt2000 pay https://mpp.t2000.ai/shortio/v1/shorten \\\\\\n --data \'{\\"url\\":\\"https://example.com/very/long/url/path\\"}\'\\n```\\n\\n### Send a push notification\\n```bash\\nt2000 pay https://mpp.t2000.ai/pushover/v1/push \\\\\\n --data \'{\\"user\\":\\"USER_KEY\\",\\"message\\":\\"Your agent has a message!\\"}\'\\n```\\n\\n## Flow (automatic)\\n1. Makes initial HTTP request to the URL\\n2. If 402: reads MPP challenge for amount and terms\\n3. If price <= --max-price: pays via Sui USDC\\n4. Retries with credential header\\n5. Returns the API response body\\n\\n## Safety\\n- If requested price exceeds --max-price, payment is refused (no funds spent)\\n- Default max-price: $1.00 USDC per request\\n- For commerce (mail, merch), set --max-price higher\\n- Payment only broadcast after 402 terms are validated\\n\\n## Errors\\n- `PRICE_EXCEEDS_LIMIT`: API asking more than --max-price\\n- `INSUFFICIENT_BALANCE`: not enough available USDC\\n- `UNSUPPORTED_NETWORK`: MPP requires a network other than Sui\\n- `PAYMENT_EXPIRED`: payment challenge has expired\\n- `DUPLICATE_PAYMENT`: nonce already used on-chain\\n\\n## MCP\\nVia MCP: use `t2000_services` to discover services, then `t2000_pay` to call them."},{"name":"t2000-rebalance","description":"Rebalance the wallet to a target allocation by executing multiple swaps in one atomic Payment Intent. Use when asked to rebalance, adjust allocation, \\"shuffle my positions\\", or move from one set of holdings to another. Every leg prices against the same on-chain snapshot \u2014 no cross-leg slippage drift; user signs once.","body":"# t2000: Rebalance Portfolio\\n\\n## Purpose\\nMove from a current allocation to a target allocation by emitting all\\nthe required `swap_execute` calls **in the same assistant turn** so the\\nengine compiles them into one Payment Intent. Result: every leg of the\\nrebalance prices against the same Sui state, slippage is bounded once,\\nand the user signs once.\\n\\n## When to use\\n\\n- \\"Rebalance my portfolio to 60% USDC / 30% SUI / 10% GOLD\\"\\n- \\"Move everything to USDC\\"\\n- \\"Adjust my allocation \u2014 I want less SUI exposure\\"\\n- \\"I\'m 80% SUI, get me to 50/50 with USDC\\"\\n\\n## Flow\\n\\n### Step 1 \u2014 Current allocation\\nCall `balance_check` (engine) or `t2000_balance --json` (CLI) to get the\\ncurrent breakdown. Compute the percentage held in each asset by USD value.\\n\\n### Step 2 \u2014 Plan trades\\nFor each asset, compute the delta vs the target:\\n- Asset over-allocated \u2192 swap **out** to USDC (or another reduce-target asset)\\n- Asset under-allocated \u2192 swap **in** from USDC (or another excess-source asset)\\n\\nPresent the plan to the user **before** executing:\\n\\n```\\n\u{1F4CA} REBALANCE PLAN\\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\\n Current Target \u0394\\n USDC $400 $600 +$200\\n SUI $400 $300 \u2212$100\\n GOLD $200 $100 \u2212$100\\n\\nTrades (1 atomic Payment Intent):\\n 1. swap 0.5 SUI \u2192 ~$100 USDC\\n 2. swap 0.05 GOLD \u2192 ~$100 USDC\\n\\nEstimated slippage: 0.3% on each leg\\nProceed?\\n```\\n\\n### Step 3 \u2014 Execute (bundled)\\n\\n**Critical:** emit ALL the `swap_execute` calls as parallel `tool_use` blocks\\n**in the same assistant turn**. The engine\'s permission gate compiles them\\ninto ONE Payment Intent. The user signs once; every leg either succeeds or\\nthe whole rebalance reverts.\\n\\n**Do NOT** call them sequentially across turns \u2014 that defeats the atomicity\\nand exposes the user to price drift between legs.\\n\\n```\\n[ASSISTANT TURN \u2014 emit in parallel]\\n tool_use: swap_execute({ from: \\"SUI\\", to: \\"USDC\\", amount: 0.5 })\\n tool_use: swap_execute({ from: \\"GOLD\\", to: \\"USDC\\", amount: 0.05 })\\n```\\n\\n### Step 4 \u2014 Summary\\nAfter the Payment Intent settles, call `balance_check` again and show the\\nfinal allocation vs target. Highlight any drift > 1% (caused by slippage\\nor rounding) and ask if the user wants a follow-up swap to close it.\\n\\n## Error handling\\n\\n| Error | Cause | What to do |\\n|---|---|---|\\n| Intent failed \u2014 `INSUFFICIENT_BALANCE` | One of the swap legs would consume more than the wallet holds | Abort the entire intent (no swaps execute). Reduce the amount on the offending leg. |\\n| Intent failed \u2014 `SLIPPAGE_EXCEEDED` | A leg exceeded the configured slippage tolerance | Abort. Re-run with looser slippage OR smaller leg sizes. |\\n| Intent failed \u2014 any reason | Atomic Payment Intent reverts the WHOLE bundle | No funds moved. Tell the user the on-chain state is unchanged. |\\n\\n## CLI fallback (no bundling)\\n\\nThe CLI does not support Payment Intent bundling today. To rebalance from\\nthe CLI, execute swaps one at a time:\\n\\n```bash\\nt2000 swap 0.5 SUI to USDC\\nt2000 swap 0.05 GOLD to USDC\\n```\\n\\nEach swap prices against the on-chain state **at the moment of execution**,\\nwhich means small drift between legs. For larger rebalances ($1k+) prefer\\nthe agent path (which bundles into one Payment Intent).\\n\\n## Fees\\n\\nPer swap leg:\\n- Cetus protocol fee: ~0.1% of swap amount (varies by pool)\\n- Audric overlay fee: 10 bps (~0.1%)\\n\\nBundled rebalances pay the same per-leg fees \u2014 bundling reduces slippage\\nrisk, not fee cost.\\n\\n## Notes\\n\\n- This skill is **engine-first** \u2014 the bundling guarantee only exists in\\n the audric/web chat agent (or any engine consumer with Payment Intent\\n compile support).\\n- For \\"optimize my yield\\" intent (sweep idle USDC into best-APY savings,\\n claim rewards, compare USDC pools), use the `optimize-all` MCP prompt\\n instead \u2014 that\'s a different shape of workflow.\\n- Health-factor check **does not run** for swap-only rebalances (no\\n collateral position changes). For rebalances that involve withdrawing\\n from savings, see `t2000-withdraw` (the safety check runs there)."},{"name":"t2000-receive","description":"Generate a payment request to receive funds into the t2000 agent wallet. Use when asked to receive money, create a payment link, share a wallet address, or generate a QR code for receiving payment. Produces a payment request with address, Sui Payment Kit URI (sui:pay?\u2026), nonce, and optional amount/memo.","body":"# t2000: Receive Payment\\n\\n## Purpose\\nGenerate a payment request containing the agent\'s wallet address, a unique\\nnonce, and a Sui Payment Kit URI (`sui:pay?\u2026`). The sender can scan the QR or\\ncopy the address to send funds. No on-chain transaction is created \u2014 this is a\\nlocal, read-only operation.\\n\\n## Command\\n```bash\\nt2000 receive [options]\\n\\n# Examples:\\nt2000 receive # Address only\\nt2000 receive --amount 25 # Request $25 USDC\\nt2000 receive --amount 100 --memo \\"Invoice #42\\" # With memo\\nt2000 receive --amount 50 --label \\"Freelance work\\" # With label\\nt2000 receive --currency SUI --amount 10 # Request SUI\\n```\\n\\n## Options\\n| Option | Description |\\n|--------|-------------|\\n| `--amount <n>` | Amount to request (omit for open amount) |\\n| `--currency <sym>` | Currency symbol (default: USDC) |\\n| `--memo <text>` | Payment note shown to sender |\\n| `--label <text>` | Description for the payment request |\\n\\n## Output\\n```\\n\u2713 Payment Request\\n\\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\\n Address 0x8b3e...d412\\n Network Sui Mainnet\\n Nonce a1b2c3d4-e5f6-7890-abcd-ef1234567890\\n Amount $25.00 USDC\\n Memo Invoice #42\\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\\n\\n Payment URI sui:pay?receiver=0x8b3e...&amount=25000000&...\\n\\n Share this URI or scan the QR to pay via any Sui wallet.\\n```\\n\\n## SDK Usage\\n```typescript\\nconst request = agent.receive({ amount: 25, memo: \'Invoice #42\' });\\n// Returns: { address, network, amount, currency, memo, label, nonce, qrUri, displayText }\\n```\\n\\n## MCP Tool\\nTool name: `t2000_receive` (read-only, auto-approved).\\n\\n## Notes\\n- This is a **local operation** \u2014 no transaction is created, no gas is used\\n- Uses **Sui Payment Kit** \u2014 generates `sui:pay?` URIs with nonce binding\\n- The nonce is a UUID that uniquely identifies each payment request\\n- Wallets that support Payment Kit register payment in an on-chain registry, preventing double-spend\\n- Without `--amount`, the request is open-ended (any amount accepted)\\n- Default currency is USDC; specify `--currency SUI` for native SUI"},{"name":"t2000-repay","description":"Repay outstanding debt. Use when asked to repay a loan, pay back debt, reduce outstanding balance, or clear borrows. Supports partial and full repayment. User pays with USDC.","body":"# t2000: Repay Borrow\\n\\n## Purpose\\nRepay outstanding debt in USDC. Supports specific amounts or `repay all` to clear the full\\nbalance including accrued interest.\\n\\n## Command\\n```bash\\nt2000 repay <amount>\\nt2000 repay all\\n\\n# Examples:\\nt2000 repay 20\\nt2000 repay all\\n```\\n\\n## Fees\\n- No protocol fee on repayment\\n\\n## Output\\n```\\n\u2713 Repaid $XX.XX USDC\\n Remaining Debt: $XX.XX\\n Tx: https://suiscan.xyz/mainnet/tx/0x...\\n```\\n\\n## Notes\\n- `repay all` calculates full outstanding principal + accrued interest\\n- Available USDC balance must cover the repayment amount"},{"name":"t2000-safeguards","description":"Configure spending limits and safety controls for t2000 agent wallets. Use when asked to set transaction limits, daily send limits, lock or unlock the agent, view safeguard settings, or protect the wallet from unauthorized spending. Required before enabling MCP server access.","body":"# t2000: Agent Safeguards\\n\\n## Purpose\\nConfigure spending limits and safety guardrails for autonomous agent\\noperation. Three controls: agent lock (kill switch), per-transaction\\nlimit, and daily send limit.\\n\\n> Safeguards are enforced on CLI and MCP. All state-changing actions\\n> require explicit confirmation before execution.\\n\\n## Commands\\n```bash\\nt2000 config show # view all safeguard settings\\nt2000 config set maxPerTx 500 # max $500 per outbound transaction\\nt2000 config set maxDailySend 1000 # max $1000 outbound per day\\nt2000 lock # freeze ALL operations immediately\\nt2000 unlock # resume operations (requires PIN)\\n```\\n\\n## Controls\\n\\n| Control | Description | Default |\\n|---------|-------------|---------|\\n| `maxPerTx` | Max USDC per single outbound op (send/pay) | 0 (unlimited) |\\n| `maxDailySend` | Max total USDC outbound per calendar day | 0 (unlimited) |\\n| `locked` | Kill switch \u2014 freezes ALL operations | false |\\n\\n## What counts as outbound\\n- `t2000 send` \u2014 transfers to other addresses\\n- `t2000 pay` \u2014 MPP API payments\\n\\n## What is NOT limited\\nInternal operations (save, withdraw, borrow, repay)\\nmove funds within the agent\'s own wallet and protocol positions. They\\nare not subject to send limits.\\n\\n## Output (config show)\\n```\\n Agent Safeguards\\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\\n Locked: No\\n Per-transaction: $500.00\\n Daily send limit: $1,000.00 ($350.00 used today)\\n```\\n\\n## Blocked output\\n```\\n \u2717 Blocked: amount $1,000.00 exceeds per-transaction limit ($500.00)\\n \u2717 Blocked: daily send limit reached ($1,000.00/$1,000.00 used today)\\n \u2717 Agent is locked. All operations frozen.\\n```\\n\\n## JSON mode\\n```bash\\nt2000 config show --json\\n```\\n```json\\n{ \\"locked\\": false, \\"maxPerTx\\": 500, \\"maxDailySend\\": 1000, \\"dailyUsed\\": 350 }\\n```\\n\\n## SDK\\n```typescript\\nconst agent = await T2000.create({ pin });\\n\\n// Check config\\nagent.enforcer.getConfig(); // { locked, maxPerTx, maxDailySend, dailyUsed, ... }\\nagent.enforcer.isConfigured(); // true if any limit is non-zero\\n\\n// Set limits\\nagent.enforcer.set(\'maxPerTx\', 500);\\nagent.enforcer.set(\'maxDailySend\', 1000);\\n\\n// Lock/unlock\\nagent.enforcer.lock();\\nagent.enforcer.unlock();\\n```\\n\\n## Important\\n- Safeguards are opt-in \u2014 defaults are permissive (0 = unlimited)\\n- MCP server requires non-zero limits before starting\\n- Lock freezes ALL operations (including internal) as a safety measure\\n- Daily counter resets at midnight UTC"},{"name":"t2000-save","description":"Deposit USDC or USDsui into savings to earn yield on Sui via NAVI Protocol. Use when asked to save money, earn interest, deposit to savings, \\"swap and save\\" a non-USDC token, or put funds to work. Not for sending to other addresses \u2014 use t2000-send for that.","body":"# t2000: Save (Deposit to Savings)\\n\\n## Purpose\\nDeposit **USDC or USDsui** into savings to earn yield on NAVI Protocol. Funds remain non-custodial and\\nwithdrawable at any time. USDsui is permitted as a strategic exception (v0.51.0+) because it has\\nits own NAVI pool, often at a different APY than USDC. Every other token (GOLD, SUI, USDT, USDe,\\nETH, NAVX, WAL) is **not saveable** \u2014 swap to USDC or USDsui first.\\n\\n## Command\\n```bash\\nt2000 save <amount> [--asset USDC|USDsui]\\nt2000 save all [--asset USDC|USDsui]\\n\\n# Examples:\\nt2000 save 80 # 80 USDC (default)\\nt2000 save 80 --asset USDsui # 80 USDsui\\nt2000 save all # full USDC balance (minus $1 gas reserve)\\nt2000 save all --asset USDsui # full USDsui balance (minus 1.0 reserve)\\n```\\n\\n- `save all`: deposits full available balance of the chosen asset minus 1.0 of that asset for safety\\n- `--asset` defaults to USDC when omitted\\n\\n## Fees\\n- Protocol fee: 0.1% on deposit (collected atomically on-chain)\\n\\n## Output\\n```\\n\u2713 Gas manager: $1.00 USDC \u2192 SUI [only shown if auto-topup triggered]\\n\u2713 Saved $XX.XX <asset> to best rate\\n\u2713 Current APY: X.XX%\\n\u2713 Savings balance: $XX.XX <asset>\\n Tx: https://suiscan.xyz/mainnet/tx/0x...\\n```\\n\\n## Notes\\n- APY is variable based on protocol utilization (USDC and USDsui pools quote independently)\\n- If available balance of the chosen asset is too low, returns INSUFFICIENT_BALANCE\\n- `t2000 supply` is an alias for `t2000 save`\\n- **Repay symmetry (v0.51.1+):** if you borrow USDsui, you must repay with USDsui (and USDC borrows must repay with USDC) \u2014 the SDK fetches the matching coin type per borrow asset.\\n\\n## Saving a non-USDC token (\\"swap and save\\")\\n\\nIf the user wants to save a token that\'s **not** USDC or USDsui \u2014 GOLD,\\nSUI, USDT, USDe, ETH, NAVX, WAL \u2014 the agent must swap first, then save.\\nThe right flow depends on the consumer:\\n\\n### Engine (audric/web) \u2014 bundled atomic swap + save\\n\\nEmit BOTH tool_use blocks in the SAME assistant turn. The engine\'s\\npermission gate compiles them into ONE Payment Intent: the swap\'s\\n`received` coin handles off as the save\'s input via coin-ref inside the\\nsame PTB. Atomic \u2014 both succeed or both revert. User signs once.\\n\\n```\\n[ASSISTANT TURN \u2014 emit in parallel]\\n tool_use: swap_execute({ from: \\"SUI\\", to: \\"USDC\\", amount: 1.0 })\\n tool_use: save_deposit({ amount: <swap_received>, asset: \\"USDC\\" })\\n```\\n\\nBefore emitting, **always preview** to the user:\\n- The source token + amount being swapped\\n- Estimated USDC received (from `swap_quote`)\\n- The save APY they\'ll earn\\n- Total fees (Cetus + Audric overlay + NAVI save fee)\\n\\n**Do NOT** call swap then save in separate turns \u2014 that loses atomicity\\nand exposes the user to price drift between the legs.\\n\\n**Do NOT** auto-decide for the user. If they say \\"save 10 SUI\\", confirm\\nthe intent: \\"That requires swapping ~10 SUI to ~$XX USDC first, then\\ndepositing. Proceed?\\" Some users want to hold SUI.\\n\\n### CLI \u2014 sequential (no bundling)\\n\\nThe CLI doesn\'t support Payment Intent bundling. Run two commands:\\n\\n```bash\\nt2000 swap 1.0 SUI to USDC\\nt2000 save all\\n```\\n\\nEach command prices against on-chain state at the moment of execution,\\nso there\'s small price drift between them. For large amounts ($1k+),\\nprefer the agent path which bundles into one Payment Intent.\\n\\n### What\'s NOT saveable\\n\\nGOLD, SUI, USDT, USDe, ETH, NAVX, WAL \u2014 none of these have NAVI lending\\npools today, so they can\'t be saved directly. Must swap to USDC or\\nUSDsui first. This is enforced by the SDK\'s `assertAllowedAsset(\'save\',\\nasset)` allow-list \u2014 calling `save_deposit({ asset: \'SUI\' })` returns\\n`UNSUPPORTED_ASSET`."},{"name":"t2000-send","description":"Send USDC from the t2000 agent wallet to another address on Sui. Use when asked to pay someone, transfer funds, send money, tip a creator, or make a payment to a specific Sui address or saved contact. Do NOT use for API payments \u2014 use t2000-pay for MPP-protected services.","body":"# t2000: Send USDC\\n\\n## Purpose\\nTransfer USDC from the agent\'s available balance to any Sui address. Gas is\\nself-funded from the agent\'s SUI reserve (auto-topped up if needed).\\n\\n## Command\\n```bash\\nt2000 send <amount> <asset> to <address_or_contact>\\nt2000 send <amount> <asset> <address_or_contact>\\n\\n# Examples:\\nt2000 send 10 USDC to 0x8b3e...d412\\nt2000 send 50 USDC to Tom\\nt2000 send 50 USDC 0xabcd...1234\\n```\\n\\nThe `to` keyword is optional. The recipient can be a Sui address (0x...) or a\\nsaved contact name (e.g. \\"Tom\\"). Use `t2000 contacts` to list saved contacts.\\n\\n## Pre-flight checks (automatic)\\n1. Sufficient available USDC balance\\n2. SUI gas reserve present; if not, auto-topup triggers transparently\\n\\n## Output\\n```\\n\u2713 Sent $XX.XX USDC \u2192 0x8b3e...d412\\n Gas: X.XXXX SUI (self-funded)\\n Balance: $XX.XX USDC\\n Tx: https://suiscan.xyz/mainnet/tx/0x...\\n```\\n\\n## Error handling\\n- `INSUFFICIENT_BALANCE`: available balance is less than the requested amount\\n- `INVALID_ADDRESS`: destination is not a valid Sui address\\n- `CONTACT_NOT_FOUND`: name is not a saved contact or valid address\\n- `SIMULATION_FAILED`: transaction would fail on-chain; details in error message\\n\\n## Recipient resolution flow\\n\\nWhen the user provides a recipient, resolve it before broadcasting:\\n\\n1. **Name given** \u2192 look up in saved contacts. If found, use the mapped\\n address. If not found and not a valid `0x...` address, ask the user\\n to clarify (suggest `t2000 contacts add <name> <address>` first).\\n2. **Address given (`0x...`)** \u2192 validate with `isValidSuiAddress()`. If\\n invalid, refuse with `INVALID_ADDRESS`.\\n3. **Ambiguous** (looks like a name AND a valid prefix) \u2192 ask the user\\n which they meant.\\n\\nAfter a successful send to a **previously-unknown raw address** (not a\\nsaved contact), offer to save it:\\n\\n> \\"Want to save 0x8b3e\u2026d412 as a contact? Say `yes <name>` to save.\\"\\n\\nIf the user provides a name, call `save_contact` (engine) or\\n`t2000 contacts add <name> <address>` (CLI). This makes future sends to\\nthe same person work by name (`t2000 send 10 USDC to <name>`).\\n\\n**Do not auto-save** without asking \u2014 the user might not want every\\none-off recipient cluttering their contacts list.\\n\\n## Engine orchestration (audric/web)\\n\\nWhen called inside the Audric chat agent:\\n\\n1. Resolve recipient (contacts lookup or address validation) \u2014 no tool call needed for contacts; resolution happens in prose.\\n2. Call `balance_check` to confirm sufficient funds.\\n3. Emit `send_transfer({ to, amount, asset })` as the write tool_use.\\n4. After the send settles, if the recipient was a raw address not already\\n in contacts, surface the \\"save as contact?\\" prompt to the user (see\\n above). The user confirms in the next turn; engine emits `save_contact`.\\n\\nSends are **single-write** \u2014 never bundle with another write in a\\nPayment Intent. Each transfer is its own intent."},{"name":"t2000-withdraw","description":"Withdraw from savings and receive USDC or USDsui. Use when asked to withdraw from savings, access deposited funds, pull money out of savings, reduce yield position, \\"close my position\\", or emergency withdraw. For sending to another address, use t2000-send.","body":"# t2000: Withdraw from Savings\\n\\n## Purpose\\nWithdraw USDC or USDsui from savings back to your checking balance.\\n\\n## Command\\n```bash\\nt2000 withdraw <amount> [--asset USDC|USDsui]\\nt2000 withdraw all [--asset USDC|USDsui]\\n\\n# Examples:\\nt2000 withdraw 25 # 25 USDC (default)\\nt2000 withdraw 25 --asset USDsui # 25 USDsui\\nt2000 withdraw all # full USDC savings position\\nt2000 withdraw all --asset USDsui # full USDsui savings position\\n```\\n\\n`--asset` defaults to USDC when omitted.\\n\\n## Fees\\n- No protocol fee on withdrawals\\n\\n## Output\\n```\\n\u2713 Withdrew $XX.XX <asset>\\n Tx: https://suiscan.xyz/mainnet/tx/0x...\\n```\\n\\n## Safety check (active when debt exists)\\n\\nIf the wallet has outstanding debt, t2000 evaluates whether the withdrawal\\nwould push the health factor below 1.5:\\n\\n| Scenario | Behavior |\\n|---|---|\\n| No debt | Withdrawal proceeds \u2014 no HF check. |\\n| Withdrawal keeps HF \u2265 1.5 | Withdrawal proceeds \u2014 note the new HF in the output. |\\n| Withdrawal would drop HF < 1.5 | **Refused** with `WITHDRAW_WOULD_LIQUIDATE`. Error data includes `safeWithdrawAmount` (the largest amount that keeps HF \u2265 1.5). |\\n\\n## Emergency / \\"close my position\\" flow\\n\\nWhen the user asks to \\"withdraw everything\\", \\"close my position\\", or\\n\\"emergency withdraw\\":\\n\\n### Step 1 \u2014 Read state\\nCall `health_check` (engine) or `t2000 balance --show-limits` (CLI) to\\nsee savings, debt, and current HF.\\n\\n### Step 2 \u2014 Decide path\\n\\n| Wallet state | Path |\\n|---|---|\\n| **No debt** | Single-write `withdraw all` for each asset held in savings. |\\n| **Has debt, savings \u2265 debt** | **Bundled repay + withdraw** \u2014 emit `repay_debt(all)` and `withdraw(remaining)` as parallel `tool_use` blocks in the SAME assistant turn. Engine compiles into one Payment Intent: atomic repay-then-withdraw, one signature. |\\n| **Has debt, savings < debt** | **Refuse** \u2014 user can\'t fully close position without first acquiring more of the borrowed asset. Tell them how much more they\'d need; do not auto-swap. |\\n\\n### Step 3 \u2014 Bundled emit (engine path)\\n\\nFor the \\"bundled repay + withdraw\\" case, emit BOTH tool_use blocks in the\\nsame assistant turn:\\n\\n```\\n[ASSISTANT TURN \u2014 emit in parallel]\\n tool_use: repay_debt({ amount: <debt>, asset: <borrowed_asset> })\\n tool_use: withdraw({ amount: <remaining>, asset: <savings_asset> })\\n```\\n\\nThe engine\'s permission gate compiles these into ONE Payment Intent. Both\\nlegs succeed or both revert \u2014 no partial close. The user signs once.\\n\\n**Do NOT** call them sequentially across turns \u2014 that loses atomicity and\\nexposes the user to a window where debt is repaid but the withdraw fails,\\nleaving the wallet in an awkward state.\\n\\n**Critical:** `repay_debt` MUST use the SAME asset as the original borrow\\n(USDsui debt \u2192 USDsui repay, USDC debt \u2192 USDC repay \u2014 see `t2000-repay`).\\nIf the user doesn\'t hold enough of the matching asset, abort with a clear\\nmessage; do not auto-swap.\\n\\n## Error handling\\n- `WITHDRAW_WOULD_LIQUIDATE` \u2014 withdrawal would push HF < 1.5. Use `safeWithdrawAmount` from error data, or repay debt first.\\n- `NO_COLLATERAL` \u2014 no savings position in the requested asset.\\n- `INSUFFICIENT_BALANCE` \u2014 requested amount exceeds savings balance.\\n- Intent failed (bundled flow) \u2014 atomic revert. No funds moved."}]';
|
|
140546
|
+
cachedSkills = JSON.parse(raw);
|
|
140547
|
+
return cachedSkills;
|
|
140548
|
+
}
|
|
140549
|
+
function toPromptName(skillName) {
|
|
140550
|
+
return `skill-${skillName.replace(/^t2000-/, "")}`;
|
|
140551
|
+
}
|
|
140552
|
+
function registerSkillPrompts(server, skills = getBakedSkills()) {
|
|
140553
|
+
for (const skill of skills) {
|
|
140554
|
+
const promptName = toPromptName(skill.name);
|
|
140555
|
+
server.prompt(
|
|
140556
|
+
promptName,
|
|
140557
|
+
skill.description,
|
|
140558
|
+
async () => ({
|
|
140559
|
+
messages: [{
|
|
140560
|
+
role: "user",
|
|
140561
|
+
content: { type: "text", text: skill.body }
|
|
140562
|
+
}]
|
|
140563
|
+
})
|
|
140564
|
+
);
|
|
140565
|
+
}
|
|
140566
|
+
}
|
|
140567
|
+
function findSkill(name, skills) {
|
|
140568
|
+
const skill = skills.find((s) => s.name === name);
|
|
140569
|
+
if (!skill) {
|
|
140570
|
+
const available = skills.map((s) => s.name).sort().join(", ");
|
|
140571
|
+
throw new Error(
|
|
140572
|
+
`[compose-skills] Unknown skill '${name}'. Available skills: ${available}.`
|
|
140573
|
+
);
|
|
140574
|
+
}
|
|
140575
|
+
return skill;
|
|
140576
|
+
}
|
|
140577
|
+
function composeSkillBody(skillName, opts = {}) {
|
|
140578
|
+
const skills = opts.skills ?? getBakedSkills();
|
|
140579
|
+
return findSkill(skillName, skills).body;
|
|
140580
|
+
}
|
|
140581
|
+
function composeSkillSections(skillName, headers, opts = {}) {
|
|
140582
|
+
const skills = opts.skills ?? getBakedSkills();
|
|
140583
|
+
const skill = findSkill(skillName, skills);
|
|
140584
|
+
if (headers.length === 0) {
|
|
140585
|
+
throw new Error(
|
|
140586
|
+
`[compose-skills] composeSkillSections('${skillName}', []): pass at least one header.`
|
|
140587
|
+
);
|
|
140588
|
+
}
|
|
140589
|
+
const sections = parseSections(skill.body);
|
|
140590
|
+
const headerSet = new Set(headers);
|
|
140591
|
+
const missing = headers.filter(
|
|
140592
|
+
(h) => !sections.some((s) => s.header === h)
|
|
140593
|
+
);
|
|
140594
|
+
if (missing.length > 0) {
|
|
140595
|
+
const available = sections.map((s) => s.header).join(", ");
|
|
140596
|
+
throw new Error(
|
|
140597
|
+
`[compose-skills] Skill '${skillName}' is missing sections: ${missing.join(", ")}. Available sections: ${available}.`
|
|
140598
|
+
);
|
|
140599
|
+
}
|
|
140600
|
+
return sections.filter((s) => headerSet.has(s.header)).map((s) => `## ${s.header}
|
|
140601
|
+
${s.content}`).join("\n").trimEnd();
|
|
140602
|
+
}
|
|
140603
|
+
function parseSections(body) {
|
|
140604
|
+
const lines = body.split("\n");
|
|
140605
|
+
const sections = [];
|
|
140606
|
+
let current = null;
|
|
140607
|
+
for (const line of lines) {
|
|
140608
|
+
const match = /^## (?!#)(.+)$/.exec(line);
|
|
140609
|
+
if (match) {
|
|
140610
|
+
if (current) sections.push(current);
|
|
140611
|
+
current = { header: match[1].trim(), content: "" };
|
|
140612
|
+
} else if (current) {
|
|
140613
|
+
current.content += (current.content ? "\n" : "") + line;
|
|
140614
|
+
}
|
|
140615
|
+
}
|
|
140616
|
+
if (current) sections.push(current);
|
|
140617
|
+
return sections.map((s) => ({
|
|
140618
|
+
header: s.header,
|
|
140619
|
+
content: s.content.replace(/\n+$/, "")
|
|
140620
|
+
}));
|
|
140621
|
+
}
|
|
140622
|
+
function registerPrompts(server, opts = {}) {
|
|
140623
|
+
const skills = opts.skills ?? getBakedSkills();
|
|
140543
140624
|
server.prompt(
|
|
140544
140625
|
"financial-report",
|
|
140545
140626
|
"Get a comprehensive summary of the agent's financial position \u2014 balance, savings, debt, health factor, and yield earnings.",
|
|
@@ -140549,34 +140630,27 @@ function registerPrompts(server) {
|
|
|
140549
140630
|
content: {
|
|
140550
140631
|
type: "text",
|
|
140551
140632
|
text: [
|
|
140552
|
-
"You are a financial
|
|
140553
|
-
"",
|
|
140554
|
-
"IMPORTANT: Call t2000_overview FIRST \u2014 it returns everything (balance, positions, health, earnings, fund status, pending rewards) in one call.",
|
|
140555
|
-
"Then call t2000_rates for rate comparison across protocols.",
|
|
140633
|
+
"You are a financial advisor for a t2000 AI agent bank account on Sui.",
|
|
140556
140634
|
"",
|
|
140557
|
-
"
|
|
140635
|
+
"STEP 1 \u2014 Render the account snapshot per the canonical skill:",
|
|
140558
140636
|
"",
|
|
140559
|
-
|
|
140560
|
-
|
|
140561
|
-
|
|
140562
|
-
|
|
140563
|
-
|
|
140564
|
-
" Net worth",
|
|
140565
|
-
"",
|
|
140566
|
-
"\u{1F4C8} Positions",
|
|
140567
|
-
" Each savings position: protocol, asset, amount, APY",
|
|
140637
|
+
composeSkillSections(
|
|
140638
|
+
"t2000-account-report",
|
|
140639
|
+
["Purpose", "Engine orchestration (audric/web)"],
|
|
140640
|
+
{ skills }
|
|
140641
|
+
),
|
|
140568
140642
|
"",
|
|
140569
|
-
"\
|
|
140570
|
-
" Current APY, daily/monthly/projected earnings",
|
|
140571
|
-
" Comparison to best available rates",
|
|
140643
|
+
"STEP 2 \u2014 Add an advisor layer ON TOP of the snapshot:",
|
|
140572
140644
|
"",
|
|
140573
|
-
"\u{
|
|
140574
|
-
"
|
|
140575
|
-
"
|
|
140645
|
+
"\u{1F4CA} RECOMMENDATIONS (max 4)",
|
|
140646
|
+
" Actionable items derived from the data:",
|
|
140647
|
+
" \u2022 Idle funds in checking \u2192 suggest sweep to USDC savings",
|
|
140648
|
+
" \u2022 Current USDC APY < best available \u2192 flag rate gap (compare via t2000_rates / t2000_all_rates)",
|
|
140649
|
+
" \u2022 Pending protocol rewards > $0.01 \u2192 suggest t2000_claim_rewards",
|
|
140650
|
+
" \u2022 Health factor < 2.0 \u2192 flag repayment priority",
|
|
140576
140651
|
"",
|
|
140577
|
-
"
|
|
140578
|
-
"
|
|
140579
|
-
" Include: idle funds, rate optimization, reward claiming, debt repayment"
|
|
140652
|
+
"Tone: data-driven, no fluff, max one paragraph of prose per recommendation.",
|
|
140653
|
+
"If everything is already optimal, say so clearly \u2014 don't invent problems."
|
|
140580
140654
|
].join("\n")
|
|
140581
140655
|
}
|
|
140582
140656
|
}]
|
|
@@ -140591,95 +140665,31 @@ function registerPrompts(server) {
|
|
|
140591
140665
|
content: {
|
|
140592
140666
|
type: "text",
|
|
140593
140667
|
text: [
|
|
140594
|
-
"You are a yield optimization
|
|
140668
|
+
"You are a yield optimization specialist for a t2000 AI agent bank account on Sui.",
|
|
140595
140669
|
"",
|
|
140596
|
-
"
|
|
140597
|
-
" 1. t2000_overview \u2014 full account state including positions and pending rewards",
|
|
140598
|
-
" 2. t2000_rates \u2014 USDC save and borrow rates",
|
|
140599
|
-
" 3. t2000_all_rates \u2014 compare USDC lending APYs across protocols (informational)",
|
|
140670
|
+
"CONTEXT (USDC-canonical save policy \u2014 from the t2000-save skill):",
|
|
140600
140671
|
"",
|
|
140601
|
-
"
|
|
140672
|
+
composeSkillSections("t2000-save", ["Purpose"], { skills }),
|
|
140673
|
+
"",
|
|
140674
|
+
"STEP 1 \u2014 Gather the data (call in parallel):",
|
|
140675
|
+
" \u2022 t2000_overview \u2014 full account state + pending rewards",
|
|
140676
|
+
" \u2022 t2000_rates \u2014 current USDC save + borrow rates",
|
|
140677
|
+
" \u2022 t2000_all_rates \u2014 per-protocol USDC APY comparison (informational)",
|
|
140678
|
+
"",
|
|
140679
|
+
"STEP 2 \u2014 Present the analysis:",
|
|
140602
140680
|
"",
|
|
140603
140681
|
"\u{1F4CA} YIELD ANALYSIS",
|
|
140604
140682
|
"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
140605
|
-
"",
|
|
140606
140683
|
" Current USDC on [protocol] \xB7 X.XX% APY",
|
|
140607
140684
|
" Best USDC [protocol] \xB7 X.XX% APY",
|
|
140608
140685
|
" APY gap +X.XX% (if any)",
|
|
140609
140686
|
"",
|
|
140610
|
-
"
|
|
140611
|
-
|
|
140612
|
-
"",
|
|
140613
|
-
"
|
|
140614
|
-
" - Idle checking funds that could be earning yield (t2000_save)",
|
|
140615
|
-
" - Claimable protocol rewards (suggest t2000_claim_rewards)"
|
|
140616
|
-
].join("\n")
|
|
140617
|
-
}
|
|
140618
|
-
}]
|
|
140619
|
-
})
|
|
140620
|
-
);
|
|
140621
|
-
server.prompt(
|
|
140622
|
-
"send-money",
|
|
140623
|
-
"Guided flow for sending USDC to a Sui address \u2014 validates address, checks limits, previews before signing.",
|
|
140624
|
-
{
|
|
140625
|
-
to: external_exports.string().optional().describe("Recipient Sui address"),
|
|
140626
|
-
amount: external_exports.number().optional().describe("Amount in dollars")
|
|
140627
|
-
},
|
|
140628
|
-
async ({ to: to2, amount: amount2 }) => {
|
|
140629
|
-
const context = [
|
|
140630
|
-
to2 ? `Recipient address: ${to2}` : "",
|
|
140631
|
-
amount2 ? `Amount: $${amount2}` : ""
|
|
140632
|
-
].filter(Boolean).join("\n");
|
|
140633
|
-
return {
|
|
140634
|
-
messages: [{
|
|
140635
|
-
role: "user",
|
|
140636
|
-
content: {
|
|
140637
|
-
type: "text",
|
|
140638
|
-
text: [
|
|
140639
|
-
"You are a payment assistant for a t2000 AI agent bank account.",
|
|
140640
|
-
"",
|
|
140641
|
-
context ? `Context:
|
|
140642
|
-
${context}
|
|
140643
|
-
` : "",
|
|
140644
|
-
"The user wants to send money. Follow this flow:",
|
|
140645
|
-
"1. If address or amount is missing, ask the user",
|
|
140646
|
-
"2. Preview the transaction (t2000_send with dryRun: true)",
|
|
140647
|
-
"3. Show the preview \u2014 amount, recipient, remaining balance, safeguard status",
|
|
140648
|
-
"4. Ask the user to confirm before executing",
|
|
140649
|
-
"5. Execute the send (t2000_send with dryRun: false)",
|
|
140650
|
-
"6. Show the transaction result with the Suiscan link"
|
|
140651
|
-
].join("\n")
|
|
140652
|
-
}
|
|
140653
|
-
}]
|
|
140654
|
-
};
|
|
140655
|
-
}
|
|
140656
|
-
);
|
|
140657
|
-
server.prompt(
|
|
140658
|
-
"budget-check",
|
|
140659
|
-
"Can I afford to spend $X? Checks balance, daily limit remaining, and whether spending would impact savings.",
|
|
140660
|
-
{
|
|
140661
|
-
amount: external_exports.number().optional().describe("Amount in dollars to check")
|
|
140662
|
-
},
|
|
140663
|
-
async ({ amount: amount2 }) => ({
|
|
140664
|
-
messages: [{
|
|
140665
|
-
role: "user",
|
|
140666
|
-
content: {
|
|
140667
|
-
type: "text",
|
|
140668
|
-
text: [
|
|
140669
|
-
"You are a budget assistant for a t2000 AI agent bank account.",
|
|
140670
|
-
"",
|
|
140671
|
-
amount2 ? `The user wants to know if they can afford to spend $${amount2}.` : "The user wants a spending check.",
|
|
140672
|
-
"",
|
|
140673
|
-
"Analyze their financial situation:",
|
|
140674
|
-
"1. Check current balance (t2000_balance)",
|
|
140675
|
-
'2. Check safeguard limits (t2000_config with action: "show")',
|
|
140676
|
-
"3. Calculate: available balance, daily limit remaining, what percentage of total this spend represents",
|
|
140687
|
+
"STEP 3 \u2014 Recommend (in priority order):",
|
|
140688
|
+
" \u2022 Idle checking \u2192 t2000_save (deploys at best USDC rate)",
|
|
140689
|
+
" \u2022 Pending rewards \u2192 t2000_claim_rewards",
|
|
140690
|
+
" \u2022 Sub-optimal position \u2192 withdraw + save (preview with dryRun first)",
|
|
140677
140691
|
"",
|
|
140678
|
-
|
|
140679
|
-
"- Can they afford it from checking?",
|
|
140680
|
-
"- Would it hit their daily send limit?",
|
|
140681
|
-
"- What balance would remain after?",
|
|
140682
|
-
"- If it's a large % of their total, flag that."
|
|
140692
|
+
`If already at best USDC rate AND no idle funds AND no rewards: say "You're optimized."`
|
|
140683
140693
|
].join("\n")
|
|
140684
140694
|
}
|
|
140685
140695
|
}]
|
|
@@ -140696,58 +140706,19 @@ ${context}
|
|
|
140696
140706
|
text: [
|
|
140697
140707
|
"You are a savings advisor for a t2000 AI agent bank account on Sui.",
|
|
140698
140708
|
"",
|
|
140699
|
-
"
|
|
140709
|
+
"WHICH ASSETS CAN BE SAVED (from the t2000-save skill \u2014 canonical):",
|
|
140700
140710
|
"",
|
|
140701
|
-
"
|
|
140702
|
-
" - How much idle checking can move to savings (keep ~$5 buffer for gas)",
|
|
140703
|
-
" - Which protocol offers the best USDC savings APY (use t2000_all_rates)",
|
|
140704
|
-
" - Expected monthly/annual yield on the recommended amount",
|
|
140705
|
-
" - Whether current USDC savings APY lags the best available (informational; new deposits use t2000_save at best USDC rate)",
|
|
140711
|
+
composeSkillSections("t2000-save", ["Purpose"], { skills }),
|
|
140706
140712
|
"",
|
|
140707
|
-
"
|
|
140708
|
-
].join("\n")
|
|
140709
|
-
}
|
|
140710
|
-
}]
|
|
140711
|
-
})
|
|
140712
|
-
);
|
|
140713
|
-
server.prompt(
|
|
140714
|
-
"what-if",
|
|
140715
|
-
'Scenario planning \u2014 "What if I save $X?" or "What if I borrow $X?" Shows projected impact on yield and risk.',
|
|
140716
|
-
{
|
|
140717
|
-
scenario: external_exports.string().optional().describe('Scenario to evaluate, e.g. "save $500" or "withdraw all savings" or "borrow $200"')
|
|
140718
|
-
},
|
|
140719
|
-
async ({ scenario }) => ({
|
|
140720
|
-
messages: [{
|
|
140721
|
-
role: "user",
|
|
140722
|
-
content: {
|
|
140723
|
-
type: "text",
|
|
140724
|
-
text: [
|
|
140725
|
-
"You are a financial scenario planner for a t2000 AI agent bank account on Sui.",
|
|
140726
|
-
"",
|
|
140727
|
-
scenario ? `The user wants to evaluate this scenario: "${scenario}"` : "The user wants to explore a hypothetical financial scenario. Ask them what they're considering.",
|
|
140728
|
-
"",
|
|
140729
|
-
"IMPORTANT: Call t2000_overview FIRST to get the full current state (balance, positions, health).",
|
|
140730
|
-
"Then preview the specific action with dryRun: true.",
|
|
140731
|
-
"",
|
|
140732
|
-
'For SAVINGS scenarios ("save $X" or "withdraw $X"):',
|
|
140733
|
-
" - Show impact on yield and health factor",
|
|
140734
|
-
"",
|
|
140735
|
-
'For BORROW scenarios ("borrow $X"):',
|
|
140736
|
-
" - Show new health factor and interest cost",
|
|
140737
|
-
"",
|
|
140738
|
-
"ALWAYS present results as a BEFORE \u2192 AFTER comparison table:",
|
|
140739
|
-
"",
|
|
140740
|
-
"\u{1F4CA} SCENARIO: [description]",
|
|
140741
|
-
" [strategy allocation breakdown if applicable]",
|
|
140713
|
+
"STEP 1 \u2014 Read the account state (call t2000_overview + t2000_all_rates in parallel).",
|
|
140742
140714
|
"",
|
|
140743
|
-
"
|
|
140744
|
-
"
|
|
140745
|
-
"
|
|
140715
|
+
"STEP 2 \u2014 Recommend:",
|
|
140716
|
+
" \u2022 How much idle checking to move (keep ~$5 SUI buffer for gas)",
|
|
140717
|
+
" \u2022 Which protocol offers the best USDC APY (cite t2000_all_rates)",
|
|
140718
|
+
" \u2022 Expected monthly/annual yield on the recommended amount",
|
|
140719
|
+
" \u2022 Whether the current position lags the best available rate",
|
|
140746
140720
|
"",
|
|
140747
|
-
"
|
|
140748
|
-
" - If it would drain total funds (checking + savings) below $5, warn about gas needs",
|
|
140749
|
-
"",
|
|
140750
|
-
'End with: "Want me to go ahead?" \u2014 ready to execute on confirmation.'
|
|
140721
|
+
"If the user wants to proceed, execute via t2000_save."
|
|
140751
140722
|
].join("\n")
|
|
140752
140723
|
}
|
|
140753
140724
|
}]
|
|
@@ -140767,27 +140738,30 @@ ${context}
|
|
|
140767
140738
|
content: {
|
|
140768
140739
|
type: "text",
|
|
140769
140740
|
text: [
|
|
140770
|
-
"You are a
|
|
140741
|
+
"You are a money-routing assistant for a t2000 AI agent bank account on Sui.",
|
|
140742
|
+
"",
|
|
140743
|
+
"SAVE ELIGIBILITY (from the t2000-save skill):",
|
|
140771
140744
|
"",
|
|
140772
|
-
|
|
140745
|
+
composeSkillSections("t2000-save", ["Purpose"], { skills }),
|
|
140773
140746
|
"",
|
|
140774
|
-
`
|
|
140775
|
-
"If sweep amount < $1, funds are already optimized.",
|
|
140747
|
+
`STEP 1 \u2014 Call t2000_overview and t2000_all_rates in parallel. Keep $${buffer2} in checking as gas buffer.`,
|
|
140776
140748
|
"",
|
|
140777
|
-
|
|
140749
|
+
`STEP 2 \u2014 Calculate sweep amount = available checking \u2212 $${buffer2}.`,
|
|
140750
|
+
"If sweep amount < $1, funds are already optimized; say so and stop.",
|
|
140751
|
+
"",
|
|
140752
|
+
"STEP 3 \u2014 Present the plan:",
|
|
140778
140753
|
"",
|
|
140779
140754
|
"\u{1F9F9} SWEEP PLAN",
|
|
140780
140755
|
"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
140781
140756
|
`Available to sweep: $X (keeping $${buffer2} buffer)`,
|
|
140782
140757
|
"",
|
|
140783
140758
|
"Actions (in order):",
|
|
140784
|
-
" 1. Save $X to best USDC rate (t2000_save;
|
|
140759
|
+
" 1. Save $X to best USDC rate (t2000_save; cite APY from t2000_rates / t2000_all_rates)",
|
|
140785
140760
|
" 2. Claim pending rewards (if available)",
|
|
140786
|
-
" 3. Optionally compare USDC APYs across protocols (t2000_all_rates) \u2014 informational",
|
|
140787
140761
|
"",
|
|
140788
140762
|
"Projected monthly yield: $X.XX (before) \u2192 $X.XX (after)",
|
|
140789
140763
|
"",
|
|
140790
|
-
"Ask to confirm, then execute sequentially."
|
|
140764
|
+
"STEP 4 \u2014 Ask to confirm, then execute sequentially."
|
|
140791
140765
|
].join("\n")
|
|
140792
140766
|
}
|
|
140793
140767
|
}]
|
|
@@ -140805,19 +140779,32 @@ ${context}
|
|
|
140805
140779
|
text: [
|
|
140806
140780
|
"You are a risk assessment specialist for a t2000 AI agent bank account on Sui.",
|
|
140807
140781
|
"",
|
|
140808
|
-
"
|
|
140782
|
+
"STEP 1 \u2014 Read the account state (use the t2000-account-report skill's tool sequence):",
|
|
140783
|
+
"",
|
|
140784
|
+
composeSkillSections(
|
|
140785
|
+
"t2000-account-report",
|
|
140786
|
+
["Engine orchestration (audric/web)"],
|
|
140787
|
+
{ skills }
|
|
140788
|
+
),
|
|
140809
140789
|
"",
|
|
140810
|
-
"
|
|
140790
|
+
"HEALTH FACTOR RULES (from the t2000-borrow skill \u2014 canonical):",
|
|
140791
|
+
"",
|
|
140792
|
+
composeSkillSections(
|
|
140793
|
+
"t2000-borrow",
|
|
140794
|
+
["Pre-borrow safety check (always runs)"],
|
|
140795
|
+
{ skills }
|
|
140796
|
+
),
|
|
140797
|
+
"",
|
|
140798
|
+
"STEP 2 \u2014 Present the risk report:",
|
|
140811
140799
|
"",
|
|
140812
140800
|
"\u{1F6E1}\uFE0F RISK REPORT",
|
|
140813
140801
|
"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
140814
|
-
"",
|
|
140815
|
-
"
|
|
140816
|
-
"2. CONCENTRATION RISK \u2014 % in each account type, % per asset",
|
|
140802
|
+
"1. LIQUIDATION RISK \u2014 Health factor + distance to liquidation (cite HF rules above)",
|
|
140803
|
+
"2. CONCENTRATION RISK \u2014 % per account type, % per asset",
|
|
140817
140804
|
"3. PROTOCOL EXPOSURE \u2014 Lending protocol distribution",
|
|
140818
140805
|
"4. YIELD EFFICIENCY \u2014 Idle assets, sub-optimal rates",
|
|
140819
140806
|
"",
|
|
140820
|
-
"OVERALL: Low / Medium / High / Critical",
|
|
140807
|
+
"OVERALL TIER: Low / Medium / High / Critical",
|
|
140821
140808
|
"",
|
|
140822
140809
|
"End with max 3 prioritized actions. If Low risk, say so \u2014 don't invent problems."
|
|
140823
140810
|
].join("\n")
|
|
@@ -140836,11 +140823,18 @@ ${context}
|
|
|
140836
140823
|
text: [
|
|
140837
140824
|
"You are a personal finance newsletter writer for a t2000 AI agent bank account on Sui.",
|
|
140838
140825
|
"",
|
|
140839
|
-
"
|
|
140826
|
+
"STEP 1 \u2014 Read the account state (use the t2000-account-report tool sequence) + t2000_history (limit: 50) in parallel:",
|
|
140827
|
+
"",
|
|
140828
|
+
composeSkillSections(
|
|
140829
|
+
"t2000-account-report",
|
|
140830
|
+
["Engine orchestration (audric/web)"],
|
|
140831
|
+
{ skills }
|
|
140832
|
+
),
|
|
140833
|
+
"",
|
|
140834
|
+
"STEP 2 \u2014 Render the recap:",
|
|
140840
140835
|
"",
|
|
140841
140836
|
"\u{1F4CA} WEEKLY RECAP",
|
|
140842
140837
|
"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
140843
|
-
"",
|
|
140844
140838
|
"\u{1F4B0} Net Worth: $X \u2014 Checking $X | Savings $X",
|
|
140845
140839
|
"\u{1F4C8} Activity: X sends, X saves, X withdrawals",
|
|
140846
140840
|
"\u{1F4B8} Yield: $X.XX this week, X% APY, $X/month projected",
|
|
@@ -140853,6 +140847,153 @@ ${context}
|
|
|
140853
140847
|
}]
|
|
140854
140848
|
})
|
|
140855
140849
|
);
|
|
140850
|
+
server.prompt(
|
|
140851
|
+
"send-money",
|
|
140852
|
+
"Guided flow for sending USDC to a Sui address \u2014 validates address, checks limits, previews before signing.",
|
|
140853
|
+
{
|
|
140854
|
+
to: external_exports.string().optional().describe("Recipient Sui address"),
|
|
140855
|
+
amount: external_exports.number().optional().describe("Amount in dollars")
|
|
140856
|
+
},
|
|
140857
|
+
async ({ to: to2, amount: amount2 }) => {
|
|
140858
|
+
const context = [
|
|
140859
|
+
to2 ? `Recipient address: ${to2}` : "",
|
|
140860
|
+
amount2 ? `Amount: $${amount2}` : ""
|
|
140861
|
+
].filter(Boolean).join("\n");
|
|
140862
|
+
return {
|
|
140863
|
+
messages: [{
|
|
140864
|
+
role: "user",
|
|
140865
|
+
content: {
|
|
140866
|
+
type: "text",
|
|
140867
|
+
text: [
|
|
140868
|
+
"You are a payment assistant for a t2000 AI agent bank account on Sui.",
|
|
140869
|
+
"",
|
|
140870
|
+
context ? `Context provided by the user:
|
|
140871
|
+
${context}
|
|
140872
|
+
` : "",
|
|
140873
|
+
"CANONICAL SEND FLOW (from the t2000-send skill \u2014 DO NOT skip steps):",
|
|
140874
|
+
"",
|
|
140875
|
+
composeSkillSections(
|
|
140876
|
+
"t2000-send",
|
|
140877
|
+
["Purpose", "Pre-flight checks (automatic)", "Recipient resolution flow"],
|
|
140878
|
+
{ skills }
|
|
140879
|
+
),
|
|
140880
|
+
"",
|
|
140881
|
+
"EXECUTION CHECKLIST:",
|
|
140882
|
+
" 1. If recipient or amount is missing, ask the user.",
|
|
140883
|
+
" 2. Preview with t2000_send dryRun: true.",
|
|
140884
|
+
" 3. Show the preview (amount, recipient, remaining balance, safeguard status).",
|
|
140885
|
+
" 4. Ask the user to confirm.",
|
|
140886
|
+
" 5. Execute with t2000_send dryRun: false.",
|
|
140887
|
+
" 6. Show the result + Suiscan link."
|
|
140888
|
+
].join("\n")
|
|
140889
|
+
}
|
|
140890
|
+
}]
|
|
140891
|
+
};
|
|
140892
|
+
}
|
|
140893
|
+
);
|
|
140894
|
+
server.prompt(
|
|
140895
|
+
"budget-check",
|
|
140896
|
+
"Can I afford to spend $X? Checks balance, daily limit remaining, and whether spending would impact savings.",
|
|
140897
|
+
{
|
|
140898
|
+
amount: external_exports.number().optional().describe("Amount in dollars to check")
|
|
140899
|
+
},
|
|
140900
|
+
async ({ amount: amount2 }) => ({
|
|
140901
|
+
messages: [{
|
|
140902
|
+
role: "user",
|
|
140903
|
+
content: {
|
|
140904
|
+
type: "text",
|
|
140905
|
+
text: [
|
|
140906
|
+
"You are a budget advisor for a t2000 AI agent bank account on Sui.",
|
|
140907
|
+
"",
|
|
140908
|
+
amount2 ? `The user wants to know if they can afford to spend $${amount2}.` : "The user wants a general spending check.",
|
|
140909
|
+
"",
|
|
140910
|
+
"WHAT THE BALANCE TOOL RETURNS (from the t2000-check-balance skill):",
|
|
140911
|
+
"",
|
|
140912
|
+
composeSkillSections(
|
|
140913
|
+
"t2000-check-balance",
|
|
140914
|
+
["Purpose"],
|
|
140915
|
+
{ skills }
|
|
140916
|
+
),
|
|
140917
|
+
"",
|
|
140918
|
+
"SAFEGUARD CONTROLS (from the t2000-safeguards skill):",
|
|
140919
|
+
"",
|
|
140920
|
+
composeSkillSections(
|
|
140921
|
+
"t2000-safeguards",
|
|
140922
|
+
["Controls"],
|
|
140923
|
+
{ skills }
|
|
140924
|
+
),
|
|
140925
|
+
"",
|
|
140926
|
+
'STEP 1 \u2014 Call t2000_balance and t2000_config (action: "show") in parallel.',
|
|
140927
|
+
"",
|
|
140928
|
+
"STEP 2 \u2014 Calculate:",
|
|
140929
|
+
" \u2022 Available checking",
|
|
140930
|
+
" \u2022 Daily limit remaining (cap \u2212 amount spent today)",
|
|
140931
|
+
" \u2022 What % of total wealth this spend represents",
|
|
140932
|
+
"",
|
|
140933
|
+
"STEP 3 \u2014 Give a yes/no answer with context:",
|
|
140934
|
+
" \u2022 Can they afford it from checking?",
|
|
140935
|
+
" \u2022 Would it hit their daily send limit?",
|
|
140936
|
+
" \u2022 What balance would remain after?",
|
|
140937
|
+
" \u2022 If it's a large % of total wealth, flag that."
|
|
140938
|
+
].join("\n")
|
|
140939
|
+
}
|
|
140940
|
+
}]
|
|
140941
|
+
})
|
|
140942
|
+
);
|
|
140943
|
+
server.prompt(
|
|
140944
|
+
"what-if",
|
|
140945
|
+
'Scenario planning \u2014 "What if I save $X?" or "What if I borrow $X?" Shows projected impact on yield and risk.',
|
|
140946
|
+
{
|
|
140947
|
+
scenario: external_exports.string().optional().describe('Scenario to evaluate, e.g. "save $500" or "withdraw all savings" or "borrow $200"')
|
|
140948
|
+
},
|
|
140949
|
+
async ({ scenario }) => ({
|
|
140950
|
+
messages: [{
|
|
140951
|
+
role: "user",
|
|
140952
|
+
content: {
|
|
140953
|
+
type: "text",
|
|
140954
|
+
text: [
|
|
140955
|
+
"You are a financial scenario planner for a t2000 AI agent bank account on Sui.",
|
|
140956
|
+
"",
|
|
140957
|
+
scenario ? `The user wants to evaluate: "${scenario}"` : "The user wants to explore a hypothetical financial scenario. Ask them what they're considering.",
|
|
140958
|
+
"",
|
|
140959
|
+
"STEP 1 \u2014 Read the current state (call t2000_overview first).",
|
|
140960
|
+
"",
|
|
140961
|
+
"STEP 2 \u2014 Identify the scenario type and apply the matching skill rules:",
|
|
140962
|
+
"",
|
|
140963
|
+
"IF THE SCENARIO IS A SAVE (t2000-save skill):",
|
|
140964
|
+
composeSkillSections("t2000-save", ["Purpose"], { skills }),
|
|
140965
|
+
"",
|
|
140966
|
+
"IF THE SCENARIO IS A BORROW (t2000-borrow skill \u2014 HF rules CANNOT be skipped):",
|
|
140967
|
+
composeSkillSections(
|
|
140968
|
+
"t2000-borrow",
|
|
140969
|
+
["Pre-borrow safety check (always runs)"],
|
|
140970
|
+
{ skills }
|
|
140971
|
+
),
|
|
140972
|
+
"",
|
|
140973
|
+
"IF THE SCENARIO IS A WITHDRAW (t2000-withdraw skill):",
|
|
140974
|
+
composeSkillSections(
|
|
140975
|
+
"t2000-withdraw",
|
|
140976
|
+
["Safety check (active when debt exists)"],
|
|
140977
|
+
{ skills }
|
|
140978
|
+
),
|
|
140979
|
+
"",
|
|
140980
|
+
"STEP 3 \u2014 Preview the specific action with dryRun: true.",
|
|
140981
|
+
"",
|
|
140982
|
+
"STEP 4 \u2014 Present BEFORE \u2192 AFTER:",
|
|
140983
|
+
"",
|
|
140984
|
+
"\u{1F4CA} SCENARIO: [description]",
|
|
140985
|
+
" Before After",
|
|
140986
|
+
" Checking $XX.XX $XX.XX",
|
|
140987
|
+
" Savings $XX.XX $XX.XX",
|
|
140988
|
+
" HF X.XX X.XX (if borrow/withdraw)",
|
|
140989
|
+
"",
|
|
140990
|
+
"STEP 5 \u2014 Smart guard: if action would drop total < $5, warn about gas.",
|
|
140991
|
+
'End with: "Want me to go ahead?" \u2014 ready to execute on confirmation.'
|
|
140992
|
+
].join("\n")
|
|
140993
|
+
}
|
|
140994
|
+
}]
|
|
140995
|
+
})
|
|
140996
|
+
);
|
|
140856
140997
|
server.prompt(
|
|
140857
140998
|
"claim-rewards",
|
|
140858
140999
|
"Check for pending protocol rewards across all lending positions and claim them \u2014 auto-converts to USDC.",
|
|
@@ -140862,34 +141003,35 @@ ${context}
|
|
|
140862
141003
|
content: {
|
|
140863
141004
|
type: "text",
|
|
140864
141005
|
text: [
|
|
140865
|
-
"You are a rewards management assistant for a t2000 AI agent bank account.",
|
|
141006
|
+
"You are a rewards management assistant for a t2000 AI agent bank account on Sui.",
|
|
140866
141007
|
"",
|
|
140867
|
-
|
|
141008
|
+
// No dedicated claim-rewards skill — the flow is operational
|
|
141009
|
+
// enough that a thin prompt suffices. Future: if a
|
|
141010
|
+
// `t2000-rewards` skill lands, compose it here.
|
|
141011
|
+
"STEP 1 \u2014 Check what's claimable:",
|
|
141012
|
+
" \u2022 t2000_pending_rewards \u2014 preview claimable amounts per protocol (no signature, no fee)",
|
|
141013
|
+
" \u2022 t2000_positions \u2014 confirm which positions accrued rewards",
|
|
140868
141014
|
"",
|
|
140869
|
-
"
|
|
140870
|
-
" - Check lending positions (t2000_positions)",
|
|
140871
|
-
' - Positions with "+rewards" tags have claimable protocol rewards',
|
|
140872
|
-
" - These are incentive tokens (like vSUI, sSUI, DEEP) earned from lending protocols",
|
|
141015
|
+
"STEP 2 \u2014 Present findings:",
|
|
140873
141016
|
"",
|
|
140874
|
-
"
|
|
140875
|
-
"
|
|
140876
|
-
|
|
140877
|
-
' Explain: "These are protocol incentive tokens that accrue on your lending positions"',
|
|
141017
|
+
" IF rewards are available:",
|
|
141018
|
+
" Show which positions have rewards and from which protocols.",
|
|
141019
|
+
' Explain: "These are protocol incentive tokens (e.g. vSUI, sSUI, DEEP) that accrue on your lending positions."',
|
|
140878
141020
|
' Ask: "Want me to claim and convert them to USDC?"',
|
|
140879
141021
|
"",
|
|
140880
|
-
"
|
|
140881
|
-
"
|
|
140882
|
-
" Show
|
|
141022
|
+
" IF no rewards are claimable:",
|
|
141023
|
+
" Say the rewards are still accruing and to check back later.",
|
|
141024
|
+
" Show current positions + APY so they know yield is being earned.",
|
|
140883
141025
|
"",
|
|
140884
|
-
"
|
|
140885
|
-
"
|
|
140886
|
-
"
|
|
140887
|
-
" Show
|
|
140888
|
-
" If received amount
|
|
141026
|
+
"STEP 3 \u2014 Execute the claim:",
|
|
141027
|
+
" \u2022 t2000_claim_rewards \u2014 claims from ALL protocols, auto-converts to USDC",
|
|
141028
|
+
" \u2022 Or t2000_harvest_rewards \u2014 claim + swap + deposit into savings as a single atomic PTB (one-shot compounding)",
|
|
141029
|
+
" \u2022 Show result: USDC received, source protocols, transaction link",
|
|
141030
|
+
" \u2022 If received amount < $0.01, explain that rewards accrue continuously",
|
|
140889
141031
|
"",
|
|
140890
|
-
"
|
|
140891
|
-
" Show updated balance after claiming",
|
|
140892
|
-
" Mention when to claim next
|
|
141032
|
+
"STEP 4 \u2014 Follow-up:",
|
|
141033
|
+
" Show updated balance after claiming.",
|
|
141034
|
+
" Mention when to claim next \u2014 weekly or monthly is typical."
|
|
140893
141035
|
].join("\n")
|
|
140894
141036
|
}
|
|
140895
141037
|
}]
|
|
@@ -140904,46 +141046,27 @@ ${context}
|
|
|
140904
141046
|
content: {
|
|
140905
141047
|
type: "text",
|
|
140906
141048
|
text: [
|
|
140907
|
-
"You are a security advisor for a t2000 AI agent bank account.",
|
|
140908
|
-
"",
|
|
140909
|
-
"Help the user review and manage their account safeguards.",
|
|
140910
|
-
"",
|
|
140911
|
-
"Step 1 \u2014 Show current settings:",
|
|
140912
|
-
' - Get safeguard config (t2000_config action: "show")',
|
|
140913
|
-
" - Show: per-transaction limit, daily send limit, daily spent today, lock status",
|
|
140914
|
-
"",
|
|
140915
|
-
"Step 2 \u2014 Explain each safeguard:",
|
|
140916
|
-
"",
|
|
140917
|
-
" \u{1F6E1}\uFE0F SAFEGUARDS",
|
|
140918
|
-
" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
141049
|
+
"You are a security advisor for a t2000 AI agent bank account on Sui.",
|
|
140919
141050
|
"",
|
|
140920
|
-
"
|
|
140921
|
-
" Every send is checked against this cap. Prevents large unauthorized transfers.",
|
|
141051
|
+
"CANONICAL SAFEGUARDS REFERENCE (from the t2000-safeguards skill \u2014 full body):",
|
|
140922
141052
|
"",
|
|
140923
|
-
"
|
|
140924
|
-
" Cumulative cap across all sends in a 24-hour window.",
|
|
140925
|
-
" Used today: $X of $X",
|
|
141053
|
+
composeSkillBody("t2000-safeguards", { skills }),
|
|
140926
141054
|
"",
|
|
140927
|
-
"
|
|
140928
|
-
|
|
140929
|
-
"
|
|
140930
|
-
" Lock via: t2000_lock (any AI agent can lock)",
|
|
140931
|
-
" Unlock via: CLI only with PIN \u2014 no AI can unlock, by design",
|
|
141055
|
+
"STEP 1 \u2014 Show current settings:",
|
|
141056
|
+
' \u2022 Call t2000_config (action: "show")',
|
|
141057
|
+
" \u2022 Surface: per-transaction limit, daily send limit, daily spent today, lock status",
|
|
140932
141058
|
"",
|
|
140933
|
-
"
|
|
140934
|
-
"
|
|
140935
|
-
" - Exporting the private key",
|
|
140936
|
-
" - Modifying safeguard limits",
|
|
141059
|
+
"STEP 2 \u2014 Explain each safeguard using the reference above. Translate technical names",
|
|
141060
|
+
' ("maxPerTx", "maxDailyUsd") into plain language for the user.',
|
|
140937
141061
|
"",
|
|
140938
|
-
"
|
|
140939
|
-
"
|
|
140940
|
-
"
|
|
140941
|
-
'
|
|
140942
|
-
" Always confirm before changing limits",
|
|
141062
|
+
"STEP 3 \u2014 Recommend appropriate limits based on the user's balance:",
|
|
141063
|
+
" \u2022 Large balances \u2192 tighter per-tx limits",
|
|
141064
|
+
" \u2022 New accounts \u2192 start conservative",
|
|
141065
|
+
' \u2022 Always confirm before changing limits via t2000_config (action: "set")',
|
|
140943
141066
|
"",
|
|
140944
|
-
"
|
|
140945
|
-
" If the user wants to lock: run t2000_lock immediately (no confirmation needed
|
|
140946
|
-
"
|
|
141067
|
+
"STEP 4 \u2014 Emergency actions:",
|
|
141068
|
+
" \u2022 If the user wants to lock: run t2000_lock immediately (no confirmation needed)",
|
|
141069
|
+
" \u2022 Remind: unlocking requires the CLI with PIN \u2014 `t2000 unlock`"
|
|
140947
141070
|
].join("\n")
|
|
140948
141071
|
}
|
|
140949
141072
|
}]
|
|
@@ -140960,37 +141083,38 @@ ${context}
|
|
|
140960
141083
|
text: [
|
|
140961
141084
|
"You are a friendly onboarding guide for t2000 \u2014 an AI agent bank account on Sui.",
|
|
140962
141085
|
"",
|
|
140963
|
-
"
|
|
141086
|
+
"STEP 1 \u2014 Read the user's current state (t2000_overview).",
|
|
141087
|
+
"",
|
|
141088
|
+
"STEP 2 \u2014 Branch the flow based on balance:",
|
|
140964
141089
|
"",
|
|
140965
141090
|
"\u{1F44B} WELCOME TO T2000",
|
|
140966
141091
|
"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
140967
141092
|
"",
|
|
140968
|
-
"
|
|
141093
|
+
"IF balance == $0 (no funds yet):",
|
|
141094
|
+
" Call t2000_deposit_info to get the agent's wallet address + supported assets.",
|
|
141095
|
+
" Then explain how to receive funds, using the t2000-receive skill as the canonical reference:",
|
|
140969
141096
|
"",
|
|
140970
|
-
"
|
|
140971
|
-
" Show deposit instructions (t2000_deposit_info)",
|
|
140972
|
-
' Explain: "Send USDC to your Sui address to get started"',
|
|
140973
|
-
" Mention: they need a small amount of SUI for gas (~$1 worth)",
|
|
141097
|
+
composeSkillSections("t2000-receive", ["Purpose"], { skills }),
|
|
140974
141098
|
"",
|
|
140975
|
-
"
|
|
140976
|
-
` "Great, you have $X ready to go! Here's what you can do:"`,
|
|
140977
|
-
" 1. SAVE \u2014 Earn yield on idle funds (show best current APY)",
|
|
140978
|
-
" 2. SEND \u2014 Transfer USDC to any Sui address or contact",
|
|
140979
|
-
" 3. PAY \u2014 Use USDC to pay for premium API services (MPP)",
|
|
140980
|
-
" 4. SAFEGUARDS \u2014 Set spending limits (recommend for accounts > $100)",
|
|
141099
|
+
" Tell them: they need a small amount of SUI for gas (~$1 worth).",
|
|
140981
141100
|
"",
|
|
140982
|
-
"IF
|
|
140983
|
-
` "
|
|
140984
|
-
"
|
|
141101
|
+
"IF balance > $0 but nothing saved yet:",
|
|
141102
|
+
` "Great, you have $X ready to go. Here's what you can do:"`,
|
|
141103
|
+
"",
|
|
141104
|
+
" SAVE \u2014 earn yield (t2000-save skill, canonical):",
|
|
141105
|
+
composeSkillSections("t2000-save", ["Purpose"], { skills }),
|
|
141106
|
+
"",
|
|
141107
|
+
" SEND \u2014 transfer USDC (t2000-send skill, see purpose).",
|
|
141108
|
+
" PAY \u2014 use USDC for premium API services (MPP).",
|
|
140985
141109
|
"",
|
|
140986
|
-
|
|
141110
|
+
" SAFEGUARDS \u2014 set spending limits for accounts > $100:",
|
|
141111
|
+
composeSkillSections("t2000-safeguards", ["Purpose"], { skills }),
|
|
140987
141112
|
"",
|
|
140988
|
-
"
|
|
140989
|
-
"
|
|
140990
|
-
" -
|
|
140991
|
-
"
|
|
140992
|
-
|
|
140993
|
-
" - Safeguards: per-tx limits, daily caps, emergency lock"
|
|
141113
|
+
"IF they already have savings:",
|
|
141114
|
+
` "You're set up. Quick status:" \u2014 mini summary (balance + savings + APY),`,
|
|
141115
|
+
" then offer to optimize (suggest the `optimize-all` or `optimize-yield` prompts).",
|
|
141116
|
+
"",
|
|
141117
|
+
'End with: "What would you like to do first?"'
|
|
140994
141118
|
].join("\n")
|
|
140995
141119
|
}
|
|
140996
141120
|
}]
|
|
@@ -141005,35 +141129,39 @@ ${context}
|
|
|
141005
141129
|
content: {
|
|
141006
141130
|
type: "text",
|
|
141007
141131
|
text: [
|
|
141008
|
-
"You are an emergency response handler for a t2000 AI agent bank account.",
|
|
141132
|
+
"You are an emergency response handler for a t2000 AI agent bank account on Sui.",
|
|
141009
141133
|
"",
|
|
141010
141134
|
"\u{1F6A8} EMERGENCY PROTOCOL",
|
|
141011
141135
|
"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
141012
141136
|
"",
|
|
141013
|
-
'
|
|
141014
|
-
" \u2192
|
|
141015
|
-
" \u2192 Then gather information",
|
|
141137
|
+
'IF the user says "lock", "freeze", "hack", "stolen", or "emergency":',
|
|
141138
|
+
" \u2192 Run t2000_lock IMMEDIATELY. No confirmation needed for locking.",
|
|
141139
|
+
" \u2192 Then gather information.",
|
|
141140
|
+
"",
|
|
141141
|
+
"SAFEGUARD CONTROLS (from the t2000-safeguards skill):",
|
|
141016
141142
|
"",
|
|
141017
|
-
"
|
|
141018
|
-
"
|
|
141143
|
+
composeSkillSections("t2000-safeguards", ["Controls"], { skills }),
|
|
141144
|
+
"",
|
|
141145
|
+
"STEP 1 \u2014 Lock first, ask later:",
|
|
141146
|
+
" Run t2000_lock to freeze ALL operations.",
|
|
141019
141147
|
' Confirm: "Account locked. No transactions can be executed."',
|
|
141020
|
-
" Explain: unlocking requires the CLI with
|
|
141148
|
+
" Explain: unlocking requires the CLI with the user's PIN \u2014 `t2000 unlock`.",
|
|
141021
141149
|
"",
|
|
141022
|
-
"
|
|
141023
|
-
" Call t2000_overview to see current state",
|
|
141024
|
-
" Call t2000_history (limit: 20) to check recent
|
|
141025
|
-
" Look for suspicious activity: unexpected sends, large withdrawals, unfamiliar addresses",
|
|
141150
|
+
"STEP 2 \u2014 Assess the situation:",
|
|
141151
|
+
" \u2022 Call t2000_overview to see current state",
|
|
141152
|
+
" \u2022 Call t2000_history (limit: 20) to check recent activity",
|
|
141153
|
+
" \u2022 Look for suspicious activity: unexpected sends, large withdrawals, unfamiliar addresses",
|
|
141026
141154
|
"",
|
|
141027
|
-
"
|
|
141028
|
-
" Show current balances (
|
|
141029
|
-
" Flag any suspicious transactions with amounts and timestamps",
|
|
141030
|
-
"
|
|
141155
|
+
"STEP 3 \u2014 Report findings:",
|
|
141156
|
+
" \u2022 Show current balances (funds still there?)",
|
|
141157
|
+
" \u2022 Flag any suspicious transactions with amounts and timestamps",
|
|
141158
|
+
" \u2022 Include Suiscan links so the user can verify on-chain",
|
|
141031
141159
|
"",
|
|
141032
|
-
"
|
|
141033
|
-
'
|
|
141034
|
-
'
|
|
141035
|
-
' Remind: "To unlock, use: t2000 unlock (
|
|
141036
|
-
'
|
|
141160
|
+
"STEP 4 \u2014 Recovery guidance:",
|
|
141161
|
+
' \u2022 Funds safe: "Your funds are secure. The lock prevents further transactions."',
|
|
141162
|
+
' \u2022 Suspicious tx found: "Review this transaction: [link]. If unauthorized, your remaining funds are now locked."',
|
|
141163
|
+
' \u2022 Remind: "To unlock, use: t2000 unlock (with PIN)"',
|
|
141164
|
+
' \u2022 Recommend: "Consider rotating your key after investigating."'
|
|
141037
141165
|
].join("\n")
|
|
141038
141166
|
}
|
|
141039
141167
|
}]
|
|
@@ -141050,23 +141178,32 @@ ${context}
|
|
|
141050
141178
|
text: [
|
|
141051
141179
|
"You are a full-account optimizer for a t2000 AI agent bank account on Sui.",
|
|
141052
141180
|
"",
|
|
141053
|
-
"
|
|
141181
|
+
"STEP 1 \u2014 Read the account state in parallel: call t2000_overview AND t2000_all_rates.",
|
|
141182
|
+
" For MCP clients with canvas rendering, also use the t2000-account-report tool sequence:",
|
|
141054
141183
|
"",
|
|
141055
|
-
|
|
141056
|
-
|
|
141184
|
+
composeSkillSections(
|
|
141185
|
+
"t2000-account-report",
|
|
141186
|
+
["Engine orchestration (audric/web)"],
|
|
141187
|
+
{ skills }
|
|
141188
|
+
),
|
|
141057
141189
|
"",
|
|
141058
|
-
"
|
|
141190
|
+
"WHAT CAN BE SAVED (from the t2000-save skill):",
|
|
141191
|
+
composeSkillSections("t2000-save", ["Purpose"], { skills }),
|
|
141059
141192
|
"",
|
|
141060
|
-
"
|
|
141061
|
-
"
|
|
141193
|
+
"WHEN TO REBALANCE (from the t2000-rebalance skill):",
|
|
141194
|
+
composeSkillSections("t2000-rebalance", ["When to use"], { skills }),
|
|
141062
141195
|
"",
|
|
141063
|
-
"2
|
|
141064
|
-
"
|
|
141196
|
+
"STEP 2 \u2014 Identify optimization levers and present a plan BEFORE executing:",
|
|
141197
|
+
"",
|
|
141198
|
+
"\u{1F527} FULL OPTIMIZATION",
|
|
141199
|
+
"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
141065
141200
|
"",
|
|
141066
|
-
"
|
|
141067
|
-
"
|
|
141201
|
+
"1. IDLE FUNDS \u2014 checking > $5? \u2192 t2000_save (preview with dryRun)",
|
|
141202
|
+
"2. USDC APY GAP \u2014 current savings APY < best available? \u2192 withdraw + save plan",
|
|
141203
|
+
"3. PENDING REWARDS \u2014 any unclaimed? \u2192 t2000_claim_rewards or t2000_harvest_rewards",
|
|
141204
|
+
"4. STALE ALLOCATIONS \u2014 any non-USDC tokens that should be swap-and-saved? \u2192 t2000_swap then t2000_save (see t2000-rebalance for atomic version)",
|
|
141068
141205
|
"",
|
|
141069
|
-
"
|
|
141206
|
+
"STEP 3 \u2014 Present the summary table:",
|
|
141070
141207
|
"",
|
|
141071
141208
|
" Action | Impact | Status",
|
|
141072
141209
|
" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500|\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500|\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
|
|
@@ -141075,15 +141212,15 @@ ${context}
|
|
|
141075
141212
|
" Claim rewards | $X.XX | Ready",
|
|
141076
141213
|
" Already optimal | \u2014 | Skipped",
|
|
141077
141214
|
"",
|
|
141078
|
-
'Ask
|
|
141079
|
-
"If everything is already optimal, say so clearly."
|
|
141215
|
+
'STEP 4 \u2014 Ask "Want me to execute all ready actions?" \u2014 execute sequentially as confirmed.',
|
|
141216
|
+
"If everything is already optimal, say so clearly. Do not invent work."
|
|
141080
141217
|
].join("\n")
|
|
141081
141218
|
}
|
|
141082
141219
|
}]
|
|
141083
141220
|
})
|
|
141084
141221
|
);
|
|
141085
141222
|
}
|
|
141086
|
-
var PKG_VERSION = "2.
|
|
141223
|
+
var PKG_VERSION = "2.4.0";
|
|
141087
141224
|
console.log = (...args) => console.error("[log]", ...args);
|
|
141088
141225
|
console.warn = (...args) => console.error("[warn]", ...args);
|
|
141089
141226
|
async function startMcpServer(opts) {
|
|
@@ -141099,6 +141236,7 @@ async function startMcpServer(opts) {
|
|
|
141099
141236
|
registerWriteTools(server, agent);
|
|
141100
141237
|
registerSafetyTools(server, agent);
|
|
141101
141238
|
registerPrompts(server);
|
|
141239
|
+
registerSkillPrompts(server);
|
|
141102
141240
|
const transport = new StdioServerTransport();
|
|
141103
141241
|
await server.connect(transport);
|
|
141104
141242
|
}
|
|
@@ -141173,4 +141311,4 @@ axios/dist/node/axios.cjs:
|
|
|
141173
141311
|
@scure/bip39/index.js:
|
|
141174
141312
|
(*! scure-bip39 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) *)
|
|
141175
141313
|
*/
|
|
141176
|
-
//# sourceMappingURL=dist-
|
|
141314
|
+
//# sourceMappingURL=dist-WS6MYX6E.js.map
|