Skip to content

Commit f982242

Browse files
authored
Merge branch 'main' into 415-add-0g-plugin
2 parents 2ab3c88 + 5b920ec commit f982242

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+3523
-1448
lines changed

.env.example

+46-45
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
# Required environment variables
1+
# Discord Configuration
22
DISCORD_APPLICATION_ID=
3-
DISCORD_API_TOKEN= # Bot token
4-
OPENAI_API_KEY=sk-* # OpenAI API key, starting with sk-
5-
REDPILL_API_KEY= # REDPILL API Key
6-
GROK_API_KEY= # GROK API Key
7-
GROQ_API_KEY=gsk_*
3+
DISCORD_API_TOKEN= # Bot token
4+
5+
# AI Model API Keys
6+
OPENAI_API_KEY= # OpenAI API key, starting with sk-
7+
REDPILL_API_KEY= # REDPILL API Key
8+
GROK_API_KEY= # GROK API Key
9+
GROQ_API_KEY= # Starts with gsk_
810
OPENROUTER_API_KEY=
9-
GOOGLE_GENERATIVE_AI_API_KEY= # Gemini API key
11+
GOOGLE_GENERATIVE_AI_API_KEY= # Gemini API key
1012

11-
ELEVENLABS_XI_API_KEY= # API key from elevenlabs
13+
# Speech Synthesis
14+
ELEVENLABS_XI_API_KEY= # API key from elevenlabs
1215

13-
# ELEVENLABS SETTINGS
16+
# ElevenLabs Settings
1417
ELEVENLABS_MODEL_ID=eleven_multilingual_v2
1518
ELEVENLABS_VOICE_ID=21m00Tcm4TlvDq8ikWAM
1619
ELEVENLABS_VOICE_STABILITY=0.5
@@ -20,78 +23,76 @@ ELEVENLABS_VOICE_USE_SPEAKER_BOOST=false
2023
ELEVENLABS_OPTIMIZE_STREAMING_LATENCY=4
2124
ELEVENLABS_OUTPUT_FORMAT=pcm_16000
2225

26+
# Twitter/X Configuration
2327
TWITTER_DRY_RUN=false
24-
TWITTER_USERNAME= # Account username
25-
TWITTER_PASSWORD= # Account password
26-
TWITTER_EMAIL= # Account email
27-
TWITTER_COOKIES= # Account cookies
28-
28+
TWITTER_USERNAME= # Account username
29+
TWITTER_PASSWORD= # Account password
30+
TWITTER_EMAIL= # Account email
31+
TWITTER_COOKIES= # Account cookies
2932
X_SERVER_URL=
3033
XAI_API_KEY=
3134
XAI_MODEL=
3235

33-
#POST INTERVAL RANDOM MIN-MAX MINUTES
34-
POST_INTERVAL_MIN= #90 #Default
35-
POST_INTERVAL_MAX= #180 #Default
36-
37-
38-
#USE IMAGE GEN
39-
IMAGE_GEN= #TRUE
36+
# Post Interval Settings (in minutes)
37+
POST_INTERVAL_MIN= # Default: 90
38+
POST_INTERVAL_MAX= # Default: 180
4039

41-
#Leave blank to use local embeddings
42-
USE_OPENAI_EMBEDDING= #TRUE
40+
# Feature Flags
41+
IMAGE_GEN= # Set to TRUE to enable image generation
42+
USE_OPENAI_EMBEDDING= # Set to TRUE for OpenAI, leave blank for local
4343

44-
#OpenRouter (Use one model for everything or set individual for small, medium, large tasks)
45-
#leave blank to use defaults hermes 70b for small tasks & 405b for medium/large tasks
46-
OPENROUTER_MODEL=
44+
# OpenRouter Models
45+
OPENROUTER_MODEL= # Default: uses hermes 70b/405b
4746
SMALL_OPENROUTER_MODEL=
48-
MEDIUM_OLLAMA_MODEL=
49-
LARGE_OLLAMA_MODEL=
47+
MEDIUM_OPENROUTER_MODEL=
48+
LARGE_OPENROUTER_MODEL=
5049

51-
52-
#Set to Use for New OLLAMA provider
53-
OLLAMA_SERVER_URL= #Leave blank for default localhost:11434
50+
# Ollama Configuration
51+
OLLAMA_SERVER_URL= # Default: localhost:11434
5452
OLLAMA_MODEL=
55-
OLLAMA_EMBEDDING_MODEL= #default mxbai-embed-large
56-
#To use custom model types for different tasks set these
57-
SMALL_OLLAMA_MODEL= #default llama3.2
58-
MEDIUM_OLLAMA_MODEL= #default herems3
59-
LARGE_OLLAMA_MODEL= #default hermes3:70b
53+
OLLAMA_EMBEDDING_MODEL= # Default: mxbai-embed-large
54+
SMALL_OLLAMA_MODEL= # Default: llama3.2
55+
MEDIUM_OLLAMA_MODEL= # Default: hermes3
56+
LARGE_OLLAMA_MODEL= # Default: hermes3:70b
6057

