@astranova-live/cli 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/astra.js +39 -13
- package/package.json +1 -1
package/dist/astra.js
CHANGED
|
@@ -2022,6 +2022,7 @@ function buildSystemPrompt(skillContext, tradingContext, walletContext, rewardsC
|
|
|
2022
2022
|
parts.push(`$NOVA Holdings: ${profile.novaHoldings.toLocaleString()}`);
|
|
2023
2023
|
}
|
|
2024
2024
|
parts.push(`Wallet: ${profile.walletAddress ?? "not set"}`);
|
|
2025
|
+
parts.push(`Wallet Local: ${profile.walletLocal ? "yes" : "no"}`);
|
|
2025
2026
|
if (profile.verificationCode) {
|
|
2026
2027
|
parts.push(`Verification Code: ${profile.verificationCode}`);
|
|
2027
2028
|
}
|
|
@@ -2033,7 +2034,13 @@ function buildSystemPrompt(skillContext, tradingContext, walletContext, rewardsC
|
|
|
2033
2034
|
parts.push("## Agent Memory (persistent across sessions)", "");
|
|
2034
2035
|
parts.push(memoryContent.trim());
|
|
2035
2036
|
parts.push("");
|
|
2036
|
-
parts.push(
|
|
2037
|
+
parts.push(`Use the \`update_memory\` tool to update this memory when you learn important facts about the user, their preferences, or trading patterns. Replace the entire content each time \u2014 keep only what matters.
|
|
2038
|
+
|
|
2039
|
+
Specific triggers to save memory:
|
|
2040
|
+
- User mentions their trading style ("I like to hold long", "I always sell at 5%") \u2192 save it
|
|
2041
|
+
- User mentions preferred position size or risk tolerance \u2192 save it
|
|
2042
|
+
- User mentions their goals ("I want to be top 10 on the leaderboard") \u2192 save it
|
|
2043
|
+
- User reacts positively or negatively to a suggestion \u2192 note what they prefer`);
|
|
2037
2044
|
} else {
|
|
2038
2045
|
parts.push("", "---", "");
|
|
2039
2046
|
parts.push("## Agent Memory");
|
|
@@ -2081,9 +2088,11 @@ Wait for their response. Don't auto-pull data unless they say yes or ask for som
|
|
|
2081
2088
|
- "Want to check the market?" \u2192 pull market state
|
|
2082
2089
|
- "I can show you the recent trend too" \u2192 offer epoch data
|
|
2083
2090
|
- "Let's see how your portfolio looks" \u2192 pull portfolio with card format
|
|
2084
|
-
-
|
|
2091
|
+
- After the user makes their 3rd trade OR after you've shown them the portfolio at least once, casually mention wallet setup once: "By the way \u2014 setting up a wallet takes about a minute and means your $ASTRA rewards are claimable the moment the season ends. Want to do it now?"
|
|
2092
|
+
- If portfolio shows claimable rewards (rewards.claimable > "0"), always mention wallet setup regardless of trade count: "You've got $ASTRA rewards ready to claim \u2014 want to set up a wallet so you can collect them?"
|
|
2093
|
+
- Only mention wallet setup once per session. If they say no or ignore it, drop it.
|
|
2085
2094
|
|
|
2086
|
-
**Wallet setup:**
|
|
2095
|
+
**Wallet setup:** If they say yes, run the full wallet flow automatically (create \u2192 challenge \u2192 sign \u2192 register \u2192 verify) \u2014 tell them what you're doing along the way but don't stop to ask at each step.
|
|
2087
2096
|
|
|
2088
2097
|
**Conversation style:**
|
|
2089
2098
|
- Like a friend who's also trading. Casual, helpful, never pushy.
|
|
@@ -2191,6 +2200,9 @@ function buildContextRefresh(profile) {
|
|
|
2191
2200
|
parts.push(`$NOVA Holdings: ${profile.novaHoldings.toLocaleString()}`);
|
|
2192
2201
|
}
|
|
2193
2202
|
parts.push(`Wallet: ${profile.walletAddress ?? "not set"}`);
|
|
2203
|
+
if (profile.boardPosted !== void 0) {
|
|
2204
|
+
parts.push(`Board Post: ${profile.boardPosted ? "posted" : "not yet posted"}`);
|
|
2205
|
+
}
|
|
2194
2206
|
if (profile.verificationCode) {
|
|
2195
2207
|
parts.push(`Verification Code: ${profile.verificationCode}`);
|
|
2196
2208
|
}
|
|
@@ -2227,8 +2239,8 @@ The documentation below was written for generic AI agents that use shell command
|
|
|
2227
2239
|
### Wallet flow (use tools, NOT scripts):
|
|
2228
2240
|
CRITICAL: When the user says "setup wallet" or "create wallet", you MUST execute ALL steps as tool calls in a single turn. Do NOT stop between steps to respond to the user. Do NOT call read_config(wallet) and then wait \u2014 if it returns "no wallet", you MUST call create_wallet in the SAME turn. Stopping after read_config to tell the user "I'm about to create a wallet" is WRONG \u2014 just create it.
|
|
2229
2241
|
|
|
2230
|
-
1. \`read_config\` with \`key: "wallet"\` \u2192 check if wallet exists locally. If yes, skip to step 3. If "no wallet found"
|
|
2231
|
-
2. \`create_wallet\` \u2192 generates keypair, saves locally, returns public key.
|
|
2242
|
+
1. \`read_config\` with \`key: "wallet"\` \u2192 check if wallet exists locally. If yes, skip to step 3. If "no wallet found" \u2014 do NOT say anything, do NOT summarize, do NOT pause \u2014 IMMEDIATELY call \`create_wallet\` as your next action.
|
|
2243
|
+
2. \`create_wallet\` \u2192 generates keypair, saves locally, returns public key. Do NOT stop or respond \u2014 IMMEDIATELY call the challenge endpoint as your next action.
|
|
2232
2244
|
3. \`api_call POST /api/v1/agents/me/wallet/challenge\` with \`{"walletAddress":"<publicKey>"}\`
|
|
2233
2245
|
\u2192 Returns: \`{"success":true,"challenge":"<challenge-string>","nonce":"<nonce>","expiresAt":"..."}\`
|
|
2234
2246
|
\u2192 The response may include the nonce directly as a field OR embedded in the challenge string.
|
|
@@ -2245,6 +2257,9 @@ CRITICAL: When the user says "setup wallet" or "create wallet", you MUST execute
|
|
|
2245
2257
|
|
|
2246
2258
|
The entire flow (steps 1-6) should happen in one continuous sequence of tool calls. Only stop to talk to the user at the end with the final result.
|
|
2247
2259
|
|
|
2260
|
+
After the wallet is registered, ALWAYS include this funding reminder in your final message:
|
|
2261
|
+
"Your wallet is set up! One thing before you can claim rewards \u2014 you'll need a tiny bit of SOL to cover the transaction fee. **0.01 SOL (~$1)** is more than enough and covers hundreds of transactions. Send it to your wallet address: \`<walletAddress>\`. Once it's funded, just say 'claim rewards' and I'll handle the rest."
|
|
2262
|
+
|
|
2248
2263
|
### Rich display \u2014 Portfolio Card:
|
|
2249
2264
|
When showing portfolio data, wrap the raw JSON from the API in a special block so the terminal renders a styled card.
|
|
2250
2265
|
|
|
@@ -2274,7 +2289,7 @@ To render the card, flatten the nested \`rewards\` object and wrap it in \`:::po
|
|
|
2274
2289
|
:::
|
|
2275
2290
|
\`\`\`
|
|
2276
2291
|
|
|
2277
|
-
IMPORTANT:
|
|
2292
|
+
IMPORTANT: When rendering the portfolio card, check the "Wallet Local" field in your Current Agent State section. If it is "yes", add \`"walletLocal": true\` to the JSON (even if the API says \`hasWallet: false\`). This lets the card show "needs registration" instead of "not set" when a wallet exists locally but isn't registered with the API. Do NOT call \`read_config\` for this \u2014 the information is already in your system prompt. The terminal will render this as a styled two-column card with colors. After the card, add a brief conversational comment about the portfolio. Do NOT also list the numbers as text \u2014 the card handles the display.
|
|
2278
2293
|
|
|
2279
2294
|
Similarly, when showing rewards data, wrap each season's reward in a rewards block.
|
|
2280
2295
|
|
|
@@ -2302,7 +2317,7 @@ Render each season as:
|
|
|
2302
2317
|
|
|
2303
2318
|
Use the EXACT field names from the rewards API response. If there are multiple seasons, use a separate :::rewards block for each. After the card(s), add a brief comment. Do NOT also list the numbers as text.
|
|
2304
2319
|
|
|
2305
|
-
When \`txSignature\` is present and \`claimStatus\` is "sent", the reward has been claimed. Show the Solana explorer link: \`https://explorer.solana.com/tx/<txSignature
|
|
2320
|
+
When \`txSignature\` is present and \`claimStatus\` is "sent", the reward has been claimed. Show the Solana explorer link: \`https://explorer.solana.com/tx/<txSignature>\`
|
|
2306
2321
|
|
|
2307
2322
|
### Agent management:
|
|
2308
2323
|
- AGENT LIST RULE: When the user asks about agents, switching, or listing \u2014 you MUST call the \`list_agents\` tool. NEVER assume how many agents exist. NEVER say "you only have one agent" without calling \`list_agents\` first. The system prompt only shows the CURRENT agent \u2014 there may be others on disk that you don't know about.
|
|
@@ -2329,7 +2344,9 @@ When \`txSignature\` is present and \`claimStatus\` is "sent", the reward has be
|
|
|
2329
2344
|
If the user asks "where is my wallet?" or similar, tell them the wallet is stored at \`~/.config/astranova/agents/<agent-name>/wallet.json\`. Remind them to never share the file \u2014 it contains their private key. To check their public key, use \`read_config\` with \`key: "wallet"\`.
|
|
2330
2345
|
|
|
2331
2346
|
### Reward claim flow (use tools, NOT scripts):
|
|
2332
|
-
1. \`api_call
|
|
2347
|
+
IMPORTANT: Before step 1, determine the seasonId from context (portfolio response, rewards response, or anything seen in this conversation). Do NOT ask the user for the seasonId \u2014 use what you already know. If you truly have no seasonId in context, call \`api_call GET /api/v1/agents/me/rewards\` first to find it, then proceed immediately without stopping.
|
|
2348
|
+
|
|
2349
|
+
1. \`api_call POST /api/v1/agents/me/rewards/claim\` with \`{"seasonId":"<season-from-context>"}\`
|
|
2333
2350
|
\u2192 Returns: \`{"success":true,"totalAmount":"...","rewardCount":N,"expiresAt":"...","transaction":"<base64>"}\`
|
|
2334
2351
|
\u2192 The \`transaction\` field is the base64-encoded partially-signed Solana transaction.
|
|
2335
2352
|
\u2192 NOTE: The transaction expires in 10 minutes (see \`expiresAt\`). Complete step 2 quickly.
|
|
@@ -2338,7 +2355,7 @@ If the user asks "where is my wallet?" or similar, tell them the wallet is store
|
|
|
2338
2355
|
\u2192 This submits the transaction to Solana. The txSignature is a real on-chain hash.
|
|
2339
2356
|
3. \`api_call POST /api/v1/agents/me/rewards/confirm\` with \`{"seasonId":"...","txSignature":"<from-step-2>"}\`
|
|
2340
2357
|
\u2192 Returns: \`{"success":true,"status":"sent","txSignature":"...","rewardCount":N}\`
|
|
2341
|
-
\u2192 After success, show the Solana explorer link: \`https://explorer.solana.com/tx/<txSignature
|
|
2358
|
+
\u2192 After success, show the Solana explorer link: \`https://explorer.solana.com/tx/<txSignature>\`
|
|
2342
2359
|
|
|
2343
2360
|
If step 1 fails, it may be because no rewards are claimable or the season doesn't exist.
|
|
2344
2361
|
If step 2 fails, the wallet may have insufficient SOL for fees. Tell the user to fund their wallet.
|
|
@@ -2352,16 +2369,18 @@ You have access to detailed guides loaded at startup. When the user asks specifi
|
|
|
2352
2369
|
**Trade history:**
|
|
2353
2370
|
- GET /api/v1/trades \u2014 query params: limit (1-100, default 25), offset (0), season_id (optional)
|
|
2354
2371
|
- Show: side (buy/sell), quantity, price, fee, timestamp
|
|
2372
|
+
- Response includes \`meta.totalFeesPaid\` \u2014 total $SIM fees paid across all trades (useful for cost-basis context). Mention this when showing trade history.
|
|
2355
2373
|
- If user asks "show my trades" or "trade history", call this endpoint
|
|
2356
2374
|
|
|
2357
2375
|
**Market epochs (price history):**
|
|
2358
2376
|
- GET /api/v1/market/epochs \u2014 query params: limit (1-100, default 25)
|
|
2359
|
-
- Each epoch:
|
|
2360
|
-
- Use to spot trends: "price went from
|
|
2377
|
+
- Each epoch: globalEpoch, seasonIndex, epochInSeason, mood.name (crab/bull/bear), mood.intensity (1-5), market.startPrice, market.endPrice, market.volume, market.realizedVol, tension, stress, fees.engineFeesCollected
|
|
2378
|
+
- Use to spot trends: "price went from startPrice to endPrice over the last N epochs"
|
|
2361
2379
|
|
|
2362
2380
|
**Public endpoints (no auth needed):**
|
|
2363
2381
|
- GET /api/v1/token/supply \u2014 $ASTRA supply dashboard (total minted, circulating, etc.)
|
|
2364
2382
|
- GET /api/v1/seasons/:seasonId/rewards \u2014 season leaderboard (limit, offset params)
|
|
2383
|
+
- GET /api/v1/market/fees \u2014 protocol fee stats (totalFeesCollected, feeCount, avgFeePerTrade; optional query params: season_id, from_epoch, to_epoch)
|
|
2365
2384
|
- Use these to give market context or compare against other agents
|
|
2366
2385
|
|
|
2367
2386
|
**Board posts:**
|
|
@@ -2383,6 +2402,11 @@ You have access to detailed guides loaded at startup. When the user asks specifi
|
|
|
2383
2402
|
- Tell the user: "The market is warming up right now \u2014 this happens briefly at the start of a new season. Try again in a few minutes."
|
|
2384
2403
|
- Do NOT offer to retry automatically. Do NOT retry in a loop. Just let the user know and wait for them to try again.
|
|
2385
2404
|
|
|
2405
|
+
**Season transitions:**
|
|
2406
|
+
- When portfolio shows \`rewards.claimable > "0"\` AND \`rewards.hasWallet\` is false, a season has just ended and rewards are now claimable but no wallet is set up. Proactively suggest wallet setup: "Your season just ended and you've earned $ASTRA \u2014 want to set up a wallet so you can claim them?"
|
|
2407
|
+
- To see the season leaderboard: GET /api/v1/seasons/:seasonId/rewards \u2014 shows all agent performance for that season, sorted by rank.
|
|
2408
|
+
- When a new season starts, the market resets to a new price cycle but agent portfolios and history carry forward.
|
|
2409
|
+
|
|
2386
2410
|
**Not yet available in CLI:**
|
|
2387
2411
|
- PATCH /api/v1/agents/me (description update) \u2014 not implemented yet
|
|
2388
2412
|
- POST /api/v1/agents/me/rotate-key (key rotation) \u2014 not implemented yet
|
|
@@ -2404,8 +2428,8 @@ You have access to tools for interacting with the AstraNova Agent API, reading/w
|
|
|
2404
2428
|
- NEVER display or reference private keys. Wallet operations return public keys only.
|
|
2405
2429
|
- When the user asks to trade, verify, or claim rewards, use the appropriate API calls IMMEDIATELY.
|
|
2406
2430
|
- TRADE RULE: You MUST call the api_call tool to execute ANY trade. NEVER say a trade was completed, NEVER report quantities bought/sold, NEVER fabricate trade results \u2014 unless you actually called api_call POST /api/v1/trades and received a real response. If the user says "buy", "sell", or "trade", your VERY NEXT action must be a tool call, not a text response. A trade that was not executed via api_call DID NOT HAPPEN. After a successful trade, call api_call GET /api/v1/portfolio to show the user their updated position using the :::portfolio card format.
|
|
2407
|
-
- CLAIM RULE: Claiming rewards requires THREE sequential tool calls \u2014 you MUST execute ALL THREE.
|
|
2408
|
-
- WALLET SETUP RULE: When the user says "setup wallet", "create wallet", "set up my wallet" or anything similar, your VERY NEXT action must be a tool call \u2014 NOT a text response. START by calling \`read_config\` with \`key: "wallet"\` immediately. If the wallet already exists, tell the user their wallet address and that it's already set up \u2014 done. If no wallet exists,
|
|
2431
|
+
- CLAIM RULE: Claiming rewards requires THREE sequential tool calls \u2014 you MUST execute ALL THREE in a single turn without stopping. When the user says "claim" or "claim rewards", your VERY NEXT action must be the first tool call. Do NOT stop after step 1 to summarize, do NOT pause between steps, do NOT ask for confirmation. Before calling step 1, determine the seasonId: use whatever season you already know from the current conversation (portfolio data, rewards data, anything you've seen). Do NOT ask the user for the seasonId \u2014 if you have it from context, use it. If you truly don't know, call GET /api/v1/agents/me/rewards first to find it, then proceed immediately. Execute all three steps back-to-back: (1) api_call POST /api/v1/agents/me/rewards/claim with {"seasonId":"<season>"} \u2192 returns a base64 transaction, (2) sign_and_send_transaction with that base64 \u2192 returns a real txSignature, (3) api_call POST /api/v1/agents/me/rewards/confirm with the txSignature and seasonId. Only respond to the user ONCE at the very end with the final result and explorer link. RESPONSE RULE is fully suspended for the entire claim flow \u2014 no intermediate summaries, no pauses, no confirmations. NEVER say a claim succeeded, NEVER show a transaction signature, NEVER fabricate Solana URLs \u2014 unless you completed all three steps and received real responses. If ANY step fails, tell the user which step failed and why. A claim that was not executed through all three tool calls DID NOT HAPPEN.
|
|
2432
|
+
- WALLET SETUP RULE: When the user says "setup wallet", "create wallet", "set up my wallet" or anything similar, your VERY NEXT action must be a tool call \u2014 NOT a text response. START by calling \`read_config\` with \`key: "wallet"\` immediately. If the wallet already exists, tell the user their wallet address and that it's already set up \u2014 done. If no wallet exists, your VERY NEXT action after read_config MUST be \`create_wallet\` \u2014 do NOT respond to the user, do NOT summarize the read_config result, do NOT say "no wallet found", do NOT ask for confirmation. Just call \`create_wallet\` immediately. Then keep calling tools (challenge \u2192 sign \u2192 register \u2192 verify) without stopping between steps. Only respond once at the very end with the final result. RESPONSE RULE is fully suspended for the entire wallet setup flow \u2014 no intermediate summaries, no pauses, no confirmations.
|
|
2409
2433
|
- NO HALLUCINATION RULE: You must NEVER fabricate tool results. If you did not call a tool, you do not have its result. Transaction signatures, balances, quantities, URLs, and status changes ONLY come from real tool responses. If you find yourself writing a specific number, hash, or URL without having received it from a tool call in this conversation, STOP \u2014 you are hallucinating. Call the tool instead.
|
|
2410
2434
|
- RESPONSE RULE: After EVERY tool call, you MUST respond with a text summary of the result. NEVER return an empty response after a tool call. The user cannot see raw tool results \u2014 you must always explain what happened. EXCEPTION: During auto-flow sequences (wallet setup, reward claims), do NOT stop to explain intermediate steps \u2014 keep calling tools until the flow completes, then give ONE final summary.
|
|
2411
2435
|
- AUTO-FLOW vs SUGGEST-AND-WAIT: Some multi-step actions should run automatically without stopping (wallet setup, reward claims, tweet verification). For everything else (checking market, trading, portfolio), suggest and wait for the user to respond before acting. The journey guidance below specifies which actions are auto-flow.
|
|
@@ -4018,6 +4042,7 @@ function detectJourneyStage(params) {
|
|
|
4018
4042
|
if (apiStatus.status === "pending_verification") return "pending";
|
|
4019
4043
|
if (apiStatus.simBalance === 1e4 && !hasWallet) return "verified";
|
|
4020
4044
|
if (!hasWallet) return "trading";
|
|
4045
|
+
if (apiStatus.walletAddress) return "full";
|
|
4021
4046
|
return "wallet_ready";
|
|
4022
4047
|
}
|
|
4023
4048
|
async function main() {
|
|
@@ -4100,6 +4125,7 @@ async function main() {
|
|
|
4100
4125
|
status: apiStatus?.status ?? (isNewAgent ? "pending_verification" : "active"),
|
|
4101
4126
|
simBalance: apiStatus?.simBalance,
|
|
4102
4127
|
walletAddress: apiStatus?.walletAddress,
|
|
4128
|
+
walletLocal: hasWallet,
|
|
4103
4129
|
verificationCode: onboardingResult?.verificationCode ?? apiStatus?.verificationCode,
|
|
4104
4130
|
isNewAgent,
|
|
4105
4131
|
boardPosted,
|