Skip to content

Commit a1515d8

Browse files
authored
Merge pull request #1295 from ai16z/feat/agent_redis_support
feat: Add caching support for Redis
2 parents ddb7684 + 20b4c74 commit a1515d8

File tree

5 files changed

+125
-66
lines changed

5 files changed

+125
-66
lines changed

.env.example

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# Cache Configs
2+
CACHE_STORE=database # Defaults to database. Other available cache store: redis and filesystem
3+
REDIS_URL= # Redis URL - could be a local redis instance or cloud hosted redis. Also support rediss:// urls
4+
15
# Discord Configuration
26
DISCORD_APPLICATION_ID=
37
DISCORD_API_TOKEN= # Bot token

agent/package.json

+60-59
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,62 @@
11
{
2-
"name": "@ai16z/agent",
3-
"version": "0.1.6-alpha.4",
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-
"@ai16z/adapter-postgres": "workspace:*",
21-
"@ai16z/adapter-sqlite": "workspace:*",
22-
"@ai16z/client-auto": "workspace:*",
23-
"@ai16z/client-direct": "workspace:*",
24-
"@ai16z/client-discord": "workspace:*",
25-
"@ai16z/client-farcaster": "workspace:*",
26-
"@ai16z/client-lens": "workspace:*",
27-
"@ai16z/client-telegram": "workspace:*",
28-
"@ai16z/client-twitter": "workspace:*",
29-
"@ai16z/client-slack": "workspace:*",
30-
"@ai16z/eliza": "workspace:*",
31-
"@ai16z/plugin-0g": "workspace:*",
32-
"@ai16z/plugin-aptos": "workspace:*",
33-
"@ai16z/plugin-bootstrap": "workspace:*",
34-
"@ai16z/plugin-intiface": "workspace:*",
35-
"@ai16z/plugin-coinbase": "workspace:*",
36-
"@ai16z/plugin-conflux": "workspace:*",
37-
"@ai16z/plugin-evm": "workspace:*",
38-
"@ai16z/plugin-flow": "workspace:*",
39-
"@ai16z/plugin-story": "workspace:*",
40-
"@ai16z/plugin-goat": "workspace:*",
41-
"@ai16z/plugin-icp": "workspace:*",
42-
"@ai16z/plugin-image-generation": "workspace:*",
43-
"@ai16z/plugin-nft-generation": "workspace:*",
44-
"@ai16z/plugin-node": "workspace:*",
45-
"@ai16z/plugin-solana": "workspace:*",
46-
"@ai16z/plugin-starknet": "workspace:*",
47-
"@ai16z/plugin-ton": "workspace:*",
48-
"@ai16z/plugin-sui": "workspace:*",
49-
"@ai16z/plugin-tee": "workspace:*",
50-
"@ai16z/plugin-multiversx": "workspace:*",
51-
"@ai16z/plugin-near": "workspace:*",
52-
"@ai16z/plugin-zksync-era": "workspace:*",
53-
"readline": "1.3.0",
54-
"ws": "8.18.0",
55-
"yargs": "17.7.2"
56-
},
57-
"devDependencies": {
58-
"ts-node": "10.9.2",
59-
"tsup": "8.3.5"
60-
}
2+
"name": "@ai16z/agent",
3+
"version": "0.1.6-alpha.4",
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+
"@ai16z/adapter-postgres": "workspace:*",
21+
"@ai16z/adapter-redis": "workspace:*",
22+
"@ai16z/adapter-sqlite": "workspace:*",
23+
"@ai16z/client-auto": "workspace:*",
24+
"@ai16z/client-direct": "workspace:*",
25+
"@ai16z/client-discord": "workspace:*",
26+
"@ai16z/client-farcaster": "workspace:*",
27+
"@ai16z/client-lens": "workspace:*",
28+
"@ai16z/client-telegram": "workspace:*",
29+
"@ai16z/client-twitter": "workspace:*",
30+
"@ai16z/client-slack": "workspace:*",
31+
"@ai16z/eliza": "workspace:*",
32+
"@ai16z/plugin-0g": "workspace:*",
33+
"@ai16z/plugin-aptos": "workspace:*",
34+
"@ai16z/plugin-bootstrap": "workspace:*",
35+
"@ai16z/plugin-intiface": "workspace:*",
36+
"@ai16z/plugin-coinbase": "workspace:*",
37+
"@ai16z/plugin-conflux": "workspace:*",
38+
"@ai16z/plugin-evm": "workspace:*",
39+
"@ai16z/plugin-flow": "workspace:*",
40+
"@ai16z/plugin-story": "workspace:*",
41+
"@ai16z/plugin-goat": "workspace:*",
42+
"@ai16z/plugin-icp": "workspace:*",
43+
"@ai16z/plugin-image-generation": "workspace:*",
44+
"@ai16z/plugin-nft-generation": "workspace:*",
45+
"@ai16z/plugin-node": "workspace:*",
46+
"@ai16z/plugin-solana": "workspace:*",
47+
"@ai16z/plugin-starknet": "workspace:*",
48+
"@ai16z/plugin-ton": "workspace:*",
49+
"@ai16z/plugin-sui": "workspace:*",
50+
"@ai16z/plugin-tee": "workspace:*",
51+
"@ai16z/plugin-multiversx": "workspace:*",
52+
"@ai16z/plugin-near": "workspace:*",
53+
"@ai16z/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+
}
6162
}