61-
# For asking Claude stuff
62-
ANTHROPIC_API_KEY=
58+
# API Keys
59+
ANTHROPIC_API_KEY= # For Claude
60+
HEURIST_API_KEY= # Get from https://heurist.ai/dev-access
6361

64-
# Heurist API (Get API Key at https://heurist.ai/dev-access)
65-
HEURIST_API_KEY=
62+
# Heurist Models
6663
SMALL_HEURIST_LANGUAGE_MODEL=
6764
MEDIUM_HEURIST_LANGUAGE_MODEL=
6865
LARGE_HEURIST_LANGUAGE_MODEL=
6966
HEURIST_IMAGE_MODEL=
7067

68+
# Wallet Configuration
7169
WALLET_PRIVATE_KEY=EXAMPLE_WALLET_PRIVATE_KEY
7270
WALLET_PUBLIC_KEY=EXAMPLE_WALLET_PUBLIC_KEY
73-
7471
BIRDEYE_API_KEY=
7572

73+
# Solana Configuration
7674
SOL_ADDRESS=So11111111111111111111111111111111111111112
7775
SLIPPAGE=1
7876
BASE_MINT=So11111111111111111111111111111111111111112
7977
RPC_URL=https://api.mainnet-beta.solana.com
8078
HELIUS_API_KEY=
8179

82-
83-
## Telegram
80+
# Telegram Configuration
8481
TELEGRAM_BOT_TOKEN=
8582

83+
# Together Configuration
8684
TOGETHER_API_KEY=
85+
86+
# Server Configuration
8787
SERVER_PORT=3000
8888

89-
# Starknet
89+
# Starknet Configuration
9090
STARKNET_ADDRESS=
9191
STARKNET_PRIVATE_KEY=
92+
STARKNET_RPC_URL=
9293

9394
#ZeroG
9495
ZEROG_INDEXER_RPC=
9596
ZEROG_EVM_RPC=
9697
ZEROG_PRIVATE_KEY=
97-
ZEROG_FLOW_ADDRESS=
98+
ZEROG_FLOW_ADDRESS=

.github/pull_request_template.md

+6
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,9 @@ None, automtated tests are fine.
7777
<!--
7878
## Deployment instructions
7979
-->
80+
81+
<!-- If you are on Discord, please join https://discord.gg/ai16z and state your Discord username here for contribute role and join us in #development-feed -->
82+
<!--
83+
## Discord username
84+
85+
-->

.github/workflows/release.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ jobs:
6161
- name: Create GitHub Release
6262
uses: actions/create-release@v1
6363
env:
64-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
64+
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
6565
PNPM_HOME: /home/runner/setup-pnpm/node_modules/.bin
6666
with:
6767
tag_name: ${{ steps.get_tag.outputs.TAG }}

agent/.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
!character.ts
44
.env
55
*.env
6-
.env*
6+
.env*
7+
/data

agent/src/index.ts

+76-24
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,21 @@ import { AutoClientInterface } from "@ai16z/client-auto";
66
import { TelegramClientInterface } from "@ai16z/client-telegram";
77
import { TwitterClientInterface } from "@ai16z/client-twitter";
88
import {
9+
DbCacheAdapter,
910
defaultCharacter,
11+
FsCacheAdapter,
12+
ICacheManager,
13+
IDatabaseCacheAdapter,
14+
stringToUuid,
1015
AgentRuntime,
11-
settings,
16+
CacheManager,
1217
Character,
1318
IAgentRuntime,
1419
ModelProviderName,
1520
elizaLogger,
21+
settings,
22+
IDatabaseAdapter,
23+
validateCharacterConfig,
1624
} from "@ai16z/eliza";
1725
import { bootstrapPlugin } from "@ai16z/plugin-bootstrap";
1826
import { solanaPlugin } from "@ai16z/plugin-solana";
@@ -22,7 +30,13 @@ import Database from "better-sqlite3";
2230
import fs from "fs";
2331
import readline from "readline";
2432
import yargs from "yargs";
33+
import path from "path";
34+
import { fileURLToPath } from "url";
2535
import { character } from "./character.ts";
36+
import type { DirectClient } from "@ai16z/client-direct";
37+
38+
const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file
39+
const __dirname = path.dirname(__filename); // get the name of the directory
2640

