Skip to content

Commit 940cfbb

Browse files
committed
Merge branch 'main' of https://github.com/ai16z/eliza into HEAD
2 parents 47ccfc1 + 8084bc8 commit 940cfbb

38 files changed

+762
-302
lines changed

.github/workflows/ci.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,13 @@ jobs:
2525
- name: Run Prettier
2626
run: pnpm run prettier --check .
2727

28+
- name: Create test env file
29+
run: |
30+
echo "TEST_DATABASE_CLIENT=sqlite" > core/.env.test
31+
echo "NODE_ENV=test" >> core/.env.test
32+
33+
- name: Run tests
34+
run: cd core && pnpm test
35+
2836
- name: Build packages
2937
run: pnpm run build

.vscode/launch.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
{
88
"type": "node",
99
"request": "launch",
10-
"name": "Launch via npm",
11-
"runtimeExecutable": "npm",
10+
"name": "Launch via pnpm",
11+
"runtimeExecutable": "pnpm",
1212
"runtimeArgs": ["run", "dev"],
1313
"skipFiles": ["<node_internals>/**"]
1414
}

README.md

+25
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,28 @@ downloads the model from huggingface and queries it locally
143143
## Discord Bot
144144

145145
For help with setting up your Discord Bot, check out here: https://discordjs.guide/preparations/setting-up-a-bot-application.html
146+
147+
# Development
148+
149+
## Testing
150+
151+
To run the test suite:
152+
153+
```bash
154+
pnpm test # Run tests once
155+
pnpm test:watch # Run tests in watch mode
156+
```
157+
158+
For database-specific tests:
159+
```bash
160+
pnpm test:sqlite # Run tests with SQLite
161+
pnpm test:sqljs # Run tests with SQL.js
162+
```
163+
164+
Tests are written using Jest and can be found in `src/**/*.test.ts` files. The test environment is configured to:
165+
- Load environment variables from `.env.test`
166+
- Use a 2-minute timeout for long-running tests
167+
- Support ESM modules
168+
- Run tests in sequence (--runInBand)
169+
170+
To create new tests, add a `.test.ts` file adjacent to the code you're testing.

core/.env.example

+2-1
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,5 @@ HELIUS_API_KEY=
4242
## Telegram
4343
TELEGRAM_BOT_TOKEN=
4444

45-
TOGETHER_API_KEY=
45+
TOGETHER_API_KEY=
46+
SERVER_PORT=3000

core/.env.test

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
TEST_DATABASE_CLIENT=sqlite
2+
NODE_ENV=test

