Skip to content

Commit

Permalink
Merge branch 'develop' into feat/view-chat-history-with-agent-in-clie…
Browse files Browse the repository at this point in the history
…nt-UI
  • Loading branch information
wtfsayo authored Jan 15, 2025
2 parents b24c35f + 6381485 commit f0eebe1
Show file tree
Hide file tree
Showing 15 changed files with 486 additions and 1 deletion.
1 change: 1 addition & 0 deletions agent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"@elizaos/plugin-avalanche": "workspace:*",
"@elizaos/plugin-video-generation": "workspace:*",
"@elizaos/plugin-web-search": "workspace:*",
"@elizaos/plugin-dexscreener": "workspace:*",
"@elizaos/plugin-letzai": "workspace:*",
"@elizaos/plugin-thirdweb": "workspace:*",
"@elizaos/plugin-genlayer": "workspace:*",
Expand Down
7 changes: 6 additions & 1 deletion agent/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ import { coinmarketcapPlugin } from "@elizaos/plugin-coinmarketcap";
import { confluxPlugin } from "@elizaos/plugin-conflux";
import { createCosmosPlugin } from "@elizaos/plugin-cosmos";
import { cronosZkEVMPlugin } from "@elizaos/plugin-cronoszkevm";
import { echoChambersPlugin } from "@elizaos/plugin-echochambers";
import { evmPlugin } from "@elizaos/plugin-evm";
import { flowPlugin } from "@elizaos/plugin-flow";
import { fuelPlugin } from "@elizaos/plugin-fuel";
Expand Down Expand Up @@ -99,6 +98,9 @@ import { thirdwebPlugin } from "@elizaos/plugin-thirdweb";
import { tonPlugin } from "@elizaos/plugin-ton";
import { squidRouterPlugin } from "@elizaos/plugin-squid-router";
import { webSearchPlugin } from "@elizaos/plugin-web-search";
import { echoChambersPlugin } from "@elizaos/plugin-echochambers";
import { dexScreenerPlugin } from "@elizaos/plugin-dexscreener";