2741
export const wait = (minTime: number = 1000, maxTime: number = 3000) => {
2842
const waitTime =
@@ -55,21 +69,22 @@ export function parseArguments(): {
5569
export async function loadCharacters(
5670
charactersArg: string
5771
): Promise<Character[]> {
58-
let characterPaths = charactersArg
59-
?.split(",")
60-
.map((path) => path.trim())
61-
.map((path) => {
62-
if (path[0] === "/") return path; // handle absolute paths
63-
// assume relative to the project root where pnpm is ran
64-
return `../${path}`;
65-
});
72+
let characterPaths = charactersArg?.split(",").map((filePath) => {
73+
if (path.basename(filePath) === filePath) {
74+
filePath = "../characters/" + filePath;
75+
}
76+
return path.resolve(process.cwd(), filePath.trim());
77+
});
78+
6679
const loadedCharacters = [];
6780

6881
if (characterPaths?.length > 0) {
6982
for (const path of characterPaths) {
7083
try {
7184
const character = JSON.parse(fs.readFileSync(path, "utf8"));
7285

86+
validateCharacterConfig(character);
87+
7388
// is there a "plugins" field?
7489
if (character.plugins) {
7590
console.log("Plugins are: ", character.plugins);
@@ -159,13 +174,18 @@ export function getTokenForProvider(
159174
}
160175
}
161176

162-
function initializeDatabase() {
177+
function initializeDatabase(dataDir: string) {
163178
if (process.env.POSTGRES_URL) {
164-
return new PostgresDatabaseAdapter({
179+
const db = new PostgresDatabaseAdapter({
165180
connectionString: process.env.POSTGRES_URL,
166181
});
182+
return db;
167183
} else {
168-
return new SqliteDatabaseAdapter(new Database("./db.sqlite"));
184+
const filePath =
185+
process.env.SQLITE_FILE ?? path.resolve(dataDir, "db.sqlite");
186+
// ":memory:";
187+
const db = new SqliteDatabaseAdapter(new Database(filePath));
188+
return db;
169189
}
170190
}
171191

@@ -209,9 +229,10 @@ export async function initializeClients(
209229
return clients;
210230
}
211231

212-
export async function createAgent(
232+
export function createAgent(
213233
character: Character,
214-
db: any,
234+
db: IDatabaseAdapter,
235+
cache: ICacheManager,
215236
token: string
216237
) {
217238
elizaLogger.success(
@@ -235,29 +256,54 @@ export async function createAgent(
235256
actions: [],
236257
services: [],
237258
managers: [],
259+
cacheManager: cache,
238260
});
239261
}
240262

241-
async function startAgent(character: Character, directClient: any) {
263+
function intializeFsCache(baseDir: string, character: Character) {
264+
const cacheDir = path.resolve(baseDir, character.id, "cache");
265+
266+
const cache = new CacheManager(new FsCacheAdapter(cacheDir));
267+
return cache;
268+
}
269+
270+
function intializeDbCache(character: Character, db: IDatabaseCacheAdapter) {
271+
const cache = new CacheManager(new DbCacheAdapter(db, character.id));
272+
return cache;
273+
}
274+
275+
async function startAgent(character: Character, directClient: DirectClient) {
242276
try {
277+
character.id ??= stringToUuid(character.name);
278+
character.username ??= character.name;
279+
243280
const token = getTokenForProvider(character.modelProvider, character);
244-
const db = initializeDatabase();
281+
const dataDir = path.join(__dirname, "../data");
245282

246-
const runtime = await createAgent(character, db, token);
283+
if (!fs.existsSync(dataDir)) {
284+
fs.mkdirSync(dataDir, { recursive: true });
285+
}
247286

248-
const clients = await initializeClients(
249-
character,
250-
runtime as IAgentRuntime
251-
);
287+
const db = initializeDatabase(dataDir);
288+
289+
await db.init();
252290

253-
directClient.registerAgent(await runtime);
291+
const cache = intializeDbCache(character, db);
292+
const runtime = createAgent(character, db, cache, token);
293+
294+
await runtime.initialize();
295+
296+
const clients = await initializeClients(character, runtime);
297+
298+
directClient.registerAgent(runtime);
254299

255300
return clients;
256301
} catch (error) {
257-
console.error(
302+
elizaLogger.error(
258303
`Error starting agent for character ${character.name}:`,
259304
error
260305
);
306+
console.error(error);
261307
throw error;
262308
}
263309
}
@@ -276,7 +322,7 @@ const startAgents = async () => {
276322

277323
try {
278324
for (const character of characters) {
279-
await startAgent(character, directClient);
325+
await startAgent(character, directClient as DirectClient);
280326
}
281327
} catch (error) {
282328
elizaLogger.error("Error starting agents:", error);
@@ -306,9 +352,15 @@ const rl = readline.createInterface({
306352
output: process.stdout,
307353
});
308354

355+
rl.on("SIGINT", () => {
356+
rl.close();
357+
process.exit(0);
358+
});
359+
309360
async function handleUserInput(input, agentId) {
310361
if (input.toLowerCase() === "exit") {
311362
rl.close();
363+
process.exit(0);
312364
return;
313365
}
314366

0 commit comments

Comments
 (0)