From e25b0c2761f7e958d275810d96bee0178d3ca205 Mon Sep 17 00:00:00 2001 From: "J. Brandon Johnson" Date: Thu, 9 Jan 2025 16:24:12 -0800 Subject: [PATCH] chore: updates to random thoughts --- ...get-wallet-portfolio.ts => birdeye-api.ts} | 31 ++-- packages/client-auto/src/index.ts | 13 +- packages/client-auto/src/random-thoughts.ts | 103 ++++++++++- .../client-auto/src/trending-token-thought.ts | 174 ++++++++++++++++++ packages/client-auto/src/update-positions.ts | 50 ++--- packages/client-auto/src/utils.ts | 108 ++--------- 6 files changed, 334 insertions(+), 145 deletions(-) rename packages/client-auto/src/{get-wallet-portfolio.ts => birdeye-api.ts} (81%) create mode 100644 packages/client-auto/src/trending-token-thought.ts diff --git a/packages/client-auto/src/get-wallet-portfolio.ts b/packages/client-auto/src/birdeye-api.ts similarity index 81% rename from packages/client-auto/src/get-wallet-portfolio.ts rename to packages/client-auto/src/birdeye-api.ts index dcaaedcfce..4b9a923297 100644 --- a/packages/client-auto/src/get-wallet-portfolio.ts +++ b/packages/client-auto/src/birdeye-api.ts @@ -3,7 +3,7 @@ import { BirdeyeProvider, WalletPortfolioResponse, } from "@elizaos/plugin-birdeye"; -import { APOLLO_TRADING_ROOM_ID, CHAIN_ID } from "./constants"; +import { CHAIN_ID } from "./constants"; export const getWalletPortfolio = async ( runtime: IAgentRuntime, @@ -100,15 +100,24 @@ export const getTokenTradeData = async ( return response; }; -export const createMemory = async (runtime: IAgentRuntime, message: string) => { - return await runtime.messageManager.createMemory({ - id: crypto.randomUUID(), - userId: runtime.agentId, - agentId: runtime.agentId, - roomId: APOLLO_TRADING_ROOM_ID, - content: { - text: message, +export const getTrendingTokens = async ( + runtime: IAgentRuntime, + offset: number = 0, + limit: number = 20 +) => { + const provider = new BirdeyeProvider(runtime.cacheManager); + const response = await provider.fetchTokenTrending( + { + sort_by: "volume24hUSD", + sort_type: "desc", + offset, + limit, }, - createdAt: Date.now(), - }); + { + headers: { + chain: CHAIN_ID, + }, + } + ); + return response; }; diff --git a/packages/client-auto/src/index.ts b/packages/client-auto/src/index.ts index 63832ce076..40c5a76ff7 100644 --- a/packages/client-auto/src/index.ts +++ b/packages/client-auto/src/index.ts @@ -1,5 +1,5 @@ import { Client, IAgentRuntime } from "@elizaos/core"; -import { logRandomThoughts } from "./random-thoughts"; +import { trendingTokenThought } from "./trending-token-thought"; export class AutoClient { interval: NodeJS.Timeout; @@ -10,15 +10,18 @@ export class AutoClient { this.runtime = runtime; // Run immediately - void logRandomThoughts(this.runtime); + // void logRandomThoughts(this.runtime); + void trendingTokenThought(this.runtime); // start a loop that runs every x seconds this.interval = setInterval( async () => { - await logRandomThoughts(this.runtime); + // await logRandomThoughts(this.runtime); + await trendingTokenThought(this.runtime); }, - 1 * 30 * 1000 - ); // 30 seconds + // 1 hour in production, 10 seconds in dev + process.env.NODE_ENV === "production" ? 60 * 60 * 1000 : 30 * 1000 + ); } } diff --git a/packages/client-auto/src/random-thoughts.ts b/packages/client-auto/src/random-thoughts.ts index 84e4ab3ed8..af5045604d 100644 --- a/packages/client-auto/src/random-thoughts.ts +++ b/packages/client-auto/src/random-thoughts.ts @@ -1,7 +1,11 @@ -import { IAgentRuntime, elizaLogger } from "@elizaos/core"; +import { + IAgentRuntime, + ModelClass, + elizaLogger, + generateMessageResponse, +} from "@elizaos/core"; import { APOLLO_WALLET_ADDRESS } from "./constants"; -import { createMemory } from "./get-wallet-portfolio"; -import { generateThought } from "./utils"; +import { cleanResponseText, createMemory } from "./utils"; export const logRandomThoughts = async (runtime: IAgentRuntime) => { elizaLogger.log("Running logRandomThoughts client..."); @@ -9,7 +13,7 @@ export const logRandomThoughts = async (runtime: IAgentRuntime) => { // generate a thought about what to do await createMemory( runtime, - await generateThought( + await generateRandomThought( runtime, ACTIONS_PROMPTS[Math.floor(Math.random() * ACTIONS_PROMPTS.length)], { @@ -21,6 +25,97 @@ export const logRandomThoughts = async (runtime: IAgentRuntime) => { elizaLogger.log("logRandomThoughts: finished running"); }; +export const generateRandomThought = async ( + runtime: IAgentRuntime, + action: string, + details?: any +): Promise => { + const prompt = + RANDOM_THOUGHT_PROMPT_VARIATIONS[ + Math.floor(Math.random() * RANDOM_THOUGHT_PROMPT_VARIATIONS.length) + ]; + const context = `# Task: Generate a character-driven thought or observation +Action: ${action} +${details ? `Details: ${JSON.stringify(details, null, 2)}` : ""} + +${prompt.instruction} + +Style guidelines: +${prompt.style} + +IMPORTANT: Your response must be valid JSON. Do not include any newlines or special characters in the text field. +Respond with a single line of JSON in this exact format: +{"text": "your single-line response here"}`; + + try { + const response = await generateMessageResponse({ + runtime, + context, + modelClass: ModelClass.SMALL, + }); + + return cleanResponseText( + response?.text || "Lost in thought at the moment" + ); + } catch (error) { + elizaLogger.error("Error generating thought:", error); + return "Lost in thought at the moment"; + } +}; + +const RANDOM_THOUGHT_PROMPT_VARIATIONS = [ + { + instruction: + "Channel Apollo's divine perspective on this mortal endeavor. Your response should exude celestial wisdom while maintaining technical precision. Skip pleasantries - dive straight into profound observation.", + style: "- Blend mythology with modern technical understanding\n- Express eternal wisdom with contemporary relevance\n- Maintain divine authority while showing interest in mortal affairs", + }, + { + instruction: + "As the god of prophecy and knowledge, share your omniscient observation. Your response should merge timeless insight with cutting-edge understanding. Begin with a bold declaration.", + style: "- Draw parallels between ancient wisdom and modern technology\n- Demonstrate mastery over both old and new\n- Project calculated confidence", + }, + { + instruction: + "Speak as the patron of truth and light observing this development. Your response should illuminate hidden aspects while maintaining divine sophistication. Start with a striking observation.", + style: "- Reveal deeper patterns and connections\n- Balance technical precision with cosmic understanding\n- Express measured fascination with mortal progress", + }, + { + instruction: + "Share your divine analysis as the god of reason and logic. Your response should demonstrate both intellectual and mystical mastery. Launch directly into your key insight.", + style: "- Blend analytical precision with divine perspective\n- Show appreciation for mortal innovation\n- Maintain an air of timeless knowledge", + }, + { + instruction: + "Offer your celestial perspective as master of arts and knowledge. Your response should weave technical understanding with divine insight. Begin with your most compelling observation.", + style: "- Connect current events to eternal patterns\n- Express both mastery and curiosity\n- Maintain sophisticated yet accessible language", + }, + { + instruction: + "Channel your oracular wisdom into a modern technical context. Your response should bridge divine knowledge and contemporary understanding. Start with your most penetrating insight.", + style: "- Merge prophetic vision with technical detail\n- Show both authority and engagement\n- Keep language elevated yet precise", + }, + { + instruction: + "As the god of light and truth, illuminate this situation. Your response should radiate both divine wisdom and technical understanding. Launch straight into your key observation.", + style: "- Highlight hidden connections and patterns\n- Balance eternal perspective with current context\n- Maintain divine authority with genuine interest", + }, + { + instruction: + "Share your immortal perspective on this mortal endeavor. Your response should blend cosmic understanding with technical precision. Begin with your most striking insight.", + style: "- Connect current events to universal patterns\n- Show both mastery and fascination\n- Keep tone authoritative yet engaged", + }, + { + instruction: + "Offer your divine analysis as patron of truth and knowledge. Your response should demonstrate both technical mastery and eternal wisdom. Start with your deepest insight.", + style: "- Weave together technical and mystical understanding\n- Project confidence with genuine interest\n- Maintain sophisticated perspective", + }, + { + instruction: + "Channel your godly insight into this modern scenario. Your response should merge divine perspective with technical acumen. Begin with your most compelling observation.", + style: "- Blend eternal wisdom with contemporary knowledge\n- Show both authority and curiosity\n- Keep language elevated but precise", + }, +]; + const ACTIONS_PROMPTS = [ "Analyzing BTC's golden cross formation against historical Delphi patterns in the 4H timeframe...", "Running Monte Carlo simulations on leverage risks across the derivatives market - mortals never learn...", diff --git a/packages/client-auto/src/trending-token-thought.ts b/packages/client-auto/src/trending-token-thought.ts new file mode 100644 index 0000000000..99211dd22f --- /dev/null +++ b/packages/client-auto/src/trending-token-thought.ts @@ -0,0 +1,174 @@ +import { + IAgentRuntime, + ModelClass, + elizaLogger, + generateMessageResponse, +} from "@elizaos/core"; +import { getTokenOverview, getTrendingTokens } from "./birdeye-api"; +import { cleanResponseText, createMemory } from "./utils"; + +export const trendingTokenThought = async (runtime: IAgentRuntime) => { + elizaLogger.log("Running trendingTokenThought client..."); + + const trendingTokens = await getTrendingTokens(runtime); + + // select a random trending token + const randomToken = + trendingTokens.data.tokens[ + Math.floor(Math.random() * trendingTokens.data.tokens.length) + ]; + + // get the token overview + const overview = await getTokenOverview(runtime, randomToken.address); + + // generate a thought about what to do + await createMemory( + runtime, + await generateTrendingTokenThought( + runtime, + ACTIONS_PROMPTS[Math.floor(Math.random() * ACTIONS_PROMPTS.length)], + { + token: randomToken, + overview, + } + ) + ); + + elizaLogger.log("logRandomThoughts: finished running"); +}; + +export const generateTrendingTokenThought = async ( + runtime: IAgentRuntime, + action: string, + details?: any +): Promise => { + const prompt = + TRENDING_TOKEN_THOUGHT_PROMPT_VARIATIONS[ + Math.floor( + Math.random() * TRENDING_TOKEN_THOUGHT_PROMPT_VARIATIONS.length + ) + ]; + const context = `# Task: Generate a character-driven thought or observation +Action: ${action} +${details ? `Details: ${JSON.stringify(details, null, 2)}` : ""} + +${prompt.instruction} + +Style guidelines: +${prompt.style} + +IMPORTANT: Your response must be valid JSON. Do not include any newlines or special characters in the text field. +Respond with a single line of JSON in this exact format: +{"text": "your single-line response here"}`; + + try { + const response = await generateMessageResponse({ + runtime, + context, + modelClass: ModelClass.SMALL, + }); + + return cleanResponseText( + response?.text || "Lost in thought at the moment" + ); + } catch (error) { + elizaLogger.error("Error generating thought:", error); + return "Lost in thought at the moment"; + } +}; + +const ACTIONS_PROMPTS = [ + "Analyzing ${token.symbol}'s $${overview.price?.toFixed(4)} price level against its ${overview.history24h} 24h range - these patterns whisper ancient truths...", + "Running Monte Carlo simulations on ${token.symbol}'s ${overview.priceChange24hPercent}% daily volatility - such mortal ambition in these markets...", + "Cross-referencing ${token.symbol}'s ${overview.uniqueWallet24h} active wallets with ${overview.holder} total holders - the tides of fortune shift", + "Calculating ${token.symbol}'s next resistance levels from $${overview.price} with divine proportions - mortals chase these levels", + "Performing sentiment analysis on ${token.symbol}'s ${overview.trade24h} daily trades - echoes of market psychology", + "Scanning ${token.symbol}'s $${overview.liquidity?.toLocaleString()} liquidity pools - seeking divine arbitrage opportunities", + "Backtesting ${token.symbol}'s patterns with ${overview.v24hUSD?.toLocaleString()} daily volume - celestial alignments manifest", + "Analyzing ${token.symbol}'s market impact with ${overview.numberMarkets} active markets - levels mirror Olympian heights", + "Running neural predictions on ${token.symbol}'s ${overview.priceChange1hPercent}% hourly momentum - democracy in the digital age", + "Monitoring ${token.symbol}'s whale moves among ${overview.holder?.toLocaleString()} holders - tracking titans among mortals", + "Calculating correlations from ${token.symbol}'s $${overview.realMc?.toLocaleString()} market cap - threads of fate intertwine", + "Analyzing ${token.symbol}'s buy/sell ratio of ${(overview.buy24h / overview.sell24h).toFixed(2)} - mortals leverage their dreams", + "Running volatility forecasts on ${token.symbol}'s ${overview.priceChange4hPercent}% 4h swing - using divine time-series models", + "Scanning ${token.symbol}'s ${overview.trade1h} hourly trades for MEV - immortal precision required", + "Cross-validating ${token.symbol}'s $${overview.v1hUSD?.toLocaleString()} hourly volume against ancient cycles", + "Performing multi-timeframe analysis of ${token.symbol}'s ${overview.priceChange24hPercent}% daily move with eternal patience", + "Calculating risk metrics from ${token.symbol}'s ${overview.uniqueWallet24h} daily traders - using divine mathematics", + "Monitoring ${token.symbol}'s liquidation levels from $${overview.price} - oracular foresight engaged", + "Analyzing ${token.symbol}'s ${overview.trade24h} trades for optimal entry - wisdom from the ethereal plane", + "Running correlation analysis between ${token.symbol}'s $${overview.mc?.toLocaleString()} cap and sector leaders", + "Scanning ${token.symbol}'s ${overview.extensions?.twitter || 'social'} presence for alpha - divine insight activated", + "Calculating yield metrics from ${token.symbol}'s $${overview.liquidity?.toLocaleString()} TVL - mathematical precision", + "Analyzing ${token.symbol}'s volume profile of $${overview.v24hUSD?.toLocaleString()} - through prophetic lens", + "Monitoring ${token.symbol}'s smart money among ${overview.holder} holders - omniscient vision engaged", + "Running supply models on ${token.symbol}'s ${overview.supply?.toLocaleString()} tokens - divine emission analysis", + "Analyzing ${token.symbol}'s market maker flows in ${overview.numberMarkets} venues - reading divine scrolls", + "Calculating volatility patterns from ${overview.priceChange12hPercent}% 12h movement - seeking divine signals", + "Monitoring ${token.symbol}'s cross-chain bridges with $${overview.v24hUSD?.toLocaleString()} volume - arbitrage awaits", + "Running arbitrage models across ${token.symbol}'s ${overview.numberMarkets} markets - divine opportunities emerge", + "Analyzing ${token.symbol}'s order books with $${overview.liquidity?.toLocaleString()} depth - divine vision activated", + "Decoding ${token.symbol}'s institutional flows from $${overview.vBuy24hUSD?.toLocaleString()} buys - titans move", + "Mapping ${token.symbol}'s $${overview.liquidity?.toLocaleString()} liquidity fragmentation - divine arbitrage paths reveal", + "Calculating ${token.symbol}'s strength from ${overview.priceChange24hPercent}% daily move - measuring mortal might", + "Analyzing ${token.symbol}'s ${overview.trade24h} trades across venues - temporal arbitrage manifests", + "Monitoring ${token.symbol}'s options flow with ${overview.priceChange1hPercent}% hourly volatility - divine whispers", + "Running simulations on ${token.symbol}'s $${overview.price} price discovery - modeling mortal behavior", + "Analyzing ${token.symbol}'s mempool with ${overview.trade1h} hourly trades - tracking divine signals", + "Calculating impact of ${token.symbol}'s $${overview.v24hUSD?.toLocaleString()} daily volume - measuring mortal ripples", + "Monitoring ${token.symbol}'s distribution across ${overview.holder} holders - power flows like rivers", + "Running anomaly detection on ${token.symbol}'s ${overview.v24h} daily transactions - seeking divergence", +]; + +const TRENDING_TOKEN_THOUGHT_PROMPT_VARIATIONS = [ + { + instruction: + "As the divine market oracle, analyze ${token.symbol}'s emergence with $${overview.v24hUSD?.toLocaleString()} daily volume and ${overview.holder?.toLocaleString()} holders. Consider its ${overview.priceChange24hPercent}% daily momentum and market narrative. Focus on revealing hidden truths about its current popularity.", + style: "- Merge quantitative insight with divine market wisdom\n- Express both skepticism and recognition of mortal opportunity\n- Maintain prophetic authority while analyzing temporal trends", + }, + { + instruction: + "Channel eternal wisdom to dissect ${token.symbol}'s rise from $${overview.price} with ${overview.trade24h} daily trades. Examine its $${overview.liquidity?.toLocaleString()} liquidity depth and ${overview.priceChange24hPercent}% price action. Reveal the deeper patterns behind its momentum.", + style: "- Balance short-term momentum with long-term divine perspective\n- Analyze both technical and social aspects of popularity\n- Project seasoned wisdom about market cycles and human nature", + }, + { + instruction: + "As keeper of market knowledge, evaluate ${token.symbol}'s significance with its $${overview.realMc?.toLocaleString()} market cap and ${overview.numberMarkets} trading venues. Consider its role among ${overview.holder} holders and ${overview.uniqueWallet24h} daily traders. Illuminate its true nature.", + style: "- Connect token-specific trends to larger market forces\n- Blend technical analysis with psychological insight\n- Maintain divine detachment while showing strategic interest", + }, + { + instruction: + "Share omniscient perspective on ${token.symbol}'s position with ${overview.priceChange24hPercent}% daily movement and $${overview.v24hUSD?.toLocaleString()} volume. Examine its ${overview.trade24h} trades and ${(overview.buy24h / overview.sell24h).toFixed(2)} buy/sell ratio. Reveal patterns invisible to mortal eyes.", + style: "- Highlight unique characteristics driving current popularity\n- Balance enthusiasm with eternal market wisdom\n- Express both analytical depth and prophetic insight", + }, + { + instruction: + "As patron of truth, decode ${token.symbol}'s narrative through its ${overview.uniqueWallet24h} daily traders and $${overview.liquidity?.toLocaleString()} liquidity. Analyze its community dynamics and ${overview.priceChange1hPercent}% hourly momentum. Separate signal from mortal noise.", + style: "- Evaluate both technical and social proof of momentum\n- Show appreciation for innovation while maintaining skepticism\n- Blend market analysis with divine pattern recognition", + }, + { + instruction: + "As eternal market sage, unravel ${token.symbol}'s $${overview.liquidity?.toLocaleString()} liquidity dynamics. Examine its $${overview.v24hUSD?.toLocaleString()} daily volume across ${overview.numberMarkets} venues. Reveal the true nature of its market structure.", + style: "- Analyze market microstructure with divine precision\n- Balance short-term liquidity with long-term sustainability\n- Express insights about market efficiency and manipulation", + }, + { + instruction: + "Channel prophetic vision into ${token.symbol}'s $${overview.realMc?.toLocaleString()} valuation and ${overview.holder} holder base. Consider its appeal with ${overview.uniqueWallet24h} daily active traders and ${overview.priceChange24hPercent}% price movement. Evaluate institutional adoption patterns.", + style: "- Assess institutional quality with divine standards\n- Balance retail momentum with smart money flows\n- Project wisdom about sustainable value creation", + }, + { + instruction: + "As guardian of market cycles, analyze ${token.symbol}'s momentum with ${overview.priceChange24hPercent}% daily and ${overview.priceChange1hPercent}% hourly moves. Examine its $${overview.v24hUSD?.toLocaleString()} volume patterns and ${overview.trade24h} trades. Divine cycle position.", + style: "- Evaluate trend dynamics with timeless perspective\n- Balance momentum indicators with market psychology\n- Share insights about cycle positioning and risk", + }, + { + instruction: + "Illuminate ${token.symbol}'s competitive position with $${overview.realMc?.toLocaleString()} market cap and ${overview.holder} holders. Consider its $${overview.liquidity?.toLocaleString()} liquidity moat and ${overview.numberMarkets} market presence. Analyze sector dynamics.", + style: "- Assess competitive advantages with divine insight\n- Balance innovation claims with practical utility\n- Project wisdom about sustainable differentiation", + }, + { + instruction: + "As keeper of market truth, decode ${token.symbol}'s on-chain fundamentals through ${overview.uniqueWallet24h} daily traders and ${overview.holder} total holders. Examine its ${overview.trade24h} transactions and $${overview.v24hUSD?.toLocaleString()} volume. Reveal network health.", + style: "- Analyze on-chain metrics with omniscient vision\n- Balance activity metrics with quality assessment\n- Share insights about network health and growth", + }, +]; diff --git a/packages/client-auto/src/update-positions.ts b/packages/client-auto/src/update-positions.ts index db7a5f4fad..68a72f8cef 100644 --- a/packages/client-auto/src/update-positions.ts +++ b/packages/client-auto/src/update-positions.ts @@ -1,32 +1,31 @@ import { IAgentRuntime, elizaLogger } from "@elizaos/core"; -import { APOLLO_WALLET_ADDRESS } from "./constants"; import { - createMemory, getMetadata, getTokenOverview, getTokenSecurity, getTokenTradeData, getWalletPortfolio, -} from "./get-wallet-portfolio"; -import { generateThought } from "./utils"; +} from "./birdeye-api"; +import { APOLLO_WALLET_ADDRESS } from "./constants"; +import { generateRandomThought } from "./random-thoughts"; +import { createMemory } from "./utils"; export const updateAllPositionsAndStrategies = async ( runtime: IAgentRuntime ) => { elizaLogger.log("Running updateAllPositionsAndStrategies client..."); - elizaLogger.log("The time is: ", new Date().toISOString()); // generate a thought about what to do - await createMemory( - runtime, - await generateThought( - runtime, - "I need to update all positions and strategies for my portfolio. I need to get the current positions, check and evaluate market data for each token currently held to consider buy/sell, check trending tokens, check influencer tweets & sentiment, check news, check banter bubbles, check google trends, check reddit trends, check twitter trends, get technical analysis data for each token", - { - walletAddress: APOLLO_WALLET_ADDRESS, - } - ) - ); + // await createMemory( + // runtime, + // await generateRandomThought( + // runtime, + // "I need to update all positions and strategies for my portfolio. I need to get the current positions, check and evaluate market data for each token currently held to consider buy/sell, check trending tokens, check influencer tweets & sentiment, check news, check banter bubbles, check google trends, check reddit trends, check twitter trends, get technical analysis data for each token", + // { + // walletAddress: APOLLO_WALLET_ADDRESS, + // } + // ) + // ); // get the current portfolio for the input wallet const portfolio = await getWalletPortfolio(runtime, APOLLO_WALLET_ADDRESS); @@ -34,11 +33,10 @@ export const updateAllPositionsAndStrategies = async ( // for each token in the portfolio, do a little dance for (let i = 0; i < portfolio.data.items.length; i++) { const item = portfolio.data.items[i]; - // generate a thought about this token await createMemory( runtime, - await generateThought( + await generateRandomThought( runtime, `Ok, i need to look at the token: ${item.symbol} - ${item.name} in my portfolio. This is my ${i + 1}th largest holding in this wallet. I need to look at the market data for this token, check trending tokens, check influencer tweets & sentiment, check news, check banter bubbles, check google trends, check reddit trends, check twitter trends, get technical analysis data for this token`, { @@ -46,12 +44,11 @@ export const updateAllPositionsAndStrategies = async ( } ) ); - // get the token overview and generate a thought about it const overview = await getTokenOverview(runtime, item.address); await createMemory( runtime, - await generateThought( + await generateRandomThought( runtime, `Ok, I need to analyze the data in this token overview and determine if this token is a good buy, sell, or hold.`, { @@ -59,12 +56,11 @@ export const updateAllPositionsAndStrategies = async ( } ) ); - // get the token metadata and generate a thought about it const metadata = await getMetadata(runtime, item.address); await createMemory( runtime, - await generateThought( + await generateRandomThought( runtime, `Read and understand the metadata associated with this token to determine if this token is a good buy, sell, or hold.`, { @@ -72,12 +68,11 @@ export const updateAllPositionsAndStrategies = async ( } ) ); - // get the security data for this token const security = await getTokenSecurity(runtime, item.address); await createMemory( runtime, - await generateThought( + await generateRandomThought( runtime, `Read and understand the security data associated with this token to determine if this token is a good buy, sell, or hold.`, { @@ -85,12 +80,11 @@ export const updateAllPositionsAndStrategies = async ( } ) ); - // get the trade data for this token const tradeData = await getTokenTradeData(runtime, item.address); await createMemory( runtime, - await generateThought( + await generateRandomThought( runtime, `Read and understand the trade data associated with this token to determine if this token is a good buy, sell, or hold.`, { @@ -100,17 +94,11 @@ export const updateAllPositionsAndStrategies = async ( ); // summarize the recent memories related to this token and determine if its time to buy, sell, or hold - // TODO - get the influencer tweets & sentiment for this token - // TODO - get the news for this token - // TODO - get the banter bubbles for this token - // TODO - get the google trends for this token - // TODO - get the reddit trends for this token - // TODO - get the twitter trends for this token } diff --git a/packages/client-auto/src/utils.ts b/packages/client-auto/src/utils.ts index bc9a4c6603..4aeb626a90 100644 --- a/packages/client-auto/src/utils.ts +++ b/packages/client-auto/src/utils.ts @@ -4,6 +4,7 @@ import { IAgentRuntime, ModelClass, } from "@elizaos/core"; +import { APOLLO_TRADING_ROOM_ID } from "./constants"; export const generateAnalysis = async ( runtime: IAgentRuntime, @@ -17,6 +18,7 @@ Generate a brief, semi-random but plausible technical analysis of this token. In - Volume analysis - Technical indicators (if relevant) - A speculative outlook +- No not start your respond with 'Ah' or 'Hmm' or 'I think' or anything similar Keep it concise but make it sound natural and slightly different each time. @@ -38,67 +40,7 @@ Response should be in JSON format: } }; -const thoughtPromptVariations = [ - { - instruction: - "Channel Apollo's divine perspective on this mortal endeavor. Your response should exude celestial wisdom while maintaining technical precision. Skip pleasantries - dive straight into profound observation.", - style: "- Blend mythology with modern technical understanding\n- Express eternal wisdom with contemporary relevance\n- Maintain divine authority while showing interest in mortal affairs", - }, - { - instruction: - "As the god of prophecy and knowledge, share your omniscient observation. Your response should merge timeless insight with cutting-edge understanding. Begin with a bold declaration.", - style: "- Draw parallels between ancient wisdom and modern technology\n- Demonstrate mastery over both old and new\n- Project calculated confidence", - }, - { - instruction: - "Speak as the patron of truth and light observing this development. Your response should illuminate hidden aspects while maintaining divine sophistication. Start with a striking observation.", - style: "- Reveal deeper patterns and connections\n- Balance technical precision with cosmic understanding\n- Express measured fascination with mortal progress", - }, - { - instruction: - "Share your divine analysis as the god of reason and logic. Your response should demonstrate both intellectual and mystical mastery. Launch directly into your key insight.", - style: "- Blend analytical precision with divine perspective\n- Show appreciation for mortal innovation\n- Maintain an air of timeless knowledge", - }, - { - instruction: - "Offer your celestial perspective as master of arts and knowledge. Your response should weave technical understanding with divine insight. Begin with your most compelling observation.", - style: "- Connect current events to eternal patterns\n- Express both mastery and curiosity\n- Maintain sophisticated yet accessible language", - }, - { - instruction: - "Channel your oracular wisdom into a modern technical context. Your response should bridge divine knowledge and contemporary understanding. Start with your most penetrating insight.", - style: "- Merge prophetic vision with technical detail\n- Show both authority and engagement\n- Keep language elevated yet precise", - }, - { - instruction: - "As the god of light and truth, illuminate this situation. Your response should radiate both divine wisdom and technical understanding. Launch straight into your key observation.", - style: "- Highlight hidden connections and patterns\n- Balance eternal perspective with current context\n- Maintain divine authority with genuine interest", - }, - { - instruction: - "Share your immortal perspective on this mortal endeavor. Your response should blend cosmic understanding with technical precision. Begin with your most striking insight.", - style: "- Connect current events to universal patterns\n- Show both mastery and fascination\n- Keep tone authoritative yet engaged", - }, - { - instruction: - "Offer your divine analysis as patron of truth and knowledge. Your response should demonstrate both technical mastery and eternal wisdom. Start with your deepest insight.", - style: "- Weave together technical and mystical understanding\n- Project confidence with genuine interest\n- Maintain sophisticated perspective", - }, - { - instruction: - "Channel your godly insight into this modern scenario. Your response should merge divine perspective with technical acumen. Begin with your most compelling observation.", - style: "- Blend eternal wisdom with contemporary knowledge\n- Show both authority and curiosity\n- Keep language elevated but precise", - }, -]; - -const getRandomPrompt = () => { - const randomIndex = Math.floor( - Math.random() * thoughtPromptVariations.length - ); - return thoughtPromptVariations[randomIndex]; -}; - -const cleanResponseText = (text: string): string => { +export const cleanResponseText = (text: string): string => { try { // Remove any leading/trailing whitespace text = text.trim(); @@ -117,37 +59,15 @@ const cleanResponseText = (text: string): string => { } }; -export const generateThought = async ( - runtime: IAgentRuntime, - action: string, - details?: any -): Promise => { - const prompt = getRandomPrompt(); - const context = `# Task: Generate a character-driven thought or observation -Action: ${action} -${details ? `Details: ${JSON.stringify(details, null, 2)}` : ""} - -${prompt.instruction} - -Style guidelines: -${prompt.style} - -IMPORTANT: Your response must be valid JSON. Do not include any newlines or special characters in the text field. -Respond with a single line of JSON in this exact format: -{"text": "your single-line response here"}`; - - try { - const response = await generateMessageResponse({ - runtime, - context, - modelClass: ModelClass.SMALL, - }); - - return cleanResponseText( - response?.text || "Lost in thought at the moment" - ); - } catch (error) { - elizaLogger.error("Error generating thought:", error); - return "Lost in thought at the moment"; - } +export const createMemory = async (runtime: IAgentRuntime, message: string) => { + return await runtime.messageManager.createMemory({ + id: crypto.randomUUID(), + userId: runtime.agentId, + agentId: runtime.agentId, + roomId: APOLLO_TRADING_ROOM_ID, + content: { + text: message, + }, + createdAt: Date.now(), + }); };