-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3045 from edwin-finance/plugin-edwin
feat: Add edwin plugin to eliza
- Loading branch information
Showing
9 changed files
with
320 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# @elizaos/plugin-edwin | ||
|
||
Edwin plugin for Eliza that enables interaction with Edwin tools for DeFi operations. | ||
|
||
## About | ||
|
||
See full info and docs at [Edwin docs](https://docs.edwin.finance). | ||
## Setup | ||
|
||
1. Install dependencies: | ||
|
||
```bash | ||
pnpm install | ||
``` | ||
|
||
2. Configure environment variables for chains you want to support: | ||
|
||
```env | ||
EVM_PRIVATE_KEY=<YOUR_EVM_PRIVATE_KEY> | ||
SOLANA_PRIVATE_KEY=<YOUR_SOLANA_PRIVATE_KEY> | ||
``` | ||
|
||
## Available Tools | ||
|
||
The plugin provides access to the following Edwin tools: | ||
|
||
- supply | ||
- withdraw | ||
- stake | ||
- addLiquidity | ||
- removeLiquidity | ||
|
||
## Usage Examples | ||
|
||
1. Supply on AAVE: | ||
|
||
``` | ||
Supply 100 USDC to AAVE | ||
``` | ||
|
||
2. Add liquidity on Meteora: | ||
|
||
``` | ||
Find a meteora pool with high liquidity and add to td 10 USDC and 0.01 SOL. | ||
``` | ||
|
||
## Development | ||
|
||
1. Build the plugin: | ||
|
||
```bash | ||
pnpm build | ||
``` | ||
|
||
2. Run in development mode: | ||
|
||
```bash | ||
pnpm dev | ||
``` | ||
|
||
## Dependencies | ||
|
||
- edwin-sdk | ||
|
||
## License | ||
|
||
MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"name": "@elizaos/plugin-edwin", | ||
"version": "0.1.0", | ||
"description": "Edwin plugin for elizaos agent", | ||
"main": "dist/index.js", | ||
"type": "module", | ||
"types": "dist/index.d.ts", | ||
"dependencies": { | ||
"@elizaos/core": "workspace:*", | ||
"edwin-sdk": "0.3.4", | ||
"tsup": "8.3.5" | ||
}, | ||
"scripts": { | ||
"build": "tsup --format esm --dts", | ||
"dev": "tsup --format esm --dts --watch" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
import { | ||
type Action, | ||
generateText, | ||
type HandlerCallback, | ||
type IAgentRuntime, | ||
type Memory, | ||
ModelClass, | ||
type State, | ||
composeContext, | ||
generateObjectDeprecated, | ||
} from "@elizaos/core"; | ||
|
||
import { Edwin, EdwinAction } from "edwin-sdk"; | ||
|
||
type GetEdwinActionsParams = { | ||
getClient: () => Promise<Edwin>; | ||
}; | ||
|
||
/** | ||
* Get all edwin actions | ||
*/ | ||
export async function getEdwinActions({ | ||
getClient, | ||
}: GetEdwinActionsParams): Promise<Action[]> { | ||
const edwin = await getClient(); | ||
const edwinActions = await edwin.getActions(); | ||
const actions = edwinActions.map((action: EdwinAction) => ({ | ||
name: action.name.toUpperCase(), | ||
description: action.description, | ||
similes: [], | ||
validate: async () => true, | ||
handler: async ( | ||
runtime: IAgentRuntime, | ||
message: Memory, | ||
state: State | undefined, | ||
options?: Record<string, unknown>, | ||
callback?: HandlerCallback | ||
): Promise<boolean> => { | ||
try { | ||
const client = await getClient(); | ||
if (!state) { | ||
state = (await runtime.composeState(message)) as State; | ||
} else { | ||
state = await runtime.updateRecentMessageState(state); | ||
} | ||
const parameterContext = composeContext({ | ||
state, | ||
template: action.template, | ||
}); | ||
const parameters = await generateObjectDeprecated({ | ||
runtime, | ||
context: parameterContext, | ||
modelClass: ModelClass.LARGE, | ||
}); | ||
const result = await executeAction(action, parameters, client); | ||
const responseContext = composeResponseContext( | ||
action, | ||
result, | ||
state | ||
); | ||
const response = await generateResponse( | ||
runtime, | ||
responseContext | ||
); | ||
callback?.({ text: response, content: result }); | ||
return true; | ||
} catch (error) { | ||
const errorMessage = | ||
error instanceof Error ? error.message : String(error); | ||
callback?.({ | ||
text: `Error executing action ${action.name}: ${errorMessage}`, | ||
content: { error: errorMessage }, | ||
}); | ||
return false; | ||
} | ||
}, | ||
examples: [], | ||
})); | ||
return actions; | ||
} | ||
|
||
async function executeAction( | ||
action: EdwinAction, | ||
parameters: any, | ||
edwin: Edwin | ||
): Promise<unknown> { | ||
const result = await action.execute(parameters); | ||
return result; | ||
} | ||
|
||
function composeResponseContext( | ||
action: EdwinAction, | ||
result: unknown, | ||
state: State | ||
): string { | ||
const responseTemplate = ` | ||
# Action Examples | ||
{{actionExamples}} | ||
# Knowledge | ||
{{knowledge}} | ||
# Task: Generate dialog and actions for the character {{agentName}}. | ||
About {{agentName}}: | ||
{{bio}} | ||
{{lore}} | ||
{{providers}} | ||
{{attachments}} | ||
# Capabilities | ||
Note that {{agentName}} is capable of reading/seeing/hearing various forms of media, including images, videos, audio, plaintext and PDFs. Recent attachments have been included above under the "Attachments" section. | ||
The action "${action.name}" was executed successfully. | ||
Here is the result: | ||
${JSON.stringify(result)} | ||
{{actions}} | ||
Respond to the message knowing that the action was successful and these were the previous messages: | ||
{{recentMessages}} | ||
`; | ||
const context = composeContext({ state, template: responseTemplate }); | ||
return context; | ||
} | ||
|
||
async function generateResponse( | ||
runtime: IAgentRuntime, | ||
context: string | ||
): Promise<string> { | ||
const response = await generateText({ | ||
runtime, | ||
context, | ||
modelClass: ModelClass.LARGE, | ||
}); | ||
return response; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import type { Plugin } from "@elizaos/core"; | ||
import { edwinProvider, getEdwinClient } from "./provider"; | ||
import { getEdwinActions } from "./actions"; | ||
|
||
// Initial banner | ||
console.log("\n┌═════════════════════════════════════┐"); | ||
console.log("│ EDWIN PLUGIN │"); | ||
console.log("│ ,_, │"); | ||
console.log("│ (o,o) │"); | ||
console.log("│ {`\"'} │"); | ||
console.log("│ -\"-\"- │"); | ||
console.log("├─────────────────────────────────────┤"); | ||
console.log("│ Initializing Edwin Plugin... │"); | ||
console.log("│ Version: 0.0.1 │"); | ||
console.log("└═════════════════════════════════════┘"); | ||
|
||
export const edwinPlugin: Plugin = { | ||
name: "[Edwin] Integration", | ||
description: "Edwin integration plugin", | ||
providers: [edwinProvider], | ||
evaluators: [], | ||
services: [], | ||
actions: await getEdwinActions({ | ||
getClient: getEdwinClient, | ||
}), | ||
}; | ||
|
||
export default edwinPlugin; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import type { Provider, IAgentRuntime } from "@elizaos/core"; | ||
import { Edwin } from "edwin-sdk"; | ||
import { EdwinConfig } from "edwin-sdk"; | ||
|
||
// Static variable to hold the singleton instance | ||
let edwinRunningInstance: Edwin | null = null; | ||
|
||
export async function getEdwinClient(): Promise<Edwin> { | ||
// If instance exists, return it | ||
if (edwinRunningInstance) { | ||
return edwinRunningInstance; | ||
} | ||
// Otherwise create new instance | ||
const edwinConfig: EdwinConfig = { | ||
evmPrivateKey: process.env.EVM_PRIVATE_KEY as `0x${string}`, | ||
solanaPrivateKey: process.env.SOLANA_PRIVATE_KEY as string, | ||
actions: ["supply", "withdraw", "stake", "getPools", "addLiquidity"], | ||
}; | ||
|
||
edwinRunningInstance = new Edwin(edwinConfig); | ||
return edwinRunningInstance; | ||
} | ||
|
||
export const edwinProvider: Provider = { | ||
async get(runtime: IAgentRuntime): Promise<string | null> { | ||
try { | ||
const edwin = await getEdwinClient(); | ||
return edwin.getPortfolio(); | ||
} catch (error) { | ||
console.error("Error in Edwin provider:", error); | ||
return null; | ||
} | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"extends": "../core/tsconfig.json", | ||
"compilerOptions": { | ||
"outDir": "dist", | ||
"rootDir": "./src", | ||
"declaration": true | ||
}, | ||
"include": ["src"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { defineConfig } from "tsup"; | ||
|
||
export default defineConfig({ | ||
entry: ["src/index.ts"], | ||
outDir: "dist", | ||
sourcemap: true, | ||
clean: true, | ||
format: ["esm"], // Ensure you're targeting CommonJS | ||
external: [ | ||
"dotenv", // Externalize dotenv to prevent bundling | ||
"fs", // Externalize fs to use Node.js built-in module | ||
"path", // Externalize other built-ins if necessary | ||
"@reflink/reflink", | ||
"@node-llama-cpp", | ||
"https", | ||
"http", | ||
"agentkeepalive", | ||
"viem", | ||
"@lifi/sdk", | ||
], | ||
}); |