Skip to content

Commit 1014e75

Browse files
Merge remote-tracking branch 'origin/develop' into eternalai-agent
# Conflicts: # .env.example
2 parents d800539 + 5c9a8d6 commit 1014e75

File tree

16 files changed

+738
-281
lines changed

16 files changed

+738
-281
lines changed

.env.example

+195-189
Large diffs are not rendered by default.

README.md

+41-26
Original file line numberDiff line numberDiff line change
@@ -61,33 +61,21 @@ cp .env.example .env
6161
pnpm i && pnpm build && pnpm start
6262
```
6363

64-
Once the agent is running, you should see the message to run "pnpm start:client" at the end.
65-
Open another terminal and move to same directory and then run below command and follow the URL to chat to your agent.
66-
67-
```bash
68-
pnpm start:client
69-
```
70-
71-
Then read the [Documentation](https://elizaos.github.io/eliza/) to learn how to customize your Eliza.
72-
7364
### Manually Start Eliza (Only recommended if you know what you are doing)
7465

66+
#### Checkout the latest release
67+
7568
```bash
7669
# Clone the repository
7770
git clone https://github.com/elizaos/eliza.git
7871

79-
# Checkout the latest release
8072
# This project iterates fast, so we recommend checking out the latest release
8173
git checkout $(git describe --tags --abbrev=0)
8274
# If the above doesn't checkout the latest release, this should work:
8375
# git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
8476
```
8577

86-
### Start Eliza with Gitpod
87-
88-
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/elizaos/eliza/tree/main)
89-
90-
### Edit the .env file
78+
#### Edit the .env file
9179

9280
Copy .env.example to .env and fill in the appropriate values.
9381

@@ -97,6 +85,32 @@ cp .env.example .env
9785

9886
Note: .env is optional. If you're planning to run multiple distinct agents, you can pass secrets through the character JSON
9987

88+
89+
#### Start Eliza
90+
91+
```bash
92+
pnpm i
93+
pnpm build
94+
pnpm start
95+
96+
# The project iterates fast, sometimes you need to clean the project if you are coming back to the project
97+
pnpm clean
98+
```
99+
100+
### Interact via Browser
101+
102+
```
103+
Once the agent is running, you should see the message to run "pnpm start:client" at the end.
104+
Open another terminal and move to same directory and then run below command and follow the URL to chat to your agent.
105+
106+
```bash
107+
pnpm start:client
108+
```
109+
110+
Then read the [Documentation](https://elizaos.github.io/eliza/) to learn how to customize your Eliza.
111+
112+
----
113+
100114
### Automatically Start Eliza
101115

102116
The start script provides an automated way to set up and run Eliza:
@@ -109,7 +123,9 @@ For detailed instructions on using the start script, including character managem
109123

110124
> **Note**: The start script handles all dependencies, environment setup, and character management automatically.
111125
112-
### Edit the character file
126+
----
127+
128+
### Modify Character
113129

114130
1. Open `packages/core/src/defaultCharacter.ts` to modify the default character. Uncomment and edit.
115131

@@ -119,16 +135,7 @@ For detailed instructions on using the start script, including character managem
119135
3. Connect with X (Twitter)
120136
- change `"clients": []` to `"clients": ["twitter"]` in the character file to connect with X
121137

122-
### Manually Start Eliza
123-
124-
```bash
125-
pnpm i
126-
pnpm build
127-
pnpm start
128-
129-
# The project iterates fast, sometimes you need to clean the project if you are coming back to the project
130-
pnpm clean
131-
```
138+
---
132139

133140
#### Additional Requirements
134141

@@ -137,6 +144,14 @@ You may need to install Sharp. If you see an error when starting up, try install
137144
```
138145
pnpm install --include=optional sharp
139146
```
147+
---
148+
149+
150+
### Start Eliza with Gitpod
151+
152+
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/elizaos/eliza/tree/main)
153+
154+
---
140155

141156
### Community & contact
142157

agent/src/index.ts