core/jest.config.js

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
/** @type {import('ts-jest').JestConfigWithTsJest} */
22
export default {
33
preset: "ts-jest",
4-
testEnvironment: "jest-environment-node",
4+
testEnvironment: "node",
55
rootDir: "./src",
66
testMatch: ["**/*.test.ts"],
7+
setupFilesAfterEnv: ["<rootDir>/test_resources/testSetup.ts"],
8+
testTimeout: 120000,
79
globals: {
810
__DEV__: true,
911
__TEST__: true,
1012
__VERSION__: "0.0.1",
1113
},
12-
// collectCoverage: true,
13-
// collectCoverageFrom: ["**/*.{ts}", "!**/*.test.{ts}", "!**/node_modules/**", "!**/vendor/**"],
14-
// coverageDirectory: "../coverage",
1514
transform: {
1615
"^.+\\.tsx?$": [
1716
"ts-jest",
@@ -24,4 +23,4 @@ export default {
2423
"^(\\.{1,2}/.*)\\.js$": "$1",
2524
},
2625
extensionsToTreatAsEsm: [".ts"],
27-
};
26+
}

core/package.json

+13-13
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,29 @@
1010
"lint": "eslint . --fix",
1111
"start": "node --loader ts-node/esm src/index.ts",
1212
"start:arok": "node --loader ts-node/esm src/index.ts --characters=\"../characters/arok.character.json\"",
13-
"start:service:ruby": "pm2 start npm --name=\"ruby\" --restart-delay=3000 --max-restarts=10 -- run start:ruby",
13+
"start:service:ruby": "pm2 start pnpm --name=\"ruby\" --restart-delay=3000 --max-restarts=10 -- run start:ruby",
1414
"stop:service:ruby": "pm2 stop ruby",
1515
"start:ruby": "node --loader ts-node/esm src/index.ts --characters=\"../characters/ruby.character.json\"",
16-
"start:service:trump": "pm2 start npm --name=\"trump\" --restart-delay=3000 --max-restarts=10 -- run start:trump",
16+
"start:service:trump": "pm2 start pnpm --name=\"trump\" --restart-delay=3000 --max-restarts=10 -- run start:trump",
1717
"stop:service:trump": "pm2 stop trump",
18-
"start:service:degen": "pm2 start npm --name=\"degen\" --restart-delay=3000 --max-restarts=10 -- run start:degen",
18+
"start:service:degen": "pm2 start pnpm --name=\"degen\" --restart-delay=3000 --max-restarts=10 -- run start:degen",
1919
"stop:service:degen": "pm2 stop degen",
2020
"start:degen": "node --loader ts-node/esm src/index.ts --characters=\"../characters/degenspartan.json\"",
21-
"start:service:all": "pm2 start npm --name=\"all\" --restart-delay=3000 --max-restarts=10 -- run start:all",
21+
"start:service:all": "pm2 start pnpm --name=\"all\" --restart-delay=3000 --max-restarts=10 -- run start:all",
2222
"stop:service:all": "pm2 stop all",
23-
"start:all": "node --loader ts-node/esm src/index.ts --characters=\"../characters/degenspartan.json\",\"../characters/ruby.character.json\"",
23+
"start:all": "node --loader ts-node/esm src/index.ts --characters=\"../characters/degenspartan.json\",\"../characters/ruby.character.json\",\"../characters/pmairca.character.json\"",
2424
"start:trump": "node --loader ts-node/esm src/index.ts --characters=\"../characters/trump.character.json\"",
25-
"start:service:tate": "pm2 start npm --name=\"tate\" --restart-delay=3000 --max-restarts=10 -- run start:tate",
25+
"start:service:tate": "pm2 start pnpm --name=\"tate\" --restart-delay=3000 --max-restarts=10 -- run start:tate",
2626
"stop:service:tate": "pm2 stop tate",
2727
"start:tate": "node --loader ts-node/esm src/index.ts --characters=\"../characters/tate.character.json\"",
2828
"watch": "tsc --watch",
2929
"dev": "tsc && nodemon",
30-
"build:docs": "cd docs && npm run build",
30+
"build:docs": "cd docs && pnpm run build",
3131
"postinstall": "npx playwright install-deps && npx playwright install",
32-
"test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest --runInBand --watch -f",
33-
"test:sqlite": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" TEST_DATABASE_CLIENT=sqlite jest --runInBand --watch -f",
34-
"test:sqljs": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" TEST_DATABASE_CLIENT=sqljs jest --runInBand --watch -f"
32+
"test": "jest --runInBand",
33+
"test:watch": "jest --runInBand --watch",
34+
"test:sqlite": "cross-env TEST_DATABASE_CLIENT=sqlite jest --runInBand --watch",
35+
"test:sqljs": "cross-env TEST_DATABASE_CLIENT=sqljs jest --runInBand --watch"
3536
},
3637
"author": "",
3738
"license": "MIT",
@@ -59,15 +60,15 @@
5960
"itty-router": "5.0.18",
6061
"jest": "29.7.0",
6162
"lint-staged": "15.2.10",
62-
"npm-run-all2": "7.0.1",
6363
"prettier": "3.3.3",
6464
"rimraf": "6.0.1",
6565
"rollup": "2.79.2",
6666
"ts-jest": "29.2.5",
6767
"ts-node": "10.9.2",
6868
"tslib": "2.8.0",
6969
"typescript": "5.6.3",
70-
"wrangler": "3.84.0"
70+
"wrangler": "3.84.0",
71+
"@types/pdfjs-dist": "^2.10.378"
7172
},
7273
"pnpm": {
7374
"overrides": {
@@ -83,7 +84,6 @@
8384
"@anthropic-ai/sdk": "^0.30.1",
8485
"@cliqz/adblocker-playwright": "1.34.0",
8586
"@coral-xyz/anchor": "^0.30.1",
86-
"@discordjs/opus": "github:discordjs/opus",
8787
"@discordjs/rest": "2.4.0",
8888
"@discordjs/voice": "0.17.0",
8989
"@echogarden/espeak-ng-emscripten": "0.3.0",

core/src/actions/imageGeneration.ts

+21
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
State,
66
Action,
77
} from "../core/types.ts";
8+
import { prettyConsole } from "../index.ts";
89
import { generateCaption, generateImage } from "./imageGenerationUtils.ts";
910

1011
export const imageGeneration: Action = {
@@ -23,11 +24,16 @@ export const imageGeneration: Action = {
2324
options: any,
2425
callback: HandlerCallback
2526
) => {
27+
prettyConsole.log("Composing state for message:", message);
2628
state = (await runtime.composeState(message)) as State;
2729
const userId = runtime.agentId;
30+
prettyConsole.log("User ID:", userId);
2831

2932
const imagePrompt = message.content.text;
33+
prettyConsole.log("Image prompt received:", imagePrompt);
3034
const res: { image: string; caption: string }[] = [];
35+
36+
prettyConsole.log("Generating image with prompt:", imagePrompt);
3137
const images = await generateImage(
3238
{
3339
prompt: imagePrompt,
@@ -37,16 +43,29 @@ export const imageGeneration: Action = {
3743
},
3844
runtime
3945
);
46+
4047
if (images.success && images.data && images.data.length > 0) {
48+
prettyConsole.log(
49+
"Image generation successful, number of images:",
50+
images.data.length
51+
);
4152
for (let i = 0; i < images.data.length; i++) {
4253
const image = images.data[i];
54+
prettyConsole.log(`Processing image ${i + 1}:`, image);
55+
4356
const caption = await generateCaption(
4457
{
4558
imageUrl: image,
4659
},
4760
runtime
4861
);
62+
63+
prettyConsole.log(
64+
`Generated caption for image ${i + 1}:`,
65+
caption.title
66+
);
4967
res.push({ image: image, caption: caption.title });
68+
5069
callback(
5170
{
5271
text: caption.description,
@@ -64,6 +83,8 @@ export const imageGeneration: Action = {
6483
[]
6584
);
6685
}
86+
} else {
87+
prettyConsole.error("Image generation failed or returned no data.");
6788
}
6889
},
6990
examples: [

core/src/adapters/postgres.ts

+14-13
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,11 @@ export class PostgresDatabaseAdapter extends DatabaseAdapter {
107107
}): Promise<Memory[]> {
108108
const client = await this.pool.connect();
109109
try {
110+
if (params.roomIds.length === 0) return [];
110111
const placeholders = params.roomIds
111112
.map((_, i) => `$${i + 2}`)
112113
.join(", ");
113-
114+
114115
let query = `SELECT * FROM memories WHERE type = $1 AND "roomId" IN (${placeholders})`;
115116
let queryParams = [params.tableName, ...params.roomIds];
116117

@@ -304,7 +305,7 @@ export class PostgresDatabaseAdapter extends DatabaseAdapter {
304305
`;
305306

306307
if (params.unique) {
307-
sql += " AND unique = true";
308+
sql += ` AND "unique" = true`;
308309
}
309310

310311
sql += ` AND 1 - (embedding <-> $3) >= $4
@@ -349,18 +350,18 @@ export class PostgresDatabaseAdapter extends DatabaseAdapter {
349350

350351
if (params.start) {
351352
paramCount++;
352-
sql += ` AND "createdAt" >= to_timestamp($${paramCount / 1000})`;
353-
values.push(params.start);
353+
sql += ` AND "createdAt" >= to_timestamp($${paramCount})`;
354+
values.push(params.start/1000);
354355
}
355356

356357
if (params.end) {
357358
paramCount++;
358-
sql += ` AND "createdAt" <= to_timestamp($${paramCount / 1000})`;
359-
values.push(params.end);
359+
sql += ` AND "createdAt" <= to_timestamp($${paramCount})`;
360+
values.push(params.end/1000);
360361
}
361362

362363
if (params.unique) {
363-
sql += " AND unique = true";
364+
sql += ` AND "unique" = true`;
364365
}
365366

366367
if (params.agentId) {
@@ -382,9 +383,9 @@ export class PostgresDatabaseAdapter extends DatabaseAdapter {
382383
return rows.map((row) => ({
383384
...row,
384385
content:
385-
typeof rows.content === "string"
386-
? JSON.parse(rows.content)
387-
: rows.content,
386+
typeof row.content === "string"
387+
? JSON.parse(row.content)
388+
: row.content,
388389
}));
389390
} finally {
390391
client.release();
@@ -635,7 +636,7 @@ export class PostgresDatabaseAdapter extends DatabaseAdapter {
635636

636637
if (params.unique) {
637638
sql += ` AND "unique" = true`;
638-
}
639+
}
639640

640641
// TODO: Test this
641642
if (params.agentId) {
@@ -759,7 +760,7 @@ export class PostgresDatabaseAdapter extends DatabaseAdapter {
759760
try {
760761
let sql = `SELECT COUNT(*) as count FROM memories WHERE type = $1 AND "roomId" = $2`;
761762
if (unique) {
762-
sql += " AND unique = true";
763+
sql += ` AND "unique" = true`;
763764
}
764765

765766
const { rows } = await client.query(sql, [tableName, roomId]);
@@ -796,7 +797,7 @@ export class PostgresDatabaseAdapter extends DatabaseAdapter {
796797
async getRoomsForParticipants(userIds: UUID[]): Promise<UUID[]> {
797798
const client = await this.pool.connect();
798799
try {
799-
const placeholders = userIds.map((_, i) => `${i + 1}`).join(", ");
800+
const placeholders = userIds.map((_, i) => `$${i + 1}`).join(", ");
800801
const { rows } = await client.query(
801802
`SELECT DISTINCT "roomId" FROM participants WHERE "userId" IN (${placeholders})`,
802803
userIds

core/src/adapters/sqlite.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter {
160160
const placeholders = params.roomIds.map(() => "?").join(", ");
161161
let sql = `SELECT * FROM memories WHERE type = ? AND roomId IN (${placeholders})`;
162162
let queryParams = [params.tableName, ...params.roomIds];
163-
163+
164164
if (params.agentId) {
165165
sql += ` AND userId = ?`;
166166
queryParams.push(params.agentId);
@@ -171,9 +171,9 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter {
171171
content: string;
172172
})[];
173173

174-
return rows.map(row => ({
174+
return rows.map((row) => ({
175175
...row,
176-
content: JSON.parse(row.content)
176+
content: JSON.parse(row.content),
177177
}));
178178
}
179179

core/src/adapters/sqlite/sqlite_vec.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import * as sqliteVec from "sqlite-vec";
22
import { Database } from "better-sqlite3";
3+
import { prettyConsole } from "../../index.ts";
34

45
// Loads the sqlite-vec extensions into the provided SQLite database
56
export function loadVecExtensions(db: Database): void {
67
try {
78
// Load sqlite-vec extensions
89
sqliteVec.load(db);
9-
console.log("sqlite-vec extensions loaded successfully.");
10+
prettyConsole.log("sqlite-vec extensions loaded successfully.");
1011
} catch (error) {
11-
console.error("Failed to load sqlite-vec extensions:", error);
12+
prettyConsole.error("Failed to load sqlite-vec extensions:", error);
1213
throw error;
1314
}
1415
}

core/src/adapters/supabase.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -318,15 +318,14 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter {
318318
tableName: string;
319319
}
320320
): Promise<Memory[]> {
321-
322321
const queryParams = {
323322
query_table_name: params.tableName,
324323
query_roomId: params.roomId,
325324
query_embedding: embedding,
326325
query_match_threshold: params.match_threshold,
327326
query_match_count: params.count,
328327
query_unique: !!params.unique,
329-
}
328+
};
330329
if (params.agentId) {
331330
(queryParams as any).query_agentId = params.agentId;
332331
}

0 commit comments

Comments
 (0)