agent/src/index.ts

+52-7
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ import {
2424
settings,
2525
stringToUuid,
2626
validateCharacterConfig,
27+
CacheStore,
2728
} from "@ai16z/eliza";
29+
import { RedisClient } from "@ai16z/adapter-redis";
2830
import { zgPlugin } from "@ai16z/plugin-0g";
2931
import { bootstrapPlugin } from "@ai16z/plugin-bootstrap";
3032
import createGoatPlugin from "@ai16z/plugin-goat";
@@ -210,11 +212,11 @@ export async function loadCharacters(
210212
export function getTokenForProvider(
211213
provider: ModelProviderName,
212214
character: Character
213-
):string {
215+
): string {
214216
switch (provider) {
215217
// no key needed for llama_local
216218
case ModelProviderName.LLAMALOCAL:
217-
return ''
219+
return "";
218220
case ModelProviderName.OPENAI:
219221
return (
220222
character.settings?.secrets?.OPENAI_API_KEY ||
@@ -310,9 +312,9 @@ export function getTokenForProvider(
310312
settings.AKASH_CHAT_API_KEY
311313
);
312314
default:
313-
const errorMessage = `Failed to get token - unsupported model provider: ${provider}`
314-
elizaLogger.error(errorMessage)
315-
throw new Error(errorMessage)
315+
const errorMessage = `Failed to get token - unsupported model provider: ${provider}`;
316+
elizaLogger.error(errorMessage);
317+
throw new Error(errorMessage);
316318
}
317319
}
318320

@@ -402,7 +404,6 @@ export async function initializeClients(
402404
// TODO: Add Slack client to the list
403405
// Initialize clients as an object
404406

405-
406407
if (clientTypes.includes("slack")) {
407408
const slackClient = await SlackClientInterface.start(runtime);
408409
if (slackClient) clients.slack = slackClient; // Use object property instead of push
@@ -583,6 +584,45 @@ function initializeDbCache(character: Character, db: IDatabaseCacheAdapter) {
583584
return cache;
584585
}
585586

587+
function initializeCache(
588+
cacheStore: string,
589+
character: Character,
590+
baseDir?: string,
591+
db?: IDatabaseCacheAdapter
592+
) {
593+
switch (cacheStore) {
594+
case CacheStore.REDIS:
595+
if (process.env.REDIS_URL) {
596+
elizaLogger.info("Connecting to Redis...");
597+
const redisClient = new RedisClient(process.env.REDIS_URL);
598+
return new CacheManager(
599+
new DbCacheAdapter(redisClient, character.id) // Using DbCacheAdapter since RedisClient also implements IDatabaseCacheAdapter
600+
);
601+
} else {
602+
throw new Error("REDIS_URL environment variable is not set.");
603+
}
604+
605+
case CacheStore.DATABASE:
606+
if (db) {
607+
elizaLogger.info("Using Database Cache...");
608+
return initializeDbCache(character, db);
609+
} else {
610+
throw new Error(
611+
"Database adapter is not provided for CacheStore.Database."
612+
);
613+
}
614+
615+
case CacheStore.FILESYSTEM:
616+
elizaLogger.info("Using File System Cache...");
617+
return initializeFsCache(baseDir, character);
618+
619+
default:
620+
throw new Error(
621+
`Invalid cache store: ${cacheStore} or required configuration missing.`
622+
);
623+
}
624+
}
625+
586626
async function startAgent(
587627
character: Character,
588628
directClient: DirectClient
@@ -604,7 +644,12 @@ async function startAgent(
604644

605645
await db.init();
606646

607-
const cache = initializeDbCache(character, db);
647+
const cache = initializeCache(
648+
process.env.CACHE_STORE,
649+
character,
650+
"",
651+
db
652+
); // "" should be replaced with dir for file system caching. THOUGHTS: might probably make this into an env
608653
const runtime: AgentRuntime = await createAgent(
609654
character,
610655
db,

packages/core/src/types.ts

+6
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,12 @@ export type CacheOptions = {
993993
expires?: number;
994994
};
995995

996+
export enum CacheStore {
997+
REDIS = "redis",
998+
DATABASE = "database",
999+
FILESYSTEM = "filesystem",
1000+
}
1001+
9961002
export interface ICacheManager {
9971003
get<T = unknown>(key: string): Promise<T | undefined>;
9981004
set<T>(key: string, value: T, options?: CacheOptions): Promise<void>;

pnpm-lock.yaml

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)