import { zksyncEraPlugin } from "@elizaos/plugin-zksync-era";
import Database from "better-sqlite3";
import fs from "fs";
Expand Down Expand Up @@ -761,6 +763,9 @@ export async function createAgent(
// character.plugins are handled when clients are added
plugins: [
bootstrapPlugin,
getSecret(character, "DEXSCREENER_API_KEY")
? dexScreenerPlugin
: null,
getSecret(character, "CONFLUX_CORE_PRIVATE_KEY")
? confluxPlugin
: null,
Expand Down
6 changes: 6 additions & 0 deletions packages/plugin-dexscreener/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*

!dist/**
!package.json
!readme.md
!tsup.config.ts
3 changes: 3 additions & 0 deletions packages/plugin-dexscreener/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import eslintGlobalConfig from "../../eslint.config.mjs";

export default [...eslintGlobalConfig];
19 changes: 19 additions & 0 deletions packages/plugin-dexscreener/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "@elizaos/plugin-dexscreener",
"version": "0.1.7-alpha.2",
"main": "dist/index.js",
"type": "module",
"types": "dist/index.d.ts",
"dependencies": {
"@elizaos/core": "workspace:*",
"tsup": "8.3.5"
},
"scripts": {
"build": "tsup --format esm --dts",
"dev": "tsup --format esm --dts --watch",
"lint": "eslint --fix --cache ."
},
"peerDependencies": {
"whatwg-url": "7.1.0"
}
}
1 change: 1 addition & 0 deletions packages/plugin-dexscreener/src/actions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./tokenAction.ts";
189 changes: 189 additions & 0 deletions packages/plugin-dexscreener/src/actions/tokenAction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
import { Action, IAgentRuntime, Memory, State, HandlerCallback } from "@elizaos/core";
import { TokenPriceProvider } from "../providers/tokenProvider";

export const priceTemplate = `Determine if this is a token price request. If it is one of the specified situations, perform the corresponding action:
Situation 1: "Get token price"
- Message contains: words like "price", "value", "cost", "worth" AND a token symbol/address
- Example: "What's the price of ETH?" or "How much is BTC worth?"
- Action: Get the current price of the token
Previous conversation for context:
{{conversation}}
You are replying to: {{message}}
`;

export class TokenPriceAction implements Action {
name = "GET_TOKEN_PRICE";
similes = ["FETCH_TOKEN_PRICE", "CHECK_TOKEN_PRICE", "TOKEN_PRICE"];
description = "Fetches and returns token price information";
suppressInitialMessage = true;
template = priceTemplate;

async validate(runtime: IAgentRuntime, message: Memory): Promise<boolean> {
const content = typeof message.content === 'string'
? message.content
: message.content?.text;

if (!content) return false;

const hasPriceKeyword = /\b(price|value|worth|cost)\b/i.test(content);
const hasToken = (
/0x[a-fA-F0-9]{40}/.test(content) ||
/[\$#]?[a-zA-Z0-9]+/i.test(content)
);

return hasPriceKeyword && hasToken;
}

async handler(
runtime: IAgentRuntime,
message: Memory,
state?: State,
_options: { [key: string]: unknown } = {},
callback?: HandlerCallback
): Promise<boolean> {
try {
// Get the provider
const provider = runtime.providers.find(p => p instanceof TokenPriceProvider);
if (!provider) {
throw new Error("Token price provider not found");
}

// Get price data
console.log("Fetching price data...");
const priceData = await provider.get(runtime, message, state);
console.log("Received price data:", priceData);

if (priceData.includes("Error")) {
throw new Error(priceData);
}

// If we have a callback, use it to send the response
if (callback) {
await callback({
text: priceData,
action: this.name
});
}

// Set the response in state to prevent further processing
if (state) {
state.responseData = {
text: priceData,
action: this.name
};
}

return true;

} catch (error) {
console.error("Error in price action handler:", error);

if (callback) {
await callback({
text: `Sorry, I couldn't fetch the token price: ${error.message}`,
action: this.name
});
}

return false;
}
}

examples = [
[
{
user: "{{user}}",
content: {
text: "check price of eth"
}
},
{
user: "{{system}}",
content: {
text: "The current price of Ethereum (ETH) is $2,345.67 with a 24h trading volume of $9.87B. The liquidity pool holds $1.23B, and the price has changed +5.43% in the last 24 hours.",
action: "GET_TOKEN_PRICE"
}
}
],
[
{
user: "{{user}}",
content: {
text: "How much is BTC worth right now?"
}
},
{
user: "{{system}}",
content: {
text: "Bitcoin (BTC) is currently trading at $42,567.89. There's $15.23B in liquidity, with a 24h volume of $25.87B. The price is up 2.15% in the last 24 hours.",
action: "GET_TOKEN_PRICE"
}
}
],
[
{
user: "{{user}}",
content: {
text: "what's the current value of $bnb"
}
},
{
user: "{{system}}",
content: {
text: "Binance Coin (BNB) is priced at $345.67 with $5.23B in liquidity. The trading volume over the last 24h is $1.87B, and the price has decreased by 1.23% during this period.",
action: "GET_TOKEN_PRICE"
}
}
],
[
{
user: "{{user}}",
content: {
text: "can you tell me the price for USDT?"
}
},
{
user: "{{system}}",
content: {
text: "Tether (USDT) is maintaining its peg at $1.00 with minimal change (+0.01%). The token has $25.23B in liquidity and has seen $45.87B in trading volume over the past 24 hours.",
action: "GET_TOKEN_PRICE"
}
}
],
[
{
user: "{{user}}",
content: {
text: "show me the cost of #SOL"
}
},
{
user: "{{system}}",
content: {
text: "Solana (SOL) is trading at $123.45, showing strong momentum with an 8.75% increase in the last 24 hours. The liquidity stands at $3.23B with a 24h trading volume of $987.54M.",
action: "GET_TOKEN_PRICE"
}
}
],
[
{
user: "{{user}}",
content: {
text: "0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0 price please"
}
},
{
user: "{{system}}",
content: {
text: "The price of Polygon (MATIC) is currently $1.23, up 3.45% in the past 24 hours. The token has $2.23B in liquidity and has seen $567.54M in trading volume today.",
action: "GET_TOKEN_PRICE"
}
}
]
];
}

export const tokenPriceAction = new TokenPriceAction();
1 change: 1 addition & 0 deletions packages/plugin-dexscreener/src/evaluators/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./tokenEvaluator.ts";
78 changes: 78 additions & 0 deletions packages/plugin-dexscreener/src/evaluators/tokenEvaluator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { Evaluator, IAgentRuntime, Memory, State } from "@elizaos/core";

export class TokenPriceEvaluator implements Evaluator {
name = "TOKEN_PRICE_EVALUATOR";
similes = ["price", "token price", "check price"];
description = "Evaluates messages for token price requests";

async validate(runtime: IAgentRuntime, message: Memory): Promise<boolean> {
const content = typeof message.content === 'string'
? message.content
: message.content?.text;

if (!content) return false;

// Check for price-related keywords
const hasPriceKeyword = /\b(price|value|worth|cost)\b/i.test(content);

// Look for either:
// 1. Ethereum address
// 2. Token symbol starting with $ or #
// 3. Token symbol after "of" or "for" (case insensitive)
const hasToken = (
/0x[a-fA-F0-9]{40}/.test(content) || // Ethereum address
/[\$#][a-zA-Z]+/.test(content) || // $TOKEN or #TOKEN format
/\b(of|for)\s+[a-zA-Z0-9]+\b/i.test(content) // "price of TOKEN" format
);

return hasPriceKeyword && hasToken;
}

async handler(runtime: IAgentRuntime, message: Memory, state?: State): Promise<string> {
return "GET_TOKEN_PRICE";
}

examples = [
{
context: "User asking for token price with address",
messages: [
{
user: "{{user}}",
content: {
text: "What's the price of 0x1234567890123456789012345678901234567890?",
action: "GET_TOKEN_PRICE"
}
}
],
outcome: "GET_TOKEN_PRICE"
},
{
context: "User checking token price with $ symbol",
messages: [
{
user: "{{user}}",
content: {
text: "Check price of $eth",
action: "GET_TOKEN_PRICE"
}
}
],
outcome: "GET_TOKEN_PRICE"
},
{
context: "User checking token price with plain symbol",
messages: [
{
user: "{{user}}",
content: {
text: "What's the value for btc",
action: "GET_TOKEN_PRICE"
}
}
],
outcome: "GET_TOKEN_PRICE"
}
];
}

export const tokenPriceEvaluator = new TokenPriceEvaluator();
18 changes: 18 additions & 0 deletions packages/plugin-dexscreener/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Plugin } from "@elizaos/core";
import { TokenPriceAction } from "./actions/tokenAction.ts";
import { TokenPriceEvaluator } from "./evaluators/tokenEvaluator.ts";
import { TokenPriceProvider } from "./providers/tokenProvider.ts";

export * as actions from "./actions";
export * as evaluators from "./evaluators";
export * as providers from "./providers";

export const dexScreenerPlugin: Plugin = {
name: "dexscreener",
description: "Dex Screener Plugin with Token Price Action, Evaluators and Providers",
actions: [
new TokenPriceAction()
],
evaluators: [ new TokenPriceEvaluator() ],
providers: [ new TokenPriceProvider() ]
};
1 change: 1 addition & 0 deletions packages/plugin-dexscreener/src/providers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./tokenProvider.ts";
Loading

0 comments on commit f0eebe1

Please sign in to comment.