Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/router-protocol/eliza in…
Browse files Browse the repository at this point in the history
…to nitro_plugin
  • Loading branch information
RaveenaBhasin committed Jan 21, 2025
2 parents cb71a7e + 80dbb30 commit e4b462d
Show file tree
Hide file tree
Showing 86 changed files with 6,401 additions and 1,657 deletions.
11 changes: 10 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ SUPABASE_ANON_KEY=
# Comma separated list of remote character urls (optional)
REMOTE_CHARACTER_URLS=

# Stores characters set by using the direct API in the data/character folder for further load when the app restarts
USE_CHARACTER_STORAGE=false

# Logging
DEFAULT_LOG_LEVEL=warn
LOG_JSON_FORMAT=false # Print everything in logger as json; false by default
Expand All @@ -31,6 +34,9 @@ DISCORD_APPLICATION_ID=
DISCORD_API_TOKEN= # Bot token
DISCORD_VOICE_CHANNEL_ID= # The ID of the voice channel the bot should join (optional)

# Devin Configuration
DEVIN_API_TOKEN= # Get your API key from docs.devin.ai/tutorials/api-integration

# Farcaster Neynar Configuration
FARCASTER_FID= # The FID associated with the account your are sending casts from
FARCASTER_NEYNAR_API_KEY= # Neynar API key: https://neynar.com/
Expand Down Expand Up @@ -89,7 +95,7 @@ MEDIUM_OPENAI_MODEL= # Default: gpt-4o
LARGE_OPENAI_MODEL= # Default: gpt-4o
EMBEDDING_OPENAI_MODEL= # Default: text-embedding-3-small
IMAGE_OPENAI_MODEL= # Default: dall-e-3
USE_OPENAI_EMBEDDING= # Set to TRUE for OpenAI/1536, leave blank for local
USE_OPENAI_EMBEDDING=TRUE # Set to TRUE for OpenAI/1536, leave blank for local

# Community Plugin for OpenAI Configuration
ENABLE_OPEN_AI_COMMUNITY_PLUGIN=false
Expand Down Expand Up @@ -488,6 +494,9 @@ NEAR_NETWORK=testnet # or mainnet
ZKSYNC_ADDRESS=
ZKSYNC_PRIVATE_KEY=

# HoldStation Wallet Configuration
HOLDSTATION_PRIVATE_KEY=

# Avail DA Configuration
AVAIL_ADDRESS=
AVAIL_SEED=
Expand Down
36 changes: 20 additions & 16 deletions .github/workflows/integrationTests.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
name: Integration Tests
on:
push:
branches:
- "*"
branches: ["*"]
pull_request:
branches:
- "*"
branches: ["*"]

jobs:
integration-tests:
Expand All @@ -15,20 +13,27 @@ jobs:
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v3
- name: Setup Node.js
uses: actions/setup-node@v4
with:
version: 9.15.0
node-version: '23.3'

- uses: actions/setup-node@v4
- name: Cache pnpm
uses: actions/cache@v4
with:
node-version: "23.3.0"
cache: "pnpm"

- name: Clean up
run: pnpm clean

path: |
~/.pnpm-store
**/node_modules
key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: ${{ runner.os }}-pnpm-

- name: Setup pnpm
uses: pnpm/action-setup@v3
with:
version: 9.15.0

- name: Install dependencies
run: pnpm install -r --no-frozen-lockfile
run: pnpm install --no-frozen-lockfile

- name: Build packages
run: pnpm build
Expand All @@ -37,5 +42,4 @@ jobs:
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
COINBASE_COMMERCE_KEY: ${{ secrets.COINBASE_COMMERCE_KEY }}
run: |
pnpm run integrationTests
run: pnpm run integrationTests
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ concatenated-output.ts
embedding-cache.json
packages/plugin-buttplug/intiface-engine

node-compile-cache

.idea
.DS_Store