+36-9
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,17 @@ function mergeCharacters(base: Character, child: Character): Character {
184184
};
185185
return mergeObjects(base, child);
186186
}
187-
async function loadCharacter(filePath: string): Promise<Character> {
188-
const content = tryLoadFile(filePath);
189-
if (!content) {
190-
throw new Error(`Character file not found: ${filePath}`);
191-
}
192-
let character = JSON.parse(content);
187+
188+
async function loadCharacterFromUrl(url: string): Promise<Character> {
189+
const response = await fetch(url);
190+
const character = await response.json();
191+
return jsonToCharacter(url, character);
192+
}
193+
194+
async function jsonToCharacter(
195+
filePath: string,
196+
character: any
197+
): Promise<Character> {
193198
validateCharacterConfig(character);
194199

195200
// .id isn't really valid
@@ -227,6 +232,15 @@ async function loadCharacter(filePath: string): Promise<Character> {
227232
return character;
228233
}
229234

235+
async function loadCharacter(filePath: string): Promise<Character> {
236+
const content = tryLoadFile(filePath);
237+
if (!content) {
238+
throw new Error(`Character file not found: ${filePath}`);
239+
}
240+
let character = JSON.parse(content);
241+
return jsonToCharacter(filePath, character);
242+
}
243+
230244
export async function loadCharacters(
231245
charactersArg: string
232246
): Promise<Character[]> {
@@ -305,6 +319,16 @@ export async function loadCharacters(
305319
}
306320

307321
if (loadedCharacters.length === 0) {
322+
if (
323+
process.env.REMOTE_CHARACTER_URL != "" &&
324+
process.env.REMOTE_CHARACTER_URL.startsWith("http")
325+
) {
326+
const character = await loadCharacterFromUrl(
327+
process.env.REMOTE_CHARACTER_URL
328+
);
329+
loadedCharacters.push(character);
330+
}
331+
308332
elizaLogger.info("No characters found, using default character");
309333
loadedCharacters.push(defaultCharacter);
310334
}
@@ -1116,14 +1140,17 @@ startAgents().catch((error) => {
11161140
});
11171141

11181142
// Prevent unhandled exceptions from crashing the process if desired
1119-
if (process.env.PREVENT_UNHANDLED_EXIT && parseBooleanFromText(process.env.PREVENT_UNHANDLED_EXIT)) {
1143+
if (
1144+
process.env.PREVENT_UNHANDLED_EXIT &&
1145+
parseBooleanFromText(process.env.PREVENT_UNHANDLED_EXIT)
1146+
) {
11201147
// Handle uncaught exceptions to prevent the process from crashing
1121-
process.on('uncaughtException', function(err) {
1148+
process.on("uncaughtException", function (err) {
11221149
console.error("uncaughtException", err);
11231150
});
11241151

11251152
// Handle unhandled rejections to prevent the process from crashing
1126-
process.on('unhandledRejection', function(err) {
1153+
process.on("unhandledRejection", function (err) {
11271154
console.error("unhandledRejection", err);
11281155
});
11291156
}

packages/adapter-pglite/src/index.ts

+27
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,33 @@ export class PGLiteDatabaseAdapter
333333
}, "getMemoryById");
334334
}
335335

336+
async getMemoriesByIds(
337+
memoryIds: UUID[],
338+
tableName?: string
339+
): Promise<Memory[]> {
340+
return this.withDatabase(async () => {
341+
if (memoryIds.length === 0) return [];
342+
const placeholders = memoryIds.map((_, i) => `$${i + 1}`).join(",");
343+
let sql = `SELECT * FROM memories WHERE id IN (${placeholders})`;
344+
const queryParams: any[] = [...memoryIds];
345+
346+
if (tableName) {
347+
sql += ` AND type = $${memoryIds.length + 1}`;
348+
queryParams.push(tableName);
349+
}
350+
351+
const { rows } = await this.query<Memory>(sql, queryParams);
352+
353+
return rows.map((row) => ({
354+
...row,
355+
content:
356+
typeof row.content === "string"
357+
? JSON.parse(row.content)
358+
: row.content,
359+
}));
360+
}, "getMemoriesByIds");
361+
}
362+
336363
async createMemory(memory: Memory, tableName: string): Promise<void> {
337364
return this.withDatabase(async () => {
338365
elizaLogger.debug("PostgresAdapter createMemory:", {

packages/adapter-postgres/src/index.ts

+27
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,33 @@ export class PostgresDatabaseAdapter
512512
}, "getMemoryById");
513513
}
514514

515+
async getMemoriesByIds(
516+
memoryIds: UUID[],
517+
tableName?: string
518+
): Promise<Memory[]> {
519+
return this.withDatabase(async () => {
520+
if (memoryIds.length === 0) return [];
521+
const placeholders = memoryIds.map((_, i) => `$${i + 1}`).join(",");
522+
let sql = `SELECT * FROM memories WHERE id IN (${placeholders})`;
523+
const queryParams: any[] = [...memoryIds];
524+
525+
if (tableName) {
526+
sql += ` AND type = $${memoryIds.length + 1}`;
527+
queryParams.push(tableName);
528+
}
529+
530+
const { rows } = await this.pool.query(sql, queryParams);
531+
532+
return rows.map((row) => ({
533+
...row,
534+
content:
535+
typeof row.content === "string"
536+
? JSON.parse(row.content)
537+
: row.content,
538+
}));
539+
}, "getMemoriesByIds");
540+
}
541+
515542
async createMemory(memory: Memory, tableName: string): Promise<void> {
516543
return this.withDatabase(async () => {
517544
elizaLogger.debug("PostgresAdapter createMemory:", {

packages/adapter-sqlite/src/index.ts

+27
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,33 @@ export class SqliteDatabaseAdapter
204204
return null;
205205
}
206206

207+
async getMemoriesByIds(
208+
memoryIds: UUID[],
209+
tableName?: string
210+
): Promise<Memory[]> {
211+
if (memoryIds.length === 0) return [];
212+
const queryParams: any[] = [];
213+
const placeholders = memoryIds.map(() => "?").join(",");
214+
let sql = `SELECT * FROM memories WHERE id IN (${placeholders})`;
215+
queryParams.push(...memoryIds);
216+
217+
if (tableName) {
218+
sql += ` AND type = ?`;
219+
queryParams.push(tableName);
220+
}
221+
222+
const memories = this.db.prepare(sql).all(...queryParams) as Memory[];
223+
224+
return memories.map((memory) => ({
225+
...memory,
226+
createdAt:
227+
typeof memory.createdAt === "string"
228+
? Date.parse(memory.createdAt as string)
229+
: memory.createdAt,
230+
content: JSON.parse(memory.content as unknown as string),
231+
}));
232+
}
233+
207234
async createMemory(memory: Memory, tableName: string): Promise<void> {
208235
// Delete any existing memory with the same ID first
209236
// const deleteSql = `DELETE FROM memories WHERE id = ? AND type = ?`;

packages/adapter-sqljs/src/index.ts

+29
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,35 @@ export class SqlJsDatabaseAdapter
237237
return memory || null;
238238
}
239239

240+
async getMemoriesByIds(
241+
memoryIds: UUID[],
242+
tableName?: string
243+
): Promise<Memory[]> {
244+
if (memoryIds.length === 0) return [];
245+
const placeholders = memoryIds.map(() => "?").join(",");
246+
let sql = `SELECT * FROM memories WHERE id IN (${placeholders})`;
247+
const queryParams: any[] = [...memoryIds];
248+
249+
if (tableName) {
250+
sql += ` AND type = ?`;
251+
queryParams.push(tableName);
252+
}
253+
254+
const stmt = this.db.prepare(sql);
255+
stmt.bind(queryParams);
256+
257+
const memories: Memory[] = [];
258+
while (stmt.step()) {
259+
const memory = stmt.getAsObject() as unknown as Memory;
260+
memories.push({
261+
...memory,
262+
content: JSON.parse(memory.content as unknown as string),
263+
});
264+
}
265+
stmt.free();
266+
return memories;
267+
}
268+
240269
async createMemory(memory: Memory, tableName: string): Promise<void> {
241270
let isUnique = true;
242271
if (memory.embedding) {

packages/adapter-supabase/src/index.ts

+25
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,31 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter {
370370
return data as Memory;
371371
}
372372

373+
async getMemoriesByIds(
374+
memoryIds: UUID[],
375+
tableName?: string
376+
): Promise<Memory[]> {
377+
if (memoryIds.length === 0) return [];
378+
379+
let query = this.supabase
380+
.from("memories")
381+
.select("*")
382+
.in("id", memoryIds);
383+
384+
if (tableName) {
385+
query = query.eq("type", tableName);
386+
}
387+
388+
const { data, error } = await query;
389+
390+
if (error) {
391+
console.error("Error retrieving memories by IDs:", error);
392+
return [];
393+
}
394+
395+
return data as Memory[];
396+
}
397+
373398
async createMemory(
374399
memory: Memory,
375400
tableName: string,

packages/core/__tests__/database.test.ts

+12
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@ class MockDatabaseAdapter extends DatabaseAdapter {
1515
getMemoryById(_id: UUID): Promise<Memory | null> {
1616
throw new Error("Method not implemented.");
1717
}
18+
async getMemoriesByIds(
19+
memoryIds: UUID[],
20+
_tableName?: string
21+
): Promise<Memory[]> {
22+
return memoryIds.map((id) => ({
23+
id: id,
24+
content: { text: "Test Memory" },
25+
roomId: "room-id" as UUID,
26+
userId: "user-id" as UUID,
27+
agentId: "agent-id" as UUID,
28+
})) as Memory[];
29+
}
1830
log(_params: {
1931
body: { [key: string]: unknown };
2032
userId: UUID;

0 commit comments

Comments
 (0)