@elizaos/agent 0.1.7-alpha.1 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/jest.config.js ADDED
@@ -0,0 +1,17 @@
1
+ /** @type {import('ts-jest').JestConfigWithTsJest} */
2
+ export default {
3
+ preset: "ts-jest",
4
+ testEnvironment: "node",
5
+ extensionsToTreatAsEsm: [".ts"],
6
+ moduleNameMapper: {
7
+ "^(\\.{1,2}/.*)\\.js$": "$1",
8
+ },
9
+ transform: {
10
+ "^.+\\.tsx?$": [
11
+ "ts-jest",
12
+ {
13
+ useESM: true,
14
+ },
15
+ ],
16
+ },
17
+ };
package/package.json CHANGED
@@ -1,62 +1,107 @@
1
1
  {
2
- "name": "@elizaos/agent",
3
- "version": "0.1.7-alpha.1",
4
- "main": "src/index.ts",
5
- "type": "module",
6
- "scripts": {
7
- "start": "node --loader ts-node/esm src/index.ts",
8
- "dev": "node --loader ts-node/esm src/index.ts",
9
- "check-types": "tsc --noEmit"
10
- },
11
- "nodemonConfig": {
12
- "watch": [
13
- "src",
14
- "../core/dist"
15
- ],
16
- "ext": "ts,json",
17
- "exec": "node --enable-source-maps --loader ts-node/esm src/index.ts"
18
- },
19
- "dependencies": {
20
- "@elizaos/adapter-postgres": "workspace:*",
21
- "@elizaos/adapter-redis": "workspace:*",
22
- "@elizaos/adapter-sqlite": "workspace:*",
23
- "@elizaos/client-auto": "workspace:*",
24
- "@elizaos/client-direct": "workspace:*",
25
- "@elizaos/client-discord": "workspace:*",
26
- "@elizaos/client-farcaster": "workspace:*",
27
- "@elizaos/client-lens": "workspace:*",
28
- "@elizaos/client-telegram": "workspace:*",
29
- "@elizaos/client-twitter": "workspace:*",
30
- "@elizaos/client-slack": "workspace:*",
31
- "@elizaos/core": "workspace:*",
32
- "@elizaos/plugin-0g": "workspace:*",
33
- "@elizaos/plugin-aptos": "workspace:*",
34
- "@elizaos/plugin-bootstrap": "workspace:*",
35
- "@elizaos/plugin-intiface": "workspace:*",
36
- "@elizaos/plugin-coinbase": "workspace:*",
37
- "@elizaos/plugin-conflux": "workspace:*",
38
- "@elizaos/plugin-evm": "workspace:*",
39
- "@elizaos/plugin-flow": "workspace:*",
40
- "@elizaos/plugin-story": "workspace:*",
41
- "@elizaos/plugin-goat": "workspace:*",
42
- "@elizaos/plugin-icp": "workspace:*",
43
- "@elizaos/plugin-image-generation": "workspace:*",
44
- "@elizaos/plugin-nft-generation": "workspace:*",
45
- "@elizaos/plugin-node": "workspace:*",
46
- "@elizaos/plugin-solana": "workspace:*",
47
- "@elizaos/plugin-starknet": "workspace:*",
48
- "@elizaos/plugin-ton": "workspace:*",
49
- "@elizaos/plugin-sui": "workspace:*",
50
- "@elizaos/plugin-tee": "workspace:*",
51
- "@elizaos/plugin-multiversx": "workspace:*",
52
- "@elizaos/plugin-near": "workspace:*",
53
- "@elizaos/plugin-zksync-era": "workspace:*",
54
- "readline": "1.3.0",
55
- "ws": "8.18.0",
56
- "yargs": "17.7.2"
57
- },
58
- "devDependencies": {
59
- "ts-node": "10.9.2",
60
- "tsup": "8.3.5"
61
- }
2
+ "name": "@elizaos/agent",
3
+ "version": "0.1.8+build.1",
4
+ "main": "src/index.ts",
5
+ "type": "module",
6
+ "scripts": {
7
+ "start": "node --loader ts-node/esm src/index.ts",
8
+ "dev": "node --loader ts-node/esm src/index.ts",
9
+ "check-types": "tsc --noEmit",
10
+ "test": "jest"
11
+ },
12
+ "nodemonConfig": {
13
+ "watch": [
14
+ "src",
15
+ "../core/dist"
16
+ ],
17
+ "ext": "ts,json",
18
+ "exec": "node --enable-source-maps --loader ts-node/esm src/index.ts"
19
+ },
20
+ "dependencies": {
21
+ "@elizaos/adapter-pglite": "0.1.8+build.1",
22
+ "@elizaos/adapter-postgres": "0.1.8+build.1",
23
+ "@elizaos/adapter-redis": "0.1.8+build.1",
24
+ "@elizaos/adapter-sqlite": "0.1.8+build.1",
25
+ "@elizaos/adapter-supabase": "0.1.8+build.1",
26
+ "@elizaos/client-auto": "0.1.8+build.1",
27
+ "@elizaos/client-direct": "0.1.8+build.1",
28
+ "@elizaos/client-discord": "0.1.8+build.1",
29
+ "@elizaos/client-farcaster": "0.1.8+build.1",
30
+ "@elizaos/client-lens": "0.1.8+build.1",
31
+ "@elizaos/client-slack": "0.1.8+build.1",
32
+ "@elizaos/client-telegram": "0.1.8+build.1",
33
+ "@elizaos/client-twitter": "0.1.8+build.1",
34
+ "@elizaos/core": "0.1.8+build.1",
35
+ "@elizaos/plugin-0g": "0.1.8+build.1",
36
+ "@elizaos/plugin-3d-generation": "0.1.8+build.1",
37
+ "@elizaos/plugin-abstract": "0.1.8+build.1",
38
+ "@elizaos/plugin-akash": "0.1.8+build.1",
39
+ "@elizaos/plugin-allora": "0.1.8+build.1",
40
+ "@elizaos/plugin-aptos": "0.1.8+build.1",
41
+ "@elizaos/plugin-arthera": "0.1.8+build.1",
42
+ "@elizaos/plugin-autonome": "0.1.8+build.1",
43
+ "@elizaos/plugin-avail": "workspace:*",
44
+ "@elizaos/plugin-avalanche": "0.1.8+build.1",
45
+ "@elizaos/plugin-binance": "0.1.8+build.1",
46
+ "@elizaos/plugin-bootstrap": "0.1.8+build.1",
47
+ "@elizaos/plugin-coinbase": "0.1.8+build.1",
48
+ "@elizaos/plugin-coingecko": "0.1.8+build.1",
49
+ "@elizaos/plugin-coinmarketcap": "0.1.8+build.1",
50
+ "@elizaos/plugin-conflux": "0.1.8+build.1",
51
+ "@elizaos/plugin-cosmos": "0.1.8+build.1",
52
+ "@elizaos/plugin-cronoszkevm": "0.1.8+build.1",
53
+ "@elizaos/plugin-depin": "0.1.8+build.1",
54
+ "@elizaos/plugin-echochambers": "0.1.8+build.1",
55
+ "@elizaos/plugin-evm": "0.1.8+build.1",
56
+ "@elizaos/plugin-flow": "0.1.8+build.1",
57
+ "@elizaos/plugin-fuel": "0.1.8+build.1",
58
+ "@elizaos/plugin-genlayer": "0.1.8+build.1",
59
+ "@elizaos/plugin-giphy": "0.1.8+build.1",
60
+ "@elizaos/plugin-gitbook": "0.1.8+build.1",
61
+ "@elizaos/plugin-goat": "0.1.8+build.1",
62
+ "@elizaos/plugin-hyperliquid": "0.1.8+build.1",
63
+ "@elizaos/plugin-icp": "0.1.8+build.1",
64
+ "@elizaos/plugin-image-generation": "0.1.8+build.1",
65
+ "@elizaos/plugin-intiface": "0.1.8+build.1",
66
+ "@elizaos/plugin-lensNetwork": "0.1.8+build.1",
67
+ "@elizaos/plugin-letzai": "0.1.8+build.1",
68
+ "@elizaos/plugin-massa": "0.1.8+build.1",
69
+ "@elizaos/plugin-movement": "0.1.8+build.1",
70
+ "@elizaos/plugin-multiversx": "0.1.8+build.1",
71
+ "@elizaos/plugin-near": "0.1.8+build.1",
72
+ "@elizaos/plugin-nft-generation": "0.1.8+build.1",
73
+ "@elizaos/plugin-node": "0.1.8+build.1",
74
+ "@elizaos/plugin-obsidian": "0.1.8+build.1",
75
+ "@elizaos/plugin-opacity": "0.1.8+build.1",
76
+ "@elizaos/plugin-open-weather": "0.1.8+build.1",
77
+ "@elizaos/plugin-primus": "0.1.8+build.1",
78
+ "@elizaos/plugin-quai": "0.1.8+build.1",
79
+ "@elizaos/plugin-sgx": "0.1.8+build.1",
80
+ "@elizaos/plugin-solana": "0.1.8+build.1",
81
+ "@elizaos/plugin-solana-agentkit": "0.1.8+build.1",
82
+ "@elizaos/plugin-stargaze": "0.1.8+build.1",
83
+ "@elizaos/plugin-starknet": "0.1.8+build.1",
84
+ "@elizaos/plugin-story": "0.1.8+build.1",
85
+ "@elizaos/plugin-sui": "0.1.8+build.1",
86
+ "@elizaos/plugin-tee": "0.1.8+build.1",
87
+ "@elizaos/plugin-tee-log": "0.1.8+build.1",
88
+ "@elizaos/plugin-tee-marlin": "0.1.8+build.1",
89
+ "@elizaos/plugin-thirdweb": "0.1.8+build.1",
90
+ "@elizaos/plugin-ton": "0.1.8+build.1",
91
+ "@elizaos/plugin-twitter": "0.1.8+build.1",
92
+ "@elizaos/plugin-video-generation": "0.1.8+build.1",
93
+ "@elizaos/plugin-web-search": "0.1.8+build.1",
94
+ "@elizaos/plugin-zksync-era": "0.1.8+build.1",
95
+ "readline": "1.3.0",
96
+ "ws": "8.18.0",
97
+ "yargs": "17.7.2"
98
+ },
99
+ "devDependencies": {
100
+ "@types/jest": "^29.5.14",
101
+ "jest": "^29.7.0",
102
+ "ts-jest": "^29.2.5",
103
+ "ts-node": "10.9.2",
104
+ "tsup": "8.3.5"
105
+ },
106
+ "gitHead": "d55c86c961960b4b34528c358eb34b2ff4b34d87"
62
107
  }