Expand Down
3 changes: 3 additions & 0 deletions agent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,13 @@
"@elizaos/plugin-hyperliquid": "workspace:*",
"@elizaos/plugin-akash": "workspace:*",
"@elizaos/plugin-quai": "workspace:*",
"@elizaos/plugin-lightning": "workspace:*",
"@elizaos/plugin-b2": "workspace:*",
"@elizaos/plugin-nft-collections": "workspace:*",
"@elizaos/plugin-pyth-data": "workspace:*",
"@elizaos/plugin-openai": "workspace:*",
"@elizaos/plugin-devin": "workspace:*",
"@elizaos/plugin-holdstation": "workspace:*",
"@elizaos/plugin-router-nitro": "workspace:*",
"readline": "1.3.0",
"ws": "8.18.0",
Expand Down
59 changes: 51 additions & 8 deletions agent/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import { DirectClient } from "@elizaos/client-direct";
import { agentKitPlugin } from "@elizaos/plugin-agentkit";
// import { ReclaimAdapter } from "@elizaos/plugin-reclaim";
import { PrimusAdapter } from "@elizaos/plugin-primus";
import { lightningPlugin } from "@elizaos/plugin-lightning";
import { elizaCodeinPlugin, onchainJson } from "@elizaos/plugin-iq6900";
import { holdstationPlugin } from "@elizaos/plugin-holdstation";

