Skip to content

Commit 42c61a8

Browse files
committed
Add a way to create/store/restore agents in the filesystem at agents/data/characters
1 parent 6cfbd18 commit 42c61a8

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

.env.example

+3
Original file line numberDiff line numberDiff line change
@@ -616,3 +616,6 @@ INSTAGRAM_POST_INTERVAL_MAX=120 # Default: 120 minutes
616616
INSTAGRAM_ENABLE_ACTION_PROCESSING=false # Enable/disable action processing
617617
INSTAGRAM_ACTION_INTERVAL=5 # Interval between actions in minutes
618618
INSTAGRAM_MAX_ACTIONS=1 # Maximum number of actions to process at once
619+
620+
# Stores characters set by using the direct API in the data/character folder for further load when the app restarts
621+
USE_CHARACTER_STORAGE=false

agent/src/index.ts

+18
Original file line numberDiff line numberDiff line change
@@ -249,11 +249,29 @@ function commaSeparatedStringToArray(commaSeparated: string): string[] {
249249
return commaSeparated?.split(",").map(value => value.trim())
250250
}
251251

252+
async function readCharactersFromStorage(characterPaths: string[]): Promise<string[]> {
253+
try {
254+
const uploadDir = path.join(process.cwd(), "data", "characters");
255+
const fileNames = await fs.promises.readdir(uploadDir);
256+
fileNames.forEach(fileName => {
257+
characterPaths.push(uploadDir + '/' + fileName);
258+
});
259+
} catch (err) {
260+
console.error('Error reading directory:', err);
261+
}
262+
263+
return characterPaths;
264+
};
252265

253266
export async function loadCharacters(
254267
charactersArg: string
255268
): Promise<Character[]> {
256269
let characterPaths = commaSeparatedStringToArray(charactersArg)
270+
271+
if(process.env.USE_CHARACTER_STORAGE) {
272+
characterPaths = await readCharactersFromStorage(characterPaths);
273+
}
274+
257275
const loadedCharacters: Character[] = [];
258276

259277
if (characterPaths?.length > 0) {

packages/client-direct/src/api.ts

+30-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import express from "express";
22
import bodyParser from "body-parser";
33
import cors from "cors";
4+
import path from "path";
5+
import fs from "fs";
46

57
import {
68
AgentRuntime,
@@ -79,6 +81,16 @@ export function createApiRouter(
7981
res.json({ agents: agentsList });
8082
});
8183

84+
router.get('/storage', async (req, res) => {
85+
try {
86+
const uploadDir = path.join(process.cwd(), "data", "characters");
87+
const files = await fs.promises.readdir(uploadDir);
88+
res.json({ files });
89+
} catch (error) {
90+
res.status(500).json({ error: error.message });
91+
}
92+
});
93+
8294
router.get("/agents/:agentId", (req, res) => {
8395
const { agentId } = validateUUIDParams(req.params, res) ?? {
8496
agentId: null,
@@ -127,7 +139,7 @@ export function createApiRouter(
127139
};
128140
if (!agentId) return;
129141

130-
const agent: AgentRuntime = agents.get(agentId);
142+
let agent: AgentRuntime = agents.get(agentId);
131143

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

152+
// stores the json data before it is modified with added data
153+
const characterJson = { ...req.body };
154+
140155
// load character from body
141156
const character = req.body;
142157
try {
@@ -152,7 +167,7 @@ export function createApiRouter(
152167

153168
// start it up (and register it)
154169
try {
155-
await directClient.startAgent(character);
170+
agent = await directClient.startAgent(character);
156171
elizaLogger.log(`${character.name} started`);
157172
} catch (e) {
158173
elizaLogger.error(`Error starting agent: ${e}`);
@@ -162,6 +177,19 @@ export function createApiRouter(
162177
});
163178
return;
164179
}
180+
181+
if(process.env.USE_CHARACTER_STORAGE === 'true') {
182+
let filename = '';
183+
try {
184+
filename = `${agent.agentId}.json`;
185+
const uploadDir = path.join(process.cwd(), "data", "characters");
186+
const filepath = path.join(uploadDir, filename);
187+
await fs.promises.writeFile(filepath, JSON.stringify({ ...characterJson, id: agent.agentId }, null, 2));
188+
} catch (error) {
189+
console.log("error:", error.message);
190+
}
191+
}
192+
165193
res.json({
166194
id: character.id,
167195
character: character,

0 commit comments

Comments
 (0)