package/src/index.ts CHANGED
@@ -1,5 +1,8 @@
1
+ import { PGLiteDatabaseAdapter } from "@elizaos/adapter-pglite";
1
2
  import { PostgresDatabaseAdapter } from "@elizaos/adapter-postgres";
3
+ import { RedisClient } from "@elizaos/adapter-redis";
2
4
  import { SqliteDatabaseAdapter } from "@elizaos/adapter-sqlite";
5
+ import { SupabaseDatabaseAdapter } from "@elizaos/adapter-supabase";
3
6
  import { AutoClientInterface } from "@elizaos/client-auto";
4
7
  import { DiscordClientInterface } from "@elizaos/client-discord";
5
8
  import { FarcasterAgentClient } from "@elizaos/client-farcaster";
@@ -7,10 +10,16 @@ import { LensAgentClient } from "@elizaos/client-lens";
7
10
  import { SlackClientInterface } from "@elizaos/client-slack";
8
11
  import { TelegramClientInterface } from "@elizaos/client-telegram";
9
12
  import { TwitterClientInterface } from "@elizaos/client-twitter";
13
+ // import { ReclaimAdapter } from "@elizaos/plugin-reclaim";
14
+ import { DirectClient } from "@elizaos/client-direct";
15
+ import { PrimusAdapter } from "@elizaos/plugin-primus";
16
+
10
17
  import {
11
18
  AgentRuntime,
12
19
  CacheManager,
20
+ CacheStore,
13
21
  Character,
22
+ Client,
14
23
  Clients,
15
24
  DbCacheAdapter,
16
25
  defaultCharacter,
@@ -24,15 +33,21 @@ import {
24
33
  settings,
25
34
  stringToUuid,
26
35
  validateCharacterConfig,
27
- CacheStore,
28
36
  } from "@elizaos/core";
29
- import { RedisClient } from "@elizaos/adapter-redis";
30
37
  import { zgPlugin } from "@elizaos/plugin-0g";
38
+
31
39
  import { bootstrapPlugin } from "@elizaos/plugin-bootstrap";
32
40
  import createGoatPlugin from "@elizaos/plugin-goat";
33
41
  // import { intifacePlugin } from "@elizaos/plugin-intiface";
34
42
  import { DirectClient } from "@elizaos/client-direct";
43
+ import { ThreeDGenerationPlugin } from "@elizaos/plugin-3d-generation";
44
+ import { abstractPlugin } from "@elizaos/plugin-abstract";
45
+ import { alloraPlugin } from "@elizaos/plugin-allora";
35
46
  import { aptosPlugin } from "@elizaos/plugin-aptos";
47
+ import { artheraPlugin } from "@elizaos/plugin-arthera";
48
+ import { availPlugin } from "@elizaos/plugin-avail";
49
+ import { avalanchePlugin } from "@elizaos/plugin-avalanche";
50
+ import { binancePlugin } from "@elizaos/plugin-binance";
36
51
  import {
37
52
  advancedTradePlugin,
38
53
  coinbaseCommercePlugin,
@@ -41,25 +56,53 @@ import {
41
56
  tradePlugin,
42
57
  webhookPlugin,
43
58
  } from "@elizaos/plugin-coinbase";
59
+ import { coinmarketcapPlugin } from "@elizaos/plugin-coinmarketcap";
60
+ import { coingeckoPlugin } from "@elizaos/plugin-coingecko";
44
61
  import { confluxPlugin } from "@elizaos/plugin-conflux";
62
+ import { createCosmosPlugin } from "@elizaos/plugin-cosmos";
63
+ import { cronosZkEVMPlugin } from "@elizaos/plugin-cronoszkevm";
64
+ import { echoChambersPlugin } from "@elizaos/plugin-echochambers";
45
65
  import { evmPlugin } from "@elizaos/plugin-evm";
46
- import { storyPlugin } from "@elizaos/plugin-story";
47
66
  import { flowPlugin } from "@elizaos/plugin-flow";
67
+ import { fuelPlugin } from "@elizaos/plugin-fuel";
68
+ import { genLayerPlugin } from "@elizaos/plugin-genlayer";
48
69
  import { imageGenerationPlugin } from "@elizaos/plugin-image-generation";
70
+ import { lensPlugin } from "@elizaos/plugin-lensNetwork";
49
71
  import { multiversxPlugin } from "@elizaos/plugin-multiversx";
50
72
  import { nearPlugin } from "@elizaos/plugin-near";
51
73
  import { nftGenerationPlugin } from "@elizaos/plugin-nft-generation";
52
74
  import { createNodePlugin } from "@elizaos/plugin-node";
75
+ import { obsidianPlugin } from "@elizaos/plugin-obsidian";
76
+ import { sgxPlugin } from "@elizaos/plugin-sgx";
53
77
  import { solanaPlugin } from "@elizaos/plugin-solana";
78
+ import { solanaAgentkitPlguin } from "@elizaos/plugin-solana-agentkit";
79
+ import { autonomePlugin } from "@elizaos/plugin-autonome";
80
+ import { storyPlugin } from "@elizaos/plugin-story";
54
81
  import { suiPlugin } from "@elizaos/plugin-sui";
55
82
  import { TEEMode, teePlugin } from "@elizaos/plugin-tee";
83
+ import { teeLogPlugin } from "@elizaos/plugin-tee-log";
84
+ import { teeMarlinPlugin } from "@elizaos/plugin-tee-marlin";
56
85
  import { tonPlugin } from "@elizaos/plugin-ton";
86
+ import { webSearchPlugin } from "@elizaos/plugin-web-search";
87
+
88
+ import { giphyPlugin } from "@elizaos/plugin-giphy";
89
+ import { letzAIPlugin } from "@elizaos/plugin-letzai";
90
+ import { thirdwebPlugin } from "@elizaos/plugin-thirdweb";
91
+ import { hyperliquidPlugin } from "@elizaos/plugin-hyperliquid";
57
92
  import { zksyncEraPlugin } from "@elizaos/plugin-zksync-era";
93
+
94
+ import { OpacityAdapter } from "@elizaos/plugin-opacity";
95
+ import { openWeatherPlugin } from "@elizaos/plugin-open-weather";
96
+ import { stargazePlugin } from "@elizaos/plugin-stargaze";
97
+ import { akashPlugin } from "@elizaos/plugin-akash";
98
+ import { quaiPlugin } from "@elizaos/plugin-quai";
58
99
  import Database from "better-sqlite3";
59
100
  import fs from "fs";
101
+ import net from "net";
60
102
  import path from "path";
61
103
  import { fileURLToPath } from "url";
62
104
  import yargs from "yargs";
105
+ import {dominosPlugin} from "@elizaos/plugin-dominos";
63
106
 
64
107
  const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file
65
108
  const __dirname = path.dirname(__filename); // get the name of the directory
@@ -106,9 +149,60 @@ function tryLoadFile(filePath: string): string | null {
106
149
  return null;
107
150
  }
108
151
  }
109
-
110
- function isAllStrings(arr: unknown[]): boolean {
111
- return Array.isArray(arr) && arr.every((item) => typeof item === "string");
152
+ function mergeCharacters(base: Character, child: Character): Character {
153
+ const mergeObjects = (baseObj: any, childObj: any) => {
154
+ const result: any = {};
155
+ const keys = new Set([...Object.keys(baseObj || {}), ...Object.keys(childObj || {})]);
156
+ keys.forEach(key => {
157
+ if (typeof baseObj[key] === 'object' && typeof childObj[key] === 'object' && !Array.isArray(baseObj[key]) && !Array.isArray(childObj[key])) {
158
+ result[key] = mergeObjects(baseObj[key], childObj[key]);
159
+ } else if (Array.isArray(baseObj[key]) || Array.isArray(childObj[key])) {
160
+ result[key] = [...(baseObj[key] || []), ...(childObj[key] || [])];
161
+ } else {
162
+ result[key] = childObj[key] !== undefined ? childObj[key] : baseObj[key];
163
+ }
164
+ });
165
+ return result;
166
+ };
167
+ return mergeObjects(base, child);
168
+ }
169
+ async function loadCharacter(filePath: string): Promise<Character> {
170
+ const content = tryLoadFile(filePath);
171
+ if (!content) {
172
+ throw new Error(`Character file not found: ${filePath}`);
173
+ }
174
+ let character = JSON.parse(content);
175
+ validateCharacterConfig(character);
176
+
177
+ // .id isn't really valid
178
+ const characterId = character.id || character.name;
179
+ const characterPrefix = `CHARACTER.${characterId.toUpperCase().replace(/ /g, "_")}.`;
180
+ const characterSettings = Object.entries(process.env)
181
+ .filter(([key]) => key.startsWith(characterPrefix))
182
+ .reduce((settings, [key, value]) => {
183
+ const settingKey = key.slice(characterPrefix.length);
184
+ return { ...settings, [settingKey]: value };
185
+ }, {});
186
+ if (Object.keys(characterSettings).length > 0) {
187
+ character.settings = character.settings || {};
188
+ character.settings.secrets = {
189
+ ...characterSettings,
190
+ ...character.settings.secrets,
191
+ };
192
+ }
193
+ // Handle plugins
194
+ character.plugins = await handlePluginImporting(
195
+ character.plugins
196
+ );
197
+ if (character.extends) {
198
+ elizaLogger.info(`Merging ${character.name} character with parent characters`);
199
+ for (const extendPath of character.extends) {
200
+ const baseCharacter = await loadCharacter(path.resolve(path.dirname(filePath), extendPath));
201
+ character = mergeCharacters(baseCharacter, character);
202
+ elizaLogger.info(`Merged ${character.name} with ${baseCharacter.name}`);
203
+ }
204
+ }
205
+ return character;
112
206
  }
113
207
 
114
208
  export async function loadCharacters(
@@ -117,11 +211,11 @@ export async function loadCharacters(
117
211
  let characterPaths = charactersArg
118
212
  ?.split(",")
119
213
  .map((filePath) => filePath.trim());
120
- const loadedCharacters = [];
214
+ const loadedCharacters: Character[] = [];
121
215
 
122
216
  if (characterPaths?.length > 0) {
123
217
  for (const characterPath of characterPaths) {
124
- let content = null;
218
+ let content: string | null = null;
125
219
  let resolvedPath = "";
126
220
 
127
221
  // Try different path resolutions in order
@@ -173,20 +267,7 @@ export async function loadCharacters(
173
267
  }
174
268
 
175
269
  try {
176
- const character = JSON.parse(content);
177
- validateCharacterConfig(character);
178
-
179
- // Handle plugins
180
- if (isAllStrings(character.plugins)) {
181
- elizaLogger.info("Plugins are: ", character.plugins);
182
- const importedPlugins = await Promise.all(
183
- character.plugins.map(async (plugin) => {
184
- const importedPlugin = await import(plugin);
185
- return importedPlugin.default;
186
- })
187
- );
188
- character.plugins = importedPlugins;
189
- }
270
+ const character: Character = await loadCharacter(resolvedPath);
190
271
 
191
272
  loadedCharacters.push(character);
192
273
  elizaLogger.info(
@@ -209,10 +290,40 @@ export async function loadCharacters(
209
290
  return loadedCharacters;
210
291
  }
211
292
 
293
+ async function handlePluginImporting(plugins: string[]) {
294
+ if (plugins.length > 0) {
295
+ elizaLogger.info("Plugins are: ", plugins);
296
+ const importedPlugins = await Promise.all(
297
+ plugins.map(async (plugin) => {
298
+ try {
299
+ const importedPlugin = await import(plugin);
300
+ const functionName =
301
+ plugin
302
+ .replace("@elizaos/plugin-", "")
303
+ .replace(/-./g, (x) => x[1].toUpperCase()) +
304
+ "Plugin"; // Assumes plugin function is camelCased with Plugin suffix
305
+ return (
306
+ importedPlugin.default || importedPlugin[functionName]
307
+ );
308
+ } catch (importError) {
309
+ elizaLogger.error(
310
+ `Failed to import plugin: ${plugin}`,
311
+ importError
312
+ );
313
+ return []; // Return null for failed imports
314
+ }
315
+ })
316
+ );
317
+ return importedPlugins;
318
+ } else {
319
+ return [];
320
+ }
321
+ }
322
+
212
323
  export function getTokenForProvider(
213
324
  provider: ModelProviderName,
214
325
  character: Character
215
- ): string {
326
+ ): string | undefined {
216
327
  switch (provider) {
217
328
  // no key needed for llama_local or gaianet
218
329
  case ModelProviderName.LLAMALOCAL:
@@ -231,6 +342,11 @@ export function getTokenForProvider(
231
342
  character.settings?.secrets?.ETERNALAI_API_KEY ||
232
343
  settings.ETERNALAI_API_KEY
233
344
  );
345
+ case ModelProviderName.NINETEEN_AI:
346
+ return (
347
+ character.settings?.secrets?.NINETEEN_AI_API_KEY ||
348
+ settings.NINETEEN_AI_API_KEY
349
+ );
234
350
  case ModelProviderName.LLAMACLOUD:
235
351
  case ModelProviderName.TOGETHER:
236
352
  return (
@@ -238,8 +354,6 @@ export function getTokenForProvider(
238
354
  settings.LLAMACLOUD_API_KEY ||
239
355
  character.settings?.secrets?.TOGETHER_API_KEY ||
240
356
  settings.TOGETHER_API_KEY ||
241
- character.settings?.secrets?.XAI_API_KEY ||
242
- settings.XAI_API_KEY ||
243
357
  character.settings?.secrets?.OPENAI_API_KEY ||
244
358
  settings.OPENAI_API_KEY
245
359
  );
@@ -320,6 +434,26 @@ export function getTokenForProvider(
320
434
  character.settings?.secrets?.GOOGLE_GENERATIVE_AI_API_KEY ||
321
435
  settings.GOOGLE_GENERATIVE_AI_API_KEY
322
436
  );
437
+ case ModelProviderName.MISTRAL:
438
+ return (
439
+ character.settings?.secrets?.MISTRAL_API_KEY ||
440
+ settings.MISTRAL_API_KEY
441
+ );
442
+ case ModelProviderName.LETZAI:
443
+ return (
444
+ character.settings?.secrets?.LETZAI_API_KEY ||
445
+ settings.LETZAI_API_KEY
446
+ );
447
+ case ModelProviderName.INFERA:
448
+ return (
449
+ character.settings?.secrets?.INFERA_API_KEY ||
450
+ settings.INFERA_API_KEY
451
+ );
452
+ case ModelProviderName.DEEPSEEK:
453
+ return (
454
+ character.settings?.secrets?.DEEPSEEK_API_KEY ||
455
+ settings.DEEPSEEK_API_KEY
456
+ );
323
457
  default:
324
458
  const errorMessage = `Failed to get token - unsupported model provider: ${provider}`;
325
459
  elizaLogger.error(errorMessage);
@@ -328,7 +462,24 @@ export function getTokenForProvider(
328
462
  }
329
463
 
330
464
  function initializeDatabase(dataDir: string) {
331
- if (process.env.POSTGRES_URL) {
465
+ if (process.env.SUPABASE_URL && process.env.SUPABASE_ANON_KEY) {
466
+ elizaLogger.info("Initializing Supabase connection...");
467
+ const db = new SupabaseDatabaseAdapter(
468
+ process.env.SUPABASE_URL,
469
+ process.env.SUPABASE_ANON_KEY
470
+ );
471
+
472
+ // Test the connection
473
+ db.init()
474
+ .then(() => {
475
+ elizaLogger.success("Successfully connected to Supabase database");
476
+ })
477
+ .catch((error) => {
478
+ elizaLogger.error("Failed to connect to Supabase:", error);
479
+ });
480
+
481
+ return db;
482
+ } else if (process.env.POSTGRES_URL) {
332
483
  elizaLogger.info("Initializing PostgreSQL connection...");
333
484
  const db = new PostgresDatabaseAdapter({
334
485
  connectionString: process.env.POSTGRES_URL,
@@ -338,20 +489,34 @@ function initializeDatabase(dataDir: string) {
338
489
  // Test the connection
339
490
  db.init()
340
491
  .then(() => {
341
- elizaLogger.success(
342
- "Successfully connected to PostgreSQL database"
343
- );
492
+ elizaLogger.success("Successfully connected to PostgreSQL database");
344
493
  })
345
494
  .catch((error) => {
346
495
  elizaLogger.error("Failed to connect to PostgreSQL:", error);
347
496
  });
348
497
 
498
+ return db;
499
+ } else if (process.env.PGLITE_DATA_DIR) {
500
+ elizaLogger.info("Initializing PgLite adapter...");
501
+ // `dataDir: memory://` for in memory pg
502
+ const db = new PGLiteDatabaseAdapter({
503
+ dataDir: process.env.PGLITE_DATA_DIR,
504
+ });
349
505
  return db;
350
506
  } else {
351
- const filePath =
352
- process.env.SQLITE_FILE ?? path.resolve(dataDir, "db.sqlite");
353
- // ":memory:";
507
+ const filePath = process.env.SQLITE_FILE ?? path.resolve(dataDir, "db.sqlite");
508
+ elizaLogger.info(`Initializing SQLite database at ${filePath}...`);
354
509
  const db = new SqliteDatabaseAdapter(new Database(filePath));
510
+
511
+ // Test the connection
512
+ db.init()
513
+ .then(() => {
514
+ elizaLogger.success("Successfully connected to SQLite database");
515
+ })
516
+ .catch((error) => {
517
+ elizaLogger.error("Failed to connect to SQLite:", error);
518
+ });
519
+
355
520
  return db;
356
521
  }
357
522
  }
@@ -368,7 +533,8 @@ export async function initializeClients(
368
533
  character.clients?.map((str) => str.toLowerCase()) || [];
369
534
  elizaLogger.log("initializeClients", clientTypes, "for", character.name);
370
535
 
371
- if (clientTypes.includes(Clients.DIRECT)) {
536
+ // Start Auto Client if "auto" detected as a configured client
537
+ if (clientTypes.includes(Clients.AUTO)) {
372
538
  const autoClient = await AutoClientInterface.start(runtime);
373
539
  if (autoClient) clients.auto = autoClient;
374
540
  }
@@ -385,12 +551,8 @@ export async function initializeClients(
385
551
 
386
552
  if (clientTypes.includes(Clients.TWITTER)) {
387
553
  const twitterClient = await TwitterClientInterface.start(runtime);
388
-
389
554
  if (twitterClient) {
390
555
  clients.twitter = twitterClient;
391
- (twitterClient as any).enableSearch = !isFalsish(
392
- getSecret(character, "TWITTER_SEARCH_ENABLE")
393
- );
394
556
  }
395
557
  }
396
558
 
@@ -418,12 +580,32 @@ export async function initializeClients(
418
580
  if (slackClient) clients.slack = slackClient; // Use object property instead of push
419
581
  }
420
582
 
583
+ function determineClientType(client: Client): string {
584
+ // Check if client has a direct type identifier
585
+ if ("type" in client) {
586
+ return (client as any).type;
587
+ }
588
+
589
+ // Check constructor name
590
+ const constructorName = client.constructor?.name;
591
+ if (constructorName && !constructorName.includes("Object")) {
592
+ return constructorName.toLowerCase().replace("client", "");
593
+ }
594
+
595
+ // Fallback: Generate a unique identifier
596
+ return `client_${Date.now()}`;
597
+ }
598
+
421
599
  if (character.plugins?.length > 0) {
422
600
  for (const plugin of character.plugins) {
423
601
  if (plugin.clients) {
424
602
  for (const client of plugin.clients) {
425
603
  const startedClient = await client.start(runtime);
426
- clients[client.name] = startedClient; // Assuming client has a name property
604
+ const clientType = determineClientType(client);
605
+ elizaLogger.debug(
606
+ `Initializing client of type: ${clientType}`
607
+ );
608
+ clients[clientType] = startedClient;
427
609
  }
428
610
  }
429
611
  }
@@ -432,31 +614,6 @@ export async function initializeClients(
432
614
  return clients;
433
615
  }
434
616
 
435
- function isFalsish(input: any): boolean {
436
- // If the input is exactly NaN, return true
437
- if (Number.isNaN(input)) {
438
- return true;
439
- }
440
-
441
- // Convert input to a string if it's not null or undefined
442
- const value = input == null ? "" : String(input);
443
-
444
- // List of common falsish string representations
445
- const falsishValues = [
446
- "false",
447
- "0",
448
- "no",
449
- "n",
450
- "off",
451
- "null",
452
- "undefined",
453
- "",
454
- ];
455
-
456
- // Check if the value (trimmed and lowercased) is in the falsish list
457
- return falsishValues.includes(value.trim().toLowerCase());
458
- }
459
-
460
617
  function getSecret(character: Character, secret: string) {
461
618
  return character.settings?.secrets?.[secret] || process.env[secret];
462
619
  }
@@ -469,11 +626,7 @@ export async function createAgent(
469
626
  cache: ICacheManager,
470
627
  token: string
471
628
  ): Promise<AgentRuntime> {
472
- elizaLogger.success(
473
- elizaLogger.successesTitle,
474
- "Creating runtime for character",
475
- character.name
476
- );
629
+ elizaLogger.log(`Creating runtime for character ${character.name}`);
477
630
 
478
631
  nodePlugin ??= createNodePlugin();
479
632
 
@@ -489,12 +642,64 @@ export async function createAgent(
489
642
  }
490
643
 
491
644
  let goatPlugin: any | undefined;
492
- if (getSecret(character, "ALCHEMY_API_KEY")) {
645
+
646
+ if (getSecret(character, "EVM_PRIVATE_KEY")) {
493
647
  goatPlugin = await createGoatPlugin((secret) =>
494
648
  getSecret(character, secret)
495
649
  );
496
650
  }
497
651
 
652
+ // Initialize Reclaim adapter if environment variables are present
653
+ // let verifiableInferenceAdapter;
654
+ // if (
655
+ // process.env.RECLAIM_APP_ID &&
656
+ // process.env.RECLAIM_APP_SECRET &&
657
+ // process.env.VERIFIABLE_INFERENCE_ENABLED === "true"
658
+ // ) {
659
+ // verifiableInferenceAdapter = new ReclaimAdapter({
660
+ // appId: process.env.RECLAIM_APP_ID,
661
+ // appSecret: process.env.RECLAIM_APP_SECRET,
662
+ // modelProvider: character.modelProvider,
663
+ // token,
664
+ // });
665
+ // elizaLogger.log("Verifiable inference adapter initialized");
666
+ // }
667
+ // Initialize Opacity adapter if environment variables are present
668
+ let verifiableInferenceAdapter;
669
+ if (
670
+ process.env.OPACITY_TEAM_ID &&
671
+ process.env.OPACITY_CLOUDFLARE_NAME &&
672
+ process.env.OPACITY_PROVER_URL &&
673
+ process.env.VERIFIABLE_INFERENCE_ENABLED === "true"
674
+ ) {
675
+ verifiableInferenceAdapter = new OpacityAdapter({
676
+ teamId: process.env.OPACITY_TEAM_ID,
677
+ teamName: process.env.OPACITY_CLOUDFLARE_NAME,
678
+ opacityProverUrl: process.env.OPACITY_PROVER_URL,
679
+ modelProvider: character.modelProvider,
680
+ token: token,
681
+ });
682
+ elizaLogger.log("Verifiable inference adapter initialized");
683
+ elizaLogger.log("teamId", process.env.OPACITY_TEAM_ID);
684
+ elizaLogger.log("teamName", process.env.OPACITY_CLOUDFLARE_NAME);
685
+ elizaLogger.log("opacityProverUrl", process.env.OPACITY_PROVER_URL);
686
+ elizaLogger.log("modelProvider", character.modelProvider);
687
+ elizaLogger.log("token", token);
688
+ }
689
+ if (
690
+ process.env.PRIMUS_APP_ID &&
691
+ process.env.PRIMUS_APP_SECRET &&
692
+ process.env.VERIFIABLE_INFERENCE_ENABLED === "true"){
693
+ verifiableInferenceAdapter = new PrimusAdapter({
694
+ appId: process.env.PRIMUS_APP_ID,
695
+ appSecret: process.env.PRIMUS_APP_SECRET,
696
+ attMode: "proxytls",
697
+ modelProvider: character.modelProvider,
698
+ token,
699
+ });
700
+ elizaLogger.log("Verifiable inference primus adapter initialized");
701
+ }
702
+
498
703
  return new AgentRuntime({
499
704
  databaseAdapter: db,
500
705
  token,
@@ -508,11 +713,16 @@ export async function createAgent(
508
713
  ? confluxPlugin
509
714
  : null,
510
715
  nodePlugin,
716
+ getSecret(character, "TAVILY_API_KEY") ? webSearchPlugin : null,
511
717
  getSecret(character, "SOLANA_PUBLIC_KEY") ||
512
718
  (getSecret(character, "WALLET_PUBLIC_KEY") &&
513
719
  !getSecret(character, "WALLET_PUBLIC_KEY")?.startsWith("0x"))
514
720
  ? solanaPlugin
515
721
  : null,
722
+ getSecret(character, "SOLANA_PRIVATE_KEY")
723
+ ? solanaAgentkitPlguin
724
+ : null,
725
+ getSecret(character, "AUTONOME_JWT_TOKEN") ? autonomePlugin : null,
516
726
  (getSecret(character, "NEAR_ADDRESS") ||
517
727
  getSecret(character, "NEAR_WALLET_PUBLIC_KEY")) &&
518
728
  getSecret(character, "NEAR_WALLET_SECRET_KEY")
@@ -523,6 +733,9 @@ export async function createAgent(
523
733
  getSecret(character, "WALLET_PUBLIC_KEY")?.startsWith("0x"))
524
734
  ? evmPlugin
525
735
  : null,
736
+ getSecret(character, "COSMOS_RECOVERY_PHRASE") &&
737
+ getSecret(character, "COSMOS_AVAILABLE_CHAINS") &&
738
+ createCosmosPlugin(),
526
739
  (getSecret(character, "SOLANA_PUBLIC_KEY") ||
527
740
  (getSecret(character, "WALLET_PUBLIC_KEY") &&
528
741
  !getSecret(character, "WALLET_PUBLIC_KEY")?.startsWith(
@@ -534,15 +747,21 @@ export async function createAgent(
534
747
  ? nftGenerationPlugin
535
748
  : null,
536
749
  getSecret(character, "ZEROG_PRIVATE_KEY") ? zgPlugin : null,
750
+ getSecret(character, "COINMARKETCAP_API_KEY")
751
+ ? coinmarketcapPlugin
752
+ : null,
537
753
  getSecret(character, "COINBASE_COMMERCE_KEY")
538
754
  ? coinbaseCommercePlugin
539
755
  : null,
540
756
  getSecret(character, "FAL_API_KEY") ||
541
757
  getSecret(character, "OPENAI_API_KEY") ||
542
758
  getSecret(character, "VENICE_API_KEY") ||
543
- getSecret(character, "HEURIST_API_KEY")
759
+ getSecret(character, "NINETEEN_AI_API_KEY") ||
760
+ getSecret(character, "HEURIST_API_KEY") ||
761
+ getSecret(character, "LIVEPEER_GATEWAY_URL")
544
762
  ? imageGenerationPlugin
545
763
  : null,
764
+ getSecret(character, "FAL_API_KEY") ? ThreeDGenerationPlugin : null,
546
765
  ...(getSecret(character, "COINBASE_API_KEY") &&
547
766
  getSecret(character, "COINBASE_PRIVATE_KEY")
548
767
  ? [
@@ -552,25 +771,89 @@ export async function createAgent(
552
771
  advancedTradePlugin,
553
772
  ]
554
773
  : []),
555
- ...(teeMode !== TEEMode.OFF && walletSecretSalt
556
- ? [teePlugin, solanaPlugin]
557
- : []),
774
+ ...(teeMode !== TEEMode.OFF && walletSecretSalt ? [teePlugin] : []),
775
+ getSecret(character, "SGX") ? sgxPlugin : null,
776
+ getSecret(character, "ENABLE_TEE_LOG") &&
777
+ ((teeMode !== TEEMode.OFF && walletSecretSalt) ||
778
+ getSecret(character, "SGX"))
779
+ ? teeLogPlugin
780
+ : null,
558
781
  getSecret(character, "COINBASE_API_KEY") &&
559
782
  getSecret(character, "COINBASE_PRIVATE_KEY") &&
560
783
  getSecret(character, "COINBASE_NOTIFICATION_URI")
561
784
  ? webhookPlugin
562
785
  : null,
563
- getSecret(character, "ALCHEMY_API_KEY") ? goatPlugin : null,
786
+ goatPlugin,
787
+ getSecret(character, "COINGECKO_API_KEY") ||
788
+ getSecret(character, "COINGECKO_PRO_API_KEY")
789
+ ? coingeckoPlugin
790
+ : null,
791
+ getSecret(character, "EVM_PROVIDER_URL") ? goatPlugin : null,
792
+ getSecret(character, "ABSTRACT_PRIVATE_KEY")
793
+ ? abstractPlugin
794
+ : null,
795
+ getSecret(character, "BINANCE_API_KEY") &&
796
+ getSecret(character, "BINANCE_SECRET_KEY")
797
+ ? binancePlugin
798
+ : null,
564
799
  getSecret(character, "FLOW_ADDRESS") &&
565
800
  getSecret(character, "FLOW_PRIVATE_KEY")
566
801
  ? flowPlugin
567
802
  : null,
803
+ getSecret(character, "LENS_ADDRESS") &&
804
+ getSecret(character, "LENS_PRIVATE_KEY")
805
+ ? lensPlugin
806
+ : null,
568
807
  getSecret(character, "APTOS_PRIVATE_KEY") ? aptosPlugin : null,
569
808
  getSecret(character, "MVX_PRIVATE_KEY") ? multiversxPlugin : null,
570
809
  getSecret(character, "ZKSYNC_PRIVATE_KEY") ? zksyncEraPlugin : null,
810
+ getSecret(character, "CRONOSZKEVM_PRIVATE_KEY")
811
+ ? cronosZkEVMPlugin
812
+ : null,
813
+ getSecret(character, "TEE_MARLIN") ? teeMarlinPlugin : null,
571
814
  getSecret(character, "TON_PRIVATE_KEY") ? tonPlugin : null,
815
+ getSecret(character, "THIRDWEB_SECRET_KEY") ? thirdwebPlugin : null,
572
816
  getSecret(character, "SUI_PRIVATE_KEY") ? suiPlugin : null,
573
817
  getSecret(character, "STORY_PRIVATE_KEY") ? storyPlugin : null,
818
+ getSecret(character, "FUEL_PRIVATE_KEY") ? fuelPlugin : null,
819
+ getSecret(character, "AVALANCHE_PRIVATE_KEY")
820
+ ? avalanchePlugin
821
+ : null,
822
+ getSecret(character, "ECHOCHAMBERS_API_URL") &&
823
+ getSecret(character, "ECHOCHAMBERS_API_KEY")
824
+ ? echoChambersPlugin
825
+ : null,
826
+ getSecret(character, "LETZAI_API_KEY") ? letzAIPlugin : null,
827
+ getSecret(character, "STARGAZE_ENDPOINT") ? stargazePlugin : null,
828
+ getSecret(character, "GIPHY_API_KEY") ? giphyPlugin : null,
829
+ getSecret(character, "GENLAYER_PRIVATE_KEY")
830
+ ? genLayerPlugin
831
+ : null,
832
+ getSecret(character, "AVAIL_SEED") &&
833
+ getSecret(character, "AVAIL_APP_ID")
834
+ ? availPlugin
835
+ : null,
836
+ getSecret(character, "OPEN_WEATHER_API_KEY")
837
+ ? openWeatherPlugin
838
+ : null,
839
+ getSecret(character, "OBSIDIAN_API_TOKEN") ? obsidianPlugin : null,
840
+ getSecret(character, "ARTHERA_PRIVATE_KEY")?.startsWith("0x")
841
+ ? artheraPlugin
842
+ : null,
843
+ getSecret(character, "ALLORA_API_KEY") ? alloraPlugin : null,
844
+ getSecret(character, "HYPERLIQUID_PRIVATE_KEY")
845
+ ? hyperliquidPlugin
846
+ : null,
847
+ getSecret(character, "HYPERLIQUID_TESTNET")
848
+ ? hyperliquidPlugin
849
+ : null,
850
+ getSecret(character, "AKASH_MNEMONIC") &&
851
+ getSecret(character, "AKASH_WALLET_ADDRESS")
852
+ ? akashPlugin
853
+ : null,
854
+ getSecret(character, "QUAI_PRIVATE_KEY")
855
+ ? quaiPlugin
856
+ : null,
574
857
  ].filter(Boolean),
575
858
  providers: [],
576
859
  actions: [],
@@ -578,10 +861,16 @@ export async function createAgent(
578
861
  managers: [],
579
862
  cacheManager: cache,
580
863
  fetch: logFetch,
864
+ verifiableInferenceAdapter,
581
865
  });
582
866
  }
583
867
 
584
868
  function initializeFsCache(baseDir: string, character: Character) {
869
+ if (!character?.id) {
870
+ throw new Error(
871
+ "initializeFsCache requires id to be set in character definition"
872
+ );
873
+ }
585
874
  const cacheDir = path.resolve(baseDir, character.id, "cache");
586
875
 
587
876
  const cache = new CacheManager(new FsCacheAdapter(cacheDir));
@@ -589,6 +878,11 @@ function initializeFsCache(baseDir: string, character: Character) {
589
878
  }
590
879
 
591
880
  function initializeDbCache(character: Character, db: IDatabaseCacheAdapter) {
881
+ if (!character?.id) {
882
+ throw new Error(
883
+ "initializeFsCache requires id to be set in character definition"
884
+ );
885
+ }
592
886
  const cache = new CacheManager(new DbCacheAdapter(db, character.id));
593
887
  return cache;
594
888
  }
@@ -604,6 +898,11 @@ function initializeCache(
604
898
  if (process.env.REDIS_URL) {
605
899
  elizaLogger.info("Connecting to Redis...");
606
900
  const redisClient = new RedisClient(process.env.REDIS_URL);
901
+ if (!character?.id) {
902
+ throw new Error(
903
+ "CacheStore.REDIS requires id to be set in character definition"
904
+ );
905
+ }
607
906
  return new CacheManager(
608
907
  new DbCacheAdapter(redisClient, character.id) // Using DbCacheAdapter since RedisClient also implements IDatabaseCacheAdapter
609
908
  );
@@ -623,6 +922,11 @@ function initializeCache(
623
922
 
624
923
  case CacheStore.FILESYSTEM:
625
924
  elizaLogger.info("Using File System Cache...");
925
+ if (!baseDir) {
926
+ throw new Error(
927
+ "baseDir must be provided for CacheStore.FILESYSTEM."
928
+ );
929
+ }
626
930
  return initializeFsCache(baseDir, character);
627
931
 
628
932
  default:
@@ -692,13 +996,30 @@ async function startAgent(
692
996
  }
693
997
  }
694
998
 
999
+ const checkPortAvailable = (port: number): Promise<boolean> => {
1000
+ return new Promise((resolve) => {
1001
+ const server = net.createServer();
1002
+
1003
+ server.once("error", (err: NodeJS.ErrnoException) => {
1004
+ if (err.code === "EADDRINUSE") {
1005
+ resolve(false);
1006
+ }
1007
+ });
1008
+
1009
+ server.once("listening", () => {
1010
+ server.close();
1011
+ resolve(true);
1012
+ });
1013
+
1014
+ server.listen(port);
1015
+ });
1016
+ };
1017
+
695
1018
  const startAgents = async () => {
696
1019
  const directClient = new DirectClient();
697
- const serverPort = parseInt(settings.SERVER_PORT || "3000");
1020
+ let serverPort = parseInt(settings.SERVER_PORT || "3000");
698
1021
  const args = parseArguments();
699
-
700
1022
  let charactersArg = args.characters || args.character;
701
-
702
1023
  let characters = [defaultCharacter];
703
1024
 
704
1025
  if (charactersArg) {
@@ -713,19 +1034,35 @@ const startAgents = async () => {
713
1034
  elizaLogger.error("Error starting agents:", error);
714
1035
  }
715
1036
 
1037
+ // Find available port
1038
+ while (!(await checkPortAvailable(serverPort))) {
1039
+ elizaLogger.warn(
1040
+ `Port ${serverPort} is in use, trying ${serverPort + 1}`
1041
+ );
1042
+ serverPort++;
1043
+ }
1044
+
716
1045
  // upload some agent functionality into directClient
717
- directClient.startAgent = async (character: Character) => {
1046
+ directClient.startAgent = async (character) => {
1047
+ // Handle plugins
1048
+ character.plugins = await handlePluginImporting(character.plugins);
1049
+
718
1050
  // wrap it so we don't have to inject directClient later
719
1051
  return startAgent(character, directClient);
720
1052
  };
1053
+
721
1054
  directClient.start(serverPort);
722
1055
 
1056
+ if (serverPort !== parseInt(settings.SERVER_PORT || "3000")) {
1057
+ elizaLogger.log(`Server started on alternate port ${serverPort}`);
1058
+ }
1059
+
723
1060
  elizaLogger.log(
724
- "Run `pnpm start:client` to start the client and visit the outputted URL (http://localhost:5173) to chat with your agents"
1061
+ "Run `pnpm start:client` to start the client and visit the outputted URL (http://localhost:5173) to chat with your agents. When running multiple agents, use client with different port `SERVER_PORT=3001 pnpm start:client`"
725
1062
  );
726
1063
  };
727
1064
 
728
1065
  startAgents().catch((error) => {
729
1066
  elizaLogger.error("Unhandled error in startAgents:", error);
730
- process.exit(1); // Exit the process after logging
1067
+ process.exit(1);
731
1068
  });
package/tsconfig.json CHANGED
@@ -5,16 +5,12 @@
5
5
  "rootDir": ".",
6
6
  "module": "ESNext",
7
7
  "moduleResolution": "Bundler",
8
- "types": [
9
- "node"
10
- ]
8
+ "types": ["node", "jest"]
11
9
  },
12
10
  "ts-node": {
13
11
  "experimentalSpecifierResolution": "node",
14
12
  "transpileOnly": true,
15
- "esm": true,
13
+ "esm": true
16
14
  },
17
- "include": [
18
- "src"
19
- ]
20
- }
15
+ "include": ["src"]
16
+ }