import {
AgentRuntime,
Expand Down Expand Up @@ -106,8 +108,10 @@ import { hyperliquidPlugin } from "@elizaos/plugin-hyperliquid";
import { echoChambersPlugin } from "@elizaos/plugin-echochambers";
import { dexScreenerPlugin } from "@elizaos/plugin-dexscreener";
import { pythDataPlugin } from "@elizaos/plugin-pyth-data";

import { openaiPlugin } from '@elizaos/plugin-openai';
import nitroPlugin from "@elizaos/plugin-router-nitro";
import { devinPlugin } from '@elizaos/plugin-devin';


import { zksyncEraPlugin } from "@elizaos/plugin-zksync-era";
Expand Down Expand Up @@ -210,7 +214,9 @@ export async function loadCharacterFromOnchain(): Promise<Character[]> {

// .id isn't really valid
const characterId = character.id || character.name;
const characterPrefix = `CHARACTER.${characterId.toUpperCase().replace(/ /g, "_")}.`;
const characterPrefix = `CHARACTER.${characterId
.toUpperCase()
.replace(/ /g, "_")}.`;

const characterSettings = Object.entries(process.env)
.filter(([key]) => key.startsWith(characterPrefix))
Expand Down Expand Up @@ -282,7 +288,9 @@ async function jsonToCharacter(

// .id isn't really valid
const characterId = character.id || character.name;
const characterPrefix = `CHARACTER.${characterId.toUpperCase().replace(/ /g, "_")}.`;
const characterPrefix = `CHARACTER.${characterId
.toUpperCase()
.replace(/ /g, "_")}.`;
const characterSettings = Object.entries(process.env)
.filter(([key]) => key.startsWith(characterPrefix))
.reduce((settings, [key, value]) => {
Expand Down Expand Up @@ -383,17 +391,39 @@ function commaSeparatedStringToArray(commaSeparated: string): string[] {
return commaSeparated?.split(",").map((value) => value.trim());
}

async function readCharactersFromStorage(characterPaths: string[]): Promise<string[]> {
try {
const uploadDir = path.join(process.cwd(), "data", "characters");
await fs.promises.mkdir(uploadDir, { recursive: true });
const fileNames = await fs.promises.readdir(uploadDir);
fileNames.forEach(fileName => {
characterPaths.push(path.join(uploadDir, fileName));
});
} catch (err) {
elizaLogger.error(`Error reading directory: ${err.message}`);
}

return characterPaths;
};

export async function loadCharacters(
charactersArg: string
): Promise<Character[]> {
const characterPaths = commaSeparatedStringToArray(charactersArg);

let characterPaths = commaSeparatedStringToArray(charactersArg);

if(process.env.USE_CHARACTER_STORAGE === "true") {
characterPaths = await readCharactersFromStorage(characterPaths);
}

const loadedCharacters: Character[] = [];

if (characterPaths?.length > 0) {
for (const characterPath of characterPaths) {
try {
const character: Character =
await loadCharacterTryPath(characterPath);
const character: Character = await loadCharacterTryPath(
characterPath
);
loadedCharacters.push(character);
} catch (e) {
process.exit(1);
Expand Down Expand Up @@ -1052,9 +1082,21 @@ export async function createAgent(
getSecret(character, "PYTH_MAINNET_PROGRAM_KEY")
? pythDataPlugin
: null,
getSecret(character, "OPENAI_API_KEY") && getSecret(character, "ENABLE_OPEN_AI_COMMUNITY_PLUGIN")
getSecret(character, "LND_TLS_CERT") &&
getSecret(character, "LND_MACAROON") &&
getSecret(character, "LND_SOCKET")
? lightningPlugin
: null,
getSecret(character, "OPENAI_API_KEY") &&
getSecret(character, "ENABLE_OPEN_AI_COMMUNITY_PLUGIN")
? openaiPlugin
: null,
getSecret(character, "DEVIN_API_TOKEN")
? devinPlugin
: null,
getSecret(character, "HOLDSTATION_PRIVATE_KEY")
? holdstationPlugin
: null,
].filter(Boolean),
providers: [],
actions: [],
Expand Down Expand Up @@ -1232,7 +1274,9 @@ const startAgents = async () => {
characters = await loadCharacterFromOnchain();
}

if ((!onchainJson && charactersArg) || hasValidRemoteUrls()) {
const notOnchainJson = !onchainJson || onchainJson == "null";

if ((notOnchainJson && charactersArg) || hasValidRemoteUrls()) {
characters = await loadCharacters(charactersArg);
}

Expand Down Expand Up @@ -1298,4 +1342,3 @@ if (
console.error("unhandledRejection", err);
});
}

48 changes: 46 additions & 2 deletions packages/client-direct/src/api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import express from "express";
import bodyParser from "body-parser";
import cors from "cors";
import path from "path";
import fs from "fs";

import {
type AgentRuntime,
Expand Down Expand Up @@ -80,6 +82,16 @@ export function createApiRouter(
res.json({ agents: agentsList });
});

router.get('/storage', async (req, res) => {
try {
const uploadDir = path.join(process.cwd(), "data", "characters");
const files = await fs.promises.readdir(uploadDir);
res.json({ files });
} catch (error) {
res.status(500).json({ error: error.message });
}
});

router.get("/agents/:agentId", (req, res) => {
const { agentId } = validateUUIDParams(req.params, res) ?? {
agentId: null,
Expand Down Expand Up @@ -127,7 +139,7 @@ export function createApiRouter(
};
if (!agentId) return;

const agent: AgentRuntime = agents.get(agentId);
let agent: AgentRuntime = agents.get(agentId);

// update character
if (agent) {
Expand All @@ -137,6 +149,9 @@ export function createApiRouter(
// if it has a different name, the agentId will change
}

// stores the json data before it is modified with added data
const characterJson = { ...req.body };

// load character from body
const character = req.body;
try {
Expand All @@ -152,7 +167,7 @@ export function createApiRouter(

// start it up (and register it)
try {
await directClient.startAgent(character);
agent = await directClient.startAgent(character);
elizaLogger.log(`${character.name} started`);
} catch (e) {
elizaLogger.error(`Error starting agent: ${e}`);
Expand All @@ -162,6 +177,35 @@ export function createApiRouter(
});
return;
}

if (process.env.USE_CHARACTER_STORAGE === "true") {
try {
const filename = `${agent.agentId}.json`;
const uploadDir = path.join(
process.cwd(),
"data",
"characters"
);
const filepath = path.join(uploadDir, filename);
await fs.promises.mkdir(uploadDir, { recursive: true });
await fs.promises.writeFile(
filepath,
JSON.stringify(
{ ...characterJson, id: agent.agentId },
null,
2
)
);
elizaLogger.info(
`Character stored successfully at ${filepath}`
);
} catch (error) {
elizaLogger.error(
`Failed to store character: ${error.message}`
);
}
}

res.json({
id: character.id,
character: character,
Expand Down
Loading

0 comments on commit e4b462d

Please sign in to comment.