From 811df46ef3b76af858f6a878d572bdb767daca60 Mon Sep 17 00:00:00 2001 From: ponderingdemocritus Date: Fri, 8 Nov 2024 08:17:46 +1100 Subject: [PATCH 1/5] yaml --- pnpm-lock.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad544fc7090..f92006c03aa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -487,7 +487,7 @@ importers: version: 2.79.2 ts-jest: specifier: 29.2.5 - version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(esbuild@0.17.19)(jest@29.7.0(@types/node@22.8.4)(ts-node@10.9.2(@types/node@22.8.4)(typescript@5.6.3)))(typescript@5.6.3) + version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(esbuild@0.24.0)(jest@29.7.0(@types/node@22.8.4)(ts-node@10.9.2(@types/node@22.8.4)(typescript@5.6.3)))(typescript@5.6.3) ts-node: specifier: 10.9.2 version: 10.9.2(@types/node@22.8.4)(typescript@5.6.3) @@ -24806,7 +24806,7 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(esbuild@0.17.19)(jest@29.7.0(@types/node@22.8.4)(ts-node@10.9.2(@types/node@22.8.4)(typescript@5.6.3)))(typescript@5.6.3): + ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(esbuild@0.24.0)(jest@29.7.0(@types/node@22.8.4)(ts-node@10.9.2(@types/node@22.8.4)(typescript@5.6.3)))(typescript@5.6.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 @@ -24824,7 +24824,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.26.0) - esbuild: 0.17.19 + esbuild: 0.24.0 ts-mixer@6.0.4: {} From a7ba13aad6ddc73089d23a97d4e778d192cfe2f1 Mon Sep 17 00:00:00 2001 From: ponderingdemocritus Date: Tue, 12 Nov 2024 18:43:47 +1100 Subject: [PATCH 2/5] tests --- packages/adapter-postgres/package.json | 2 +- packages/adapter-postgres/src/adapter.ts | 854 ++++++++++++++++++ packages/adapter-postgres/src/index.ts | 837 +---------------- packages/adapter-postgres/tsconfig.json | 8 + packages/adapter-postgres/tsup.config.ts | 20 + packages/adapter-sqlite/package.json | 2 +- packages/adapter-sqlite/src/adapter.ts | 649 +++++++++++++ packages/adapter-sqlite/src/index.ts | 652 +------------ packages/adapter-sqlite/src/sqlite_vec.ts | 2 +- packages/adapter-sqlite/tsconfig.json | 8 + packages/adapter-sqlite/tsup.config.ts | 21 + packages/adapter-sqljs/package.json | 2 +- packages/adapter-sqljs/src/adapter.ts | 746 +++++++++++++++ packages/adapter-sqljs/src/index.ts | 749 +-------------- packages/adapter-sqljs/tsconfig.json | 8 + packages/adapter-sqljs/tsup.config.ts | 20 + packages/adapter-supabase/package.json | 2 +- packages/adapter-supabase/tsconfig.json | 8 + packages/adapter-supabase/tsup.config.ts | 20 + packages/agent/tsconfig.json | 2 - packages/core/src/index.ts | 1 + packages/core/src/tests/actions.test.d.ts | 1 - packages/core/src/tests/browser.test.ts | 98 -- packages/core/src/tests/continue.test.d.ts | 1 - packages/core/src/tests/continue.test.ts | 233 ----- packages/core/src/tests/evaluation.test.d.ts | 1 - packages/core/src/tests/fact.test.d.ts | 1 - packages/core/src/tests/goal.test.d.ts | 1 - packages/core/src/tests/goals.test.d.ts | 1 - packages/core/src/tests/ignore.test.d.ts | 1 - packages/core/src/tests/memory.test.d.ts | 1 - packages/core/src/tests/messages.test.d.ts | 1 - packages/core/src/tests/providers.test.d.ts | 1 - .../core/src/tests/relationships.test.d.ts | 1 - packages/core/src/tests/runtime.test.d.ts | 1 - packages/core/src/tests/time.test.d.ts | 1 - packages/core/src/tests/token.test.d.ts | 1 - packages/core/src/tests/token.test.ts | 77 -- packages/core/src/tests/utils.test.ts | 76 -- packages/core/tsconfig.json | 17 +- packages/plugin-bootstrap/src/index.ts | 6 +- packages/plugin-bootstrap/tsconfig.json | 2 - .../plugin-image-generation/tsconfig.json | 2 - packages/plugin-node/src/index.ts | 8 + packages/plugin-node/tsconfig.json | 2 - packages/plugin-solana/src/index.ts | 6 +- packages/test/package.json | 31 + .../src/test_resources/cache.ts | 0 .../src/test_resources/constants.ts | 2 +- .../src/test_resources/createRuntime.ts | 23 +- .../{core => test}/src/test_resources/data.ts | 2 +- .../test_resources/getOrCreateRelationship.ts | 0 .../src/test_resources/populateMemories.ts | 4 +- .../src/test_resources/report.ts | 0 .../src/test_resources/runAiTest.ts | 2 +- .../src/test_resources/templates.ts | 0 .../src/test_resources/testAction.ts | 6 +- .../src/test_resources/testEvaluator.ts | 0 .../src/test_resources/testSetup.ts | 1 - .../src/test_resources/types.ts | 0 .../{core => test}/src/tests/actions.test.ts | 27 +- .../src/tests}/basic.test.ts | 0 packages/test/src/tests/browser.test.ts | 98 ++ packages/test/src/tests/continue.test.ts | 233 +++++ .../src/tests/evaluation.test.ts | 60 +- .../{core => test}/src/tests/fact.test.ts | 38 +- .../{core => test}/src/tests/goal.test.ts | 31 +- .../{core => test}/src/tests/goals.test.ts | 15 +- .../{core => test}/src/tests/ignore.test.ts | 34 +- .../{core => test}/src/tests/memory.test.ts | 31 +- .../{core => test}/src/tests/messages.test.ts | 20 +- .../src/tests/providers.test.ts | 7 +- .../src/tests/relationships.test.ts | 12 +- .../{core => test}/src/tests/runtime.test.ts | 14 +- .../{core => test}/src/tests/time.test.ts | 13 +- packages/test/src/tests/token.test.ts | 77 ++ packages/test/src/tests/utils.test.ts | 76 ++ packages/test/tsconfig.json | 8 + packages/test/tsup.config.ts | 20 + pnpm-lock.yaml | 614 +++++++------ 80 files changed, 3455 insertions(+), 3198 deletions(-) create mode 100644 packages/adapter-postgres/src/adapter.ts create mode 100644 packages/adapter-postgres/tsconfig.json create mode 100644 packages/adapter-postgres/tsup.config.ts create mode 100644 packages/adapter-sqlite/src/adapter.ts create mode 100644 packages/adapter-sqlite/tsconfig.json create mode 100644 packages/adapter-sqlite/tsup.config.ts create mode 100644 packages/adapter-sqljs/src/adapter.ts create mode 100644 packages/adapter-sqljs/tsconfig.json create mode 100644 packages/adapter-sqljs/tsup.config.ts create mode 100644 packages/adapter-supabase/tsconfig.json create mode 100644 packages/adapter-supabase/tsup.config.ts delete mode 100644 packages/core/src/tests/actions.test.d.ts delete mode 100644 packages/core/src/tests/browser.test.ts delete mode 100644 packages/core/src/tests/continue.test.d.ts delete mode 100644 packages/core/src/tests/continue.test.ts delete mode 100644 packages/core/src/tests/evaluation.test.d.ts delete mode 100644 packages/core/src/tests/fact.test.d.ts delete mode 100644 packages/core/src/tests/goal.test.d.ts delete mode 100644 packages/core/src/tests/goals.test.d.ts delete mode 100644 packages/core/src/tests/ignore.test.d.ts delete mode 100644 packages/core/src/tests/memory.test.d.ts delete mode 100644 packages/core/src/tests/messages.test.d.ts delete mode 100644 packages/core/src/tests/providers.test.d.ts delete mode 100644 packages/core/src/tests/relationships.test.d.ts delete mode 100644 packages/core/src/tests/runtime.test.d.ts delete mode 100644 packages/core/src/tests/time.test.d.ts delete mode 100644 packages/core/src/tests/token.test.d.ts delete mode 100644 packages/core/src/tests/token.test.ts delete mode 100644 packages/core/src/tests/utils.test.ts create mode 100644 packages/test/package.json rename packages/{core => test}/src/test_resources/cache.ts (100%) rename packages/{core => test}/src/test_resources/constants.ts (92%) rename packages/{core => test}/src/test_resources/createRuntime.ts (87%) rename packages/{core => test}/src/test_resources/data.ts (99%) rename packages/{core => test}/src/test_resources/getOrCreateRelationship.ts (100%) rename packages/{core => test}/src/test_resources/populateMemories.ts (96%) rename packages/{core => test}/src/test_resources/report.ts (100%) rename packages/{core => test}/src/test_resources/runAiTest.ts (90%) rename packages/{core => test}/src/test_resources/templates.ts (100%) rename packages/{core => test}/src/test_resources/testAction.ts (93%) rename packages/{core => test}/src/test_resources/testEvaluator.ts (100%) rename packages/{core => test}/src/test_resources/testSetup.ts (88%) rename packages/{core => test}/src/test_resources/types.ts (100%) rename packages/{core => test}/src/tests/actions.test.ts (91%) rename packages/{core/src/test_resources => test/src/tests}/basic.test.ts (100%) create mode 100644 packages/test/src/tests/browser.test.ts create mode 100644 packages/test/src/tests/continue.test.ts rename packages/{core => test}/src/tests/evaluation.test.ts (67%) rename packages/{core => test}/src/tests/fact.test.ts (76%) rename packages/{core => test}/src/tests/goal.test.ts (86%) rename packages/{core => test}/src/tests/goals.test.ts (90%) rename packages/{core => test}/src/tests/ignore.test.ts (86%) rename packages/{core => test}/src/tests/memory.test.ts (95%) rename packages/{core => test}/src/tests/messages.test.ts (85%) rename packages/{core => test}/src/tests/providers.test.ts (87%) rename packages/{core => test}/src/tests/relationships.test.ts (79%) rename packages/{core => test}/src/tests/runtime.test.ts (87%) rename packages/{core => test}/src/tests/time.test.ts (86%) create mode 100644 packages/test/src/tests/token.test.ts create mode 100644 packages/test/src/tests/utils.test.ts create mode 100644 packages/test/tsconfig.json create mode 100644 packages/test/tsup.config.ts diff --git a/packages/adapter-postgres/package.json b/packages/adapter-postgres/package.json index 1e123b8849a..cf10079b926 100644 --- a/packages/adapter-postgres/package.json +++ b/packages/adapter-postgres/package.json @@ -12,7 +12,7 @@ "tsup": "^8.3.5" }, "scripts": { - "build": "echo 'No build step required'", + "build": "tsup --format esm --dts", "dev": "tsup --watch" } } diff --git a/packages/adapter-postgres/src/adapter.ts b/packages/adapter-postgres/src/adapter.ts new file mode 100644 index 00000000000..2f4da22f5ef --- /dev/null +++ b/packages/adapter-postgres/src/adapter.ts @@ -0,0 +1,854 @@ +import { v4 } from "uuid"; +import pg from "pg"; +import { + Account, + Actor, + GoalStatus, + type Goal, + type Memory, + type Relationship, + type UUID, + Participant, +} from "@ai16z/eliza/src/types.ts"; +import { DatabaseAdapter } from "@ai16z/eliza/src/database.ts"; +const { Pool } = pg; + +export class PostgresDatabaseAdapter extends DatabaseAdapter { + private pool: typeof Pool; + + constructor(connectionConfig: any) { + super(); + + this.pool = new Pool({ + ...connectionConfig, + max: 20, + idleTimeoutMillis: 30000, + connectionTimeoutMillis: 2000, + }); + + this.pool.on("error", (err) => { + console.error("Unexpected error on idle client", err); + }); + + this.testConnection(); + } + + async testConnection(): Promise { + let client; + try { + client = await this.pool.connect(); + const result = await client.query("SELECT NOW()"); + console.log("Database connection test successful:", result.rows[0]); + return true; + } catch (error) { + console.error("Database connection test failed:", error); + throw new Error(`Failed to connect to database: ${error.message}`); + } finally { + if (client) client.release(); + } + } + + async getRoom(roomId: UUID): Promise { + const client = await this.pool.connect(); + try { + const { rows } = await client.query( + "SELECT id FROM rooms WHERE id = $1", + [roomId] + ); + return rows.length > 0 ? (rows[0].id as UUID) : null; + } finally { + client.release(); + } + } + + async getParticipantsForAccount(userId: UUID): Promise { + const client = await this.pool.connect(); + try { + const { rows } = await client.query( + `SELECT id, "userId", "roomId", "last_message_read" + FROM participants + WHERE "userId" = $1`, + [userId] + ); + return rows as Participant[]; + } finally { + client.release(); + } + } + + async getParticipantUserState( + roomId: UUID, + userId: UUID + ): Promise<"FOLLOWED" | "MUTED" | null> { + const client = await this.pool.connect(); + try { + const { rows } = await client.query( + `SELECT "userState" FROM participants WHERE "roomId" = $1 AND "userId" = $2`, + [roomId, userId] + ); + return rows.length > 0 ? rows[0].userState : null; + } finally { + client.release(); + } + } + + async getMemoriesByRoomIds(params: { + roomIds: UUID[]; + agentId?: UUID; + tableName: string; + }): Promise { + const client = await this.pool.connect(); + try { + if (params.roomIds.length === 0) return []; + const placeholders = params.roomIds + .map((_, i) => `$${i + 2}`) + .join(", "); + + let query = `SELECT * FROM memories WHERE type = $1 AND "roomId" IN (${placeholders})`; + let queryParams = [params.tableName, ...params.roomIds]; + + if (params.agentId) { + query += ` AND "agentId" = $${params.roomIds.length + 2}`; + queryParams = [...queryParams, params.agentId]; + } + + const { rows } = await client.query(query, queryParams); + return rows.map((row) => ({ + ...row, + content: + typeof row.content === "string" + ? JSON.parse(row.content) + : row.content, + })); + } finally { + client.release(); + } + } + + async setParticipantUserState( + roomId: UUID, + userId: UUID, + state: "FOLLOWED" | "MUTED" | null + ): Promise { + const client = await this.pool.connect(); + try { + await client.query( + `UPDATE participants SET "userState" = $1 WHERE "roomId" = $2 AND "userId" = $3`, + [state, roomId, userId] + ); + } finally { + client.release(); + } + } + + async getParticipantsForRoom(roomId: UUID): Promise { + const client = await this.pool.connect(); + try { + const { rows } = await client.query( + 'SELECT "userId" FROM participants WHERE "roomId" = $1', + [roomId] + ); + return rows.map((row) => row.userId); + } finally { + client.release(); + } + } + + async getAccountById(userId: UUID): Promise { + const client = await this.pool.connect(); + try { + const { rows } = await client.query( + "SELECT * FROM accounts WHERE id = $1", + [userId] + ); + if (rows.length === 0) return null; + + const account = rows[0]; + console.log("account", account); + return { + ...account, + details: + typeof account.details === "string" + ? JSON.parse(account.details) + : account.details, + }; + } finally { + client.release(); + } + } + + async createAccount(account: Account): Promise { + const client = await this.pool.connect(); + try { + await client.query( + `INSERT INTO accounts (id, name, username, email, "avatarUrl", details) + VALUES ($1, $2, $3, $4, $5, $6)`, + [ + account.id ?? v4(), + account.name, + account.username || "", + account.email || "", + account.avatarUrl || "", + JSON.stringify(account.details), + ] + ); + return true; + } catch (error) { + console.log("Error creating account", error); + return false; + } finally { + client.release(); + } + } + + async getActorById(params: { roomId: UUID }): Promise { + const client = await this.pool.connect(); + try { + const { rows } = await client.query( + `SELECT a.id, a.name, a.username, a.details + FROM participants p + LEFT JOIN accounts a ON p."userId" = a.id + WHERE p."roomId" = $1`, + [params.roomId] + ); + return rows.map((row) => ({ + ...row, + details: + typeof row.details === "string" + ? JSON.parse(row.details) + : row.details, + })); + } finally { + client.release(); + } + } + + async getMemoryById(id: UUID): Promise { + const client = await this.pool.connect(); + try { + const { rows } = await client.query( + "SELECT * FROM memories WHERE id = $1", + [id] + ); + if (rows.length === 0) return null; + + return { + ...rows[0], + content: + typeof rows[0].content === "string" + ? JSON.parse(rows[0].content) + : rows[0].content, + }; + } finally { + client.release(); + } + } + + async createMemory(memory: Memory, tableName: string): Promise { + const client = await this.pool.connect(); + try { + let isUnique = true; + if (memory.embedding) { + const similarMemories = await this.searchMemoriesByEmbedding( + memory.embedding, + { + tableName, + roomId: memory.roomId, + match_threshold: 0.95, + count: 1, + } + ); + isUnique = similarMemories.length === 0; + } + + await client.query( + `INSERT INTO memories ( + id, type, content, embedding, "userId", "roomId", "agentId", "unique", "createdAt" + ) VALUES ($1, $2, $3, $4, $5::uuid, $6::uuid, $7::uuid, $8, to_timestamp($9/1000.0))`, + [ + memory.id ?? v4(), + tableName, + JSON.stringify(memory.content), + memory.embedding ? `[${memory.embedding.join(",")}]` : null, + memory.userId, + memory.roomId, + memory.agentId, + memory.unique ?? isUnique, + Date.now(), + ] + ); + } finally { + client.release(); + } + } + + async searchMemories(params: { + tableName: string; + roomId: UUID; + embedding: number[]; + match_threshold: number; + match_count: number; + unique: boolean; + }): Promise { + const client = await this.pool.connect(); + try { + let sql = ` + SELECT *, + 1 - (embedding <-> $3) as similarity + FROM memories + WHERE type = $1 AND "roomId" = $2 + `; + + if (params.unique) { + sql += ` AND "unique" = true`; + } + + sql += ` AND 1 - (embedding <-> $3) >= $4 + ORDER BY embedding <-> $3 + LIMIT $5`; + + const { rows } = await client.query(sql, [ + params.tableName, + params.roomId, + params.embedding, + params.match_threshold, + params.match_count, + ]); + + return rows.map((row) => ({ + ...row, + content: + typeof row.content === "string" + ? JSON.parse(row.content) + : row.content, + similarity: row.similarity, + })); + } finally { + client.release(); + } + } + + async getMemories(params: { + roomId: UUID; + count?: number; + unique?: boolean; + tableName: string; + agentId?: UUID; + start?: number; + end?: number; + }): Promise { + if (!params.tableName) throw new Error("tableName is required"); + if (!params.roomId) throw new Error("roomId is required"); + + const client = await this.pool.connect(); + try { + let sql = `SELECT * FROM memories WHERE type = $1 AND "roomId" = $2`; + const values: any[] = [params.tableName, params.roomId]; + let paramCount = 2; + + if (params.start) { + paramCount++; + sql += ` AND "createdAt" >= to_timestamp($${paramCount})`; + values.push(params.start / 1000); + } + + if (params.end) { + paramCount++; + sql += ` AND "createdAt" <= to_timestamp($${paramCount})`; + values.push(params.end / 1000); + } + + if (params.unique) { + sql += ` AND "unique" = true`; + } + + if (params.agentId) { + paramCount++; + sql += ` AND "agentId" = $${paramCount}`; + values.push(params.agentId); + } + + sql += ' ORDER BY "createdAt" DESC'; + + if (params.count) { + paramCount++; + sql += ` LIMIT $${paramCount}`; + values.push(params.count); + } + + console.log("sql", sql, values); + + const { rows } = await client.query(sql, values); + return rows.map((row) => ({ + ...row, + content: + typeof row.content === "string" + ? JSON.parse(row.content) + : row.content, + })); + } finally { + client.release(); + } + } + + async getGoals(params: { + roomId: UUID; + userId?: UUID | null; + onlyInProgress?: boolean; + count?: number; + }): Promise { + const client = await this.pool.connect(); + try { + let sql = `SELECT * FROM goals WHERE "roomId" = $1`; + const values: any[] = [params.roomId]; + let paramCount = 1; + + if (params.userId) { + paramCount++; + sql += ` AND "userId" = $${paramCount}`; + values.push(params.userId); + } + + if (params.onlyInProgress) { + sql += " AND status = 'IN_PROGRESS'"; + } + + if (params.count) { + paramCount++; + sql += ` LIMIT $${paramCount}`; + values.push(params.count); + } + + const { rows } = await client.query(sql, values); + return rows.map((row) => ({ + ...row, + objectives: + typeof row.objectives === "string" + ? JSON.parse(row.objectives) + : row.objectives, + })); + } finally { + client.release(); + } + } + + async updateGoal(goal: Goal): Promise { + const client = await this.pool.connect(); + try { + await client.query( + `UPDATE goals SET name = $1, status = $2, objectives = $3 WHERE id = $4`, + [ + goal.name, + goal.status, + JSON.stringify(goal.objectives), + goal.id, + ] + ); + } finally { + client.release(); + } + } + + async createGoal(goal: Goal): Promise { + const client = await this.pool.connect(); + try { + await client.query( + `INSERT INTO goals (id, "roomId", "userId", name, status, objectives) + VALUES ($1, $2, $3, $4, $5, $6)`, + [ + goal.id ?? v4(), + goal.roomId, + goal.userId, + goal.name, + goal.status, + JSON.stringify(goal.objectives), + ] + ); + } finally { + client.release(); + } + } + + async removeGoal(goalId: UUID): Promise { + const client = await this.pool.connect(); + try { + await client.query("DELETE FROM goals WHERE id = $1", [goalId]); + } finally { + client.release(); + } + } + + async createRoom(roomId?: UUID): Promise { + const client = await this.pool.connect(); + try { + const newRoomId = roomId || v4(); + await client.query("INSERT INTO rooms (id) VALUES ($1)", [ + newRoomId, + ]); + return newRoomId as UUID; + } finally { + client.release(); + } + } + + async removeRoom(roomId: UUID): Promise { + const client = await this.pool.connect(); + try { + await client.query("DELETE FROM rooms WHERE id = $1", [roomId]); + } finally { + client.release(); + } + } + + async createRelationship(params: { + userA: UUID; + userB: UUID; + }): Promise { + if (!params.userA || !params.userB) { + throw new Error("userA and userB are required"); + } + + const client = await this.pool.connect(); + try { + await client.query( + `INSERT INTO relationships (id, "userA", "userB", "userId") + VALUES ($1, $2, $3, $4)`, + [v4(), params.userA, params.userB, params.userA] + ); + return true; + } catch (error) { + console.log("Error creating relationship", error); + return false; + } finally { + client.release(); + } + } + + async getRelationship(params: { + userA: UUID; + userB: UUID; + }): Promise { + const client = await this.pool.connect(); + try { + const { rows } = await client.query( + `SELECT * FROM relationships + WHERE ("userA" = $1 AND "userB" = $2) OR ("userA" = $2 AND "userB" = $1)`, + [params.userA, params.userB] + ); + return rows.length > 0 ? rows[0] : null; + } finally { + client.release(); + } + } + + async getRelationships(params: { userId: UUID }): Promise { + const client = await this.pool.connect(); + try { + const { rows } = await client.query( + `SELECT * FROM relationships WHERE "userA" = $1 OR "userB" = $1`, + [params.userId] + ); + return rows; + } finally { + client.release(); + } + } + + async getCachedEmbeddings(opts: { + query_table_name: string; + query_threshold: number; + query_input: string; + query_field_name: string; + query_field_sub_name: string; + query_match_count: number; + }): Promise<{ embedding: number[]; levenshtein_score: number }[]> { + const client = await this.pool.connect(); + try { + // Get the JSON field content as text first + const sql = ` + WITH content_text AS ( + SELECT + embedding, + COALESCE( + content->$2->>$3, + '' + ) as content_text + FROM memories + WHERE type = $4 + AND content->$2->>$3 IS NOT NULL + ) + SELECT + embedding, + levenshtein( + $1, + content_text + ) as levenshtein_score + FROM content_text + ORDER BY levenshtein_score + LIMIT $5 + `; + + const { rows } = await client.query(sql, [ + opts.query_input, + opts.query_field_name, + opts.query_field_sub_name, + opts.query_table_name, + opts.query_match_count, + ]); + + return rows.map((row) => ({ + embedding: row.embedding, + levenshtein_score: row.levenshtein_score, + })); + } catch (error) { + console.error("Error in getCachedEmbeddings:", error); + throw error; + } finally { + client.release(); + } + } + + async log(params: { + body: { [key: string]: unknown }; + userId: UUID; + roomId: UUID; + type: string; + }): Promise { + const client = await this.pool.connect(); + try { + await client.query( + `INSERT INTO logs (body, "userId", "roomId", type) + VALUES ($1, $2, $3, $4)`, + [params.body, params.userId, params.roomId, params.type] + ); + } finally { + client.release(); + } + } + + async searchMemoriesByEmbedding( + embedding: number[], + params: { + match_threshold?: number; + count?: number; + agentId?: UUID; + roomId?: UUID; + unique?: boolean; + tableName: string; + } + ): Promise { + const client = await this.pool.connect(); + try { + const vectorStr = `[${embedding.join(",")}]`; + + let sql = ` + SELECT *, + 1 - (embedding <-> $1::vector) as similarity + FROM memories + WHERE type = $2 + `; + + const values: any[] = [vectorStr, params.tableName]; + let paramCount = 2; + + if (params.unique) { + sql += ` AND "unique" = true`; + } + + if (params.agentId) { + paramCount++; + sql += ` AND "agentId" = $${paramCount}`; + values.push(params.agentId); + } + + if (params.roomId) { + paramCount++; + sql += ` AND "roomId" = $${paramCount}::uuid`; + values.push(params.roomId); + } + + if (params.match_threshold) { + paramCount++; + sql += ` AND 1 - (embedding <-> $1::vector) >= $${paramCount}`; + values.push(params.match_threshold); + } + + sql += ` ORDER BY embedding <-> $1::vector`; + + if (params.count) { + paramCount++; + sql += ` LIMIT $${paramCount}`; + values.push(params.count); + } + + const { rows } = await client.query(sql, values); + return rows.map((row) => ({ + ...row, + content: + typeof row.content === "string" + ? JSON.parse(row.content) + : row.content, + similarity: row.similarity, + })); + } finally { + client.release(); + } + } + + async addParticipant(userId: UUID, roomId: UUID): Promise { + const client = await this.pool.connect(); + try { + await client.query( + `INSERT INTO participants (id, "userId", "roomId") + VALUES ($1, $2, $3)`, + [v4(), userId, roomId] + ); + return true; + } catch (error) { + console.log("Error adding participant", error); + return false; + } finally { + client.release(); + } + } + + async removeParticipant(userId: UUID, roomId: UUID): Promise { + const client = await this.pool.connect(); + try { + await client.query( + `DELETE FROM participants WHERE "userId" = $1 AND "roomId" = $2`, + [userId, roomId] + ); + return true; + } catch (error) { + console.log("Error removing participant", error); + return false; + } finally { + client.release(); + } + } + + async updateGoalStatus(params: { + goalId: UUID; + status: GoalStatus; + }): Promise { + const client = await this.pool.connect(); + try { + await client.query("UPDATE goals SET status = $1 WHERE id = $2", [ + params.status, + params.goalId, + ]); + } finally { + client.release(); + } + } + + async removeMemory(memoryId: UUID, tableName: string): Promise { + const client = await this.pool.connect(); + try { + await client.query( + "DELETE FROM memories WHERE type = $1 AND id = $2", + [tableName, memoryId] + ); + } finally { + client.release(); + } + } + + async removeAllMemories(roomId: UUID, tableName: string): Promise { + const client = await this.pool.connect(); + try { + await client.query( + `DELETE FROM memories WHERE type = $1 AND "roomId" = $2`, + [tableName, roomId] + ); + } finally { + client.release(); + } + } + + async countMemories( + roomId: UUID, + unique = true, + tableName = "" + ): Promise { + if (!tableName) throw new Error("tableName is required"); + + const client = await this.pool.connect(); + try { + let sql = `SELECT COUNT(*) as count FROM memories WHERE type = $1 AND "roomId" = $2`; + if (unique) { + sql += ` AND "unique" = true`; + } + + const { rows } = await client.query(sql, [tableName, roomId]); + return parseInt(rows[0].count); + } finally { + client.release(); + } + } + + async removeAllGoals(roomId: UUID): Promise { + const client = await this.pool.connect(); + try { + await client.query(`DELETE FROM goals WHERE "roomId" = $1`, [ + roomId, + ]); + } finally { + client.release(); + } + } + + async getRoomsForParticipant(userId: UUID): Promise { + const client = await this.pool.connect(); + try { + const { rows } = await client.query( + `SELECT "roomId" FROM participants WHERE "userId" = $1`, + [userId] + ); + return rows.map((row) => row.roomId); + } finally { + client.release(); + } + } + + async getRoomsForParticipants(userIds: UUID[]): Promise { + const client = await this.pool.connect(); + try { + const placeholders = userIds.map((_, i) => `$${i + 1}`).join(", "); + const { rows } = await client.query( + `SELECT DISTINCT "roomId" FROM participants WHERE "userId" IN (${placeholders})`, + userIds + ); + return rows.map((row) => row.roomId); + } finally { + client.release(); + } + } + + async getActorDetails(params: { roomId: string }): Promise { + const sql = ` + SELECT + a.id, + a.name, + a.username, + COALESCE(a.details::jsonb, '{}'::jsonb) as details + FROM participants p + LEFT JOIN accounts a ON p."userId" = a.id + WHERE p."roomId" = $1 + `; + + try { + const result = await this.pool.query(sql, [params.roomId]); + return result.rows.map((row) => ({ + ...row, + details: row.details, // PostgreSQL automatically handles JSON parsing + })); + } catch (error) { + console.error("Error fetching actor details:", error); + throw new Error("Failed to fetch actor details"); + } + } +} + +export default PostgresDatabaseAdapter; diff --git a/packages/adapter-postgres/src/index.ts b/packages/adapter-postgres/src/index.ts index 00d61867da7..c6f666bd966 100644 --- a/packages/adapter-postgres/src/index.ts +++ b/packages/adapter-postgres/src/index.ts @@ -1,836 +1 @@ -import { v4 } from "uuid"; -import pg from "pg"; -import { - Account, - Actor, - GoalStatus, - type Goal, - type Memory, - type Relationship, - type UUID, - Participant, -} from "@ai16z/eliza/src/types.ts"; -import { DatabaseAdapter } from "@ai16z/eliza/src/database.ts"; -const { Pool } = pg; - -export class PostgresDatabaseAdapter extends DatabaseAdapter { - private pool: typeof Pool; - - constructor(connectionConfig: any) { - super(); - - this.pool = new Pool({ - ...connectionConfig, - max: 20, - idleTimeoutMillis: 30000, - connectionTimeoutMillis: 2000, - }); - - this.pool.on("error", (err) => { - console.error("Unexpected error on idle client", err); - }); - - this.testConnection(); - } - - async testConnection(): Promise { - let client; - try { - client = await this.pool.connect(); - const result = await client.query("SELECT NOW()"); - console.log("Database connection test successful:", result.rows[0]); - return true; - } catch (error) { - console.error("Database connection test failed:", error); - throw new Error(`Failed to connect to database: ${error.message}`); - } finally { - if (client) client.release(); - } - } - - async getRoom(roomId: UUID): Promise { - const client = await this.pool.connect(); - try { - const { rows } = await client.query( - "SELECT id FROM rooms WHERE id = $1", - [roomId] - ); - return rows.length > 0 ? (rows[0].id as UUID) : null; - } finally { - client.release(); - } - } - - async getParticipantsForAccount(userId: UUID): Promise { - const client = await this.pool.connect(); - try { - const { rows } = await client.query( - `SELECT id, "userId", "roomId", "last_message_read" - FROM participants - WHERE "userId" = $1`, - [userId] - ); - return rows as Participant[]; - } finally { - client.release(); - } - } - - async getParticipantUserState( - roomId: UUID, - userId: UUID - ): Promise<"FOLLOWED" | "MUTED" | null> { - const client = await this.pool.connect(); - try { - const { rows } = await client.query( - `SELECT "userState" FROM participants WHERE "roomId" = $1 AND "userId" = $2`, - [roomId, userId] - ); - return rows.length > 0 ? rows[0].userState : null; - } finally { - client.release(); - } - } - - async getMemoriesByRoomIds(params: { - roomIds: UUID[]; - agentId?: UUID; - tableName: string; - }): Promise { - const client = await this.pool.connect(); - try { - if (params.roomIds.length === 0) return []; - const placeholders = params.roomIds - .map((_, i) => `$${i + 2}`) - .join(", "); - - let query = `SELECT * FROM memories WHERE type = $1 AND "roomId" IN (${placeholders})`; - let queryParams = [params.tableName, ...params.roomIds]; - - if (params.agentId) { - query += ` AND "agentId" = $${params.roomIds.length + 2}`; - queryParams = [...queryParams, params.agentId]; - } - - const { rows } = await client.query(query, queryParams); - return rows.map((row) => ({ - ...row, - content: typeof row.content === "string" ? JSON.parse(row.content) : row.content, - })); - } finally { - client.release(); - } - } - - async setParticipantUserState( - roomId: UUID, - userId: UUID, - state: "FOLLOWED" | "MUTED" | null - ): Promise { - const client = await this.pool.connect(); - try { - await client.query( - `UPDATE participants SET "userState" = $1 WHERE "roomId" = $2 AND "userId" = $3`, - [state, roomId, userId] - ); - } finally { - client.release(); - } - } - - async getParticipantsForRoom(roomId: UUID): Promise { - const client = await this.pool.connect(); - try { - const { rows } = await client.query( - 'SELECT "userId" FROM participants WHERE "roomId" = $1', - [roomId] - ); - return rows.map((row) => row.userId); - } finally { - client.release(); - } - } - - async getAccountById(userId: UUID): Promise { - const client = await this.pool.connect(); - try { - const { rows } = await client.query( - "SELECT * FROM accounts WHERE id = $1", - [userId] - ); - if (rows.length === 0) return null; - - const account = rows[0]; - console.log("account", account); - return { - ...account, - details: typeof account.details === "string" - ? JSON.parse(account.details) - : account.details, - }; - } finally { - client.release(); - } - } - - async createAccount(account: Account): Promise { - const client = await this.pool.connect(); - try { - await client.query( - `INSERT INTO accounts (id, name, username, email, "avatarUrl", details) - VALUES ($1, $2, $3, $4, $5, $6)`, - [ - account.id ?? v4(), - account.name, - account.username || "", - account.email || "", - account.avatarUrl || "", - JSON.stringify(account.details), - ] - ); - return true; - } catch (error) { - console.log("Error creating account", error); - return false; - } finally { - client.release(); - } - } - - async getActorById(params: { roomId: UUID }): Promise { - const client = await this.pool.connect(); - try { - const { rows } = await client.query( - `SELECT a.id, a.name, a.username, a.details - FROM participants p - LEFT JOIN accounts a ON p."userId" = a.id - WHERE p."roomId" = $1`, - [params.roomId] - ); - return rows.map((row) => ({ - ...row, - details: typeof row.details === "string" - ? JSON.parse(row.details) - : row.details, - })); - } finally { - client.release(); - } - } - - async getMemoryById(id: UUID): Promise { - const client = await this.pool.connect(); - try { - const { rows } = await client.query( - "SELECT * FROM memories WHERE id = $1", - [id] - ); - if (rows.length === 0) return null; - - return { - ...rows[0], - content: typeof rows[0].content === "string" - ? JSON.parse(rows[0].content) - : rows[0].content, - }; - } finally { - client.release(); - } - } - - async createMemory(memory: Memory, tableName: string): Promise { - const client = await this.pool.connect(); - try { - let isUnique = true; - if (memory.embedding) { - const similarMemories = await this.searchMemoriesByEmbedding( - memory.embedding, - { - tableName, - roomId: memory.roomId, - match_threshold: 0.95, - count: 1, - } - ); - isUnique = similarMemories.length === 0; - } - - await client.query( - `INSERT INTO memories ( - id, type, content, embedding, "userId", "roomId", "agentId", "unique", "createdAt" - ) VALUES ($1, $2, $3, $4, $5::uuid, $6::uuid, $7::uuid, $8, to_timestamp($9/1000.0))`, - [ - memory.id ?? v4(), - tableName, - JSON.stringify(memory.content), - memory.embedding ? `[${memory.embedding.join(",")}]` : null, - memory.userId, - memory.roomId, - memory.agentId, - memory.unique ?? isUnique, - Date.now(), - ] - ); - } finally { - client.release(); - } - } - - async searchMemories(params: { - tableName: string; - roomId: UUID; - embedding: number[]; - match_threshold: number; - match_count: number; - unique: boolean; - }): Promise { - const client = await this.pool.connect(); - try { - let sql = ` - SELECT *, - 1 - (embedding <-> $3) as similarity - FROM memories - WHERE type = $1 AND "roomId" = $2 - `; - - if (params.unique) { - sql += ` AND "unique" = true`; - } - - sql += ` AND 1 - (embedding <-> $3) >= $4 - ORDER BY embedding <-> $3 - LIMIT $5`; - - const { rows } = await client.query(sql, [ - params.tableName, - params.roomId, - params.embedding, - params.match_threshold, - params.match_count, - ]); - - return rows.map((row) => ({ - ...row, - content: typeof row.content === "string" ? JSON.parse(row.content) : row.content, - similarity: row.similarity, - })); - } finally { - client.release(); - } - } - - async getMemories(params: { - roomId: UUID; - count?: number; - unique?: boolean; - tableName: string; - agentId?: UUID; - start?: number; - end?: number; - }): Promise { - if (!params.tableName) throw new Error("tableName is required"); - if (!params.roomId) throw new Error("roomId is required"); - - const client = await this.pool.connect(); - try { - let sql = `SELECT * FROM memories WHERE type = $1 AND "roomId" = $2`; - const values: any[] = [params.tableName, params.roomId]; - let paramCount = 2; - - if (params.start) { - paramCount++; - sql += ` AND "createdAt" >= to_timestamp($${paramCount})`; - values.push(params.start / 1000); - } - - if (params.end) { - paramCount++; - sql += ` AND "createdAt" <= to_timestamp($${paramCount})`; - values.push(params.end / 1000); - } - - if (params.unique) { - sql += ` AND "unique" = true`; - } - - if (params.agentId) { - paramCount++; - sql += ` AND "agentId" = $${paramCount}`; - values.push(params.agentId); - } - - sql += ' ORDER BY "createdAt" DESC'; - - if (params.count) { - paramCount++; - sql += ` LIMIT $${paramCount}`; - values.push(params.count); - } - - console.log("sql", sql, values); - - const { rows } = await client.query(sql, values); - return rows.map((row) => ({ - ...row, - content: typeof row.content === "string" - ? JSON.parse(row.content) - : row.content, - })); - } finally { - client.release(); - } - } - - async getGoals(params: { - roomId: UUID; - userId?: UUID | null; - onlyInProgress?: boolean; - count?: number; - }): Promise { - const client = await this.pool.connect(); - try { - let sql = `SELECT * FROM goals WHERE "roomId" = $1`; - const values: any[] = [params.roomId]; - let paramCount = 1; - - if (params.userId) { - paramCount++; - sql += ` AND "userId" = $${paramCount}`; - values.push(params.userId); - } - - if (params.onlyInProgress) { - sql += " AND status = 'IN_PROGRESS'"; - } - - if (params.count) { - paramCount++; - sql += ` LIMIT $${paramCount}`; - values.push(params.count); - } - - const { rows } = await client.query(sql, values); - return rows.map((row) => ({ - ...row, - objectives: typeof row.objectives === "string" - ? JSON.parse(row.objectives) - : row.objectives, - })); - } finally { - client.release(); - } - } - - async updateGoal(goal: Goal): Promise { - const client = await this.pool.connect(); - try { - await client.query( - `UPDATE goals SET name = $1, status = $2, objectives = $3 WHERE id = $4`, - [goal.name, goal.status, JSON.stringify(goal.objectives), goal.id] - ); - } finally { - client.release(); - } - } - - async createGoal(goal: Goal): Promise { - const client = await this.pool.connect(); - try { - await client.query( - `INSERT INTO goals (id, "roomId", "userId", name, status, objectives) - VALUES ($1, $2, $3, $4, $5, $6)`, - [ - goal.id ?? v4(), - goal.roomId, - goal.userId, - goal.name, - goal.status, - JSON.stringify(goal.objectives), - ] - ); - } finally { - client.release(); - } - } - - async removeGoal(goalId: UUID): Promise { - const client = await this.pool.connect(); - try { - await client.query("DELETE FROM goals WHERE id = $1", [goalId]); - } finally { - client.release(); - } - } - - async createRoom(roomId?: UUID): Promise { - const client = await this.pool.connect(); - try { - const newRoomId = roomId || v4(); - await client.query("INSERT INTO rooms (id) VALUES ($1)", [newRoomId]); - return newRoomId as UUID; - } finally { - client.release(); - } - } - - async removeRoom(roomId: UUID): Promise { - const client = await this.pool.connect(); - try { - await client.query("DELETE FROM rooms WHERE id = $1", [roomId]); - } finally { - client.release(); - } - } - - async createRelationship(params: { - userA: UUID; - userB: UUID; - }): Promise { - if (!params.userA || !params.userB) { - throw new Error("userA and userB are required"); - } - - const client = await this.pool.connect(); - try { - await client.query( - `INSERT INTO relationships (id, "userA", "userB", "userId") - VALUES ($1, $2, $3, $4)`, - [v4(), params.userA, params.userB, params.userA] - ); - return true; - } catch (error) { - console.log("Error creating relationship", error); - return false; - } finally { - client.release(); - } - } - - async getRelationship(params: { - userA: UUID; - userB: UUID; - }): Promise { - const client = await this.pool.connect(); - try { - const { rows } = await client.query( - `SELECT * FROM relationships - WHERE ("userA" = $1 AND "userB" = $2) OR ("userA" = $2 AND "userB" = $1)`, - [params.userA, params.userB] - ); - return rows.length > 0 ? rows[0] : null; - } finally { - client.release(); - } - } - - async getRelationships(params: { userId: UUID }): Promise { - const client = await this.pool.connect(); - try { - const { rows } = await client.query( - `SELECT * FROM relationships WHERE "userA" = $1 OR "userB" = $1`, - [params.userId] - ); - return rows; - } finally { - client.release(); - } - } - - async getCachedEmbeddings(opts: { - query_table_name: string; - query_threshold: number; - query_input: string; - query_field_name: string; - query_field_sub_name: string; - query_match_count: number; - }): Promise<{ embedding: number[]; levenshtein_score: number }[]> { - const client = await this.pool.connect(); - try { - // Get the JSON field content as text first - const sql = ` - WITH content_text AS ( - SELECT - embedding, - COALESCE( - content->$2->>$3, - '' - ) as content_text - FROM memories - WHERE type = $4 - AND content->$2->>$3 IS NOT NULL - ) - SELECT - embedding, - levenshtein( - $1, - content_text - ) as levenshtein_score - FROM content_text - ORDER BY levenshtein_score - LIMIT $5 - `; - - const { rows } = await client.query(sql, [ - opts.query_input, - opts.query_field_name, - opts.query_field_sub_name, - opts.query_table_name, - opts.query_match_count, - ]); - - return rows.map((row) => ({ - embedding: row.embedding, - levenshtein_score: row.levenshtein_score, - })); - } catch (error) { - console.error('Error in getCachedEmbeddings:', error); - throw error; - } finally { - client.release(); - } - } - - async log(params: { - body: { [key: string]: unknown }; - userId: UUID; - roomId: UUID; - type: string; - }): Promise { - const client = await this.pool.connect(); - try { - await client.query( - `INSERT INTO logs (body, "userId", "roomId", type) - VALUES ($1, $2, $3, $4)`, - [params.body, params.userId, params.roomId, params.type] - ); - } finally { - client.release(); - } - } - - async searchMemoriesByEmbedding( - embedding: number[], - params: { - match_threshold?: number; - count?: number; - agentId?: UUID; - roomId?: UUID; - unique?: boolean; - tableName: string; - } - ): Promise { - const client = await this.pool.connect(); - try { - const vectorStr = `[${embedding.join(",")}]`; - - let sql = ` - SELECT *, - 1 - (embedding <-> $1::vector) as similarity - FROM memories - WHERE type = $2 - `; - - const values: any[] = [vectorStr, params.tableName]; - let paramCount = 2; - - if (params.unique) { - sql += ` AND "unique" = true`; - } - - if (params.agentId) { - paramCount++; - sql += ` AND "agentId" = $${paramCount}`; - values.push(params.agentId); - } - - if (params.roomId) { - paramCount++; - sql += ` AND "roomId" = $${paramCount}::uuid`; - values.push(params.roomId); - } - - if (params.match_threshold) { - paramCount++; - sql += ` AND 1 - (embedding <-> $1::vector) >= $${paramCount}`; - values.push(params.match_threshold); - } - - sql += ` ORDER BY embedding <-> $1::vector`; - - if (params.count) { - paramCount++; - sql += ` LIMIT $${paramCount}`; - values.push(params.count); - } - - const { rows } = await client.query(sql, values); - return rows.map((row) => ({ - ...row, - content: typeof row.content === "string" - ? JSON.parse(row.content) - : row.content, - similarity: row.similarity, - })); - } finally { - client.release(); - } - } - - async addParticipant(userId: UUID, roomId: UUID): Promise { - const client = await this.pool.connect(); - try { - await client.query( - `INSERT INTO participants (id, "userId", "roomId") - VALUES ($1, $2, $3)`, - [v4(), userId, roomId] - ); - return true; - } catch (error) { - console.log("Error adding participant", error); - return false; - } finally { - client.release(); - } - } - - async removeParticipant(userId: UUID, roomId: UUID): Promise { - const client = await this.pool.connect(); - try { - await client.query( - `DELETE FROM participants WHERE "userId" = $1 AND "roomId" = $2`, - [userId, roomId] - ); - return true; - } catch (error) { - console.log("Error removing participant", error); - return false; - } finally { - client.release(); - } - } - - async updateGoalStatus(params: { - goalId: UUID; - status: GoalStatus; - }): Promise { - const client = await this.pool.connect(); - try { - await client.query( - "UPDATE goals SET status = $1 WHERE id = $2", - [params.status, params.goalId] - ); - } finally { - client.release(); - } - } - - async removeMemory(memoryId: UUID, tableName: string): Promise { - const client = await this.pool.connect(); - try { - await client.query( - "DELETE FROM memories WHERE type = $1 AND id = $2", - [tableName, memoryId] - ); - } finally { - client.release(); - } - } - - async removeAllMemories(roomId: UUID, tableName: string): Promise { - const client = await this.pool.connect(); - try { - await client.query( - `DELETE FROM memories WHERE type = $1 AND "roomId" = $2`, - [tableName, roomId] - ); - } finally { - client.release(); - } - } - - async countMemories( - roomId: UUID, - unique = true, - tableName = "" - ): Promise { - if (!tableName) throw new Error("tableName is required"); - - const client = await this.pool.connect(); - try { - let sql = `SELECT COUNT(*) as count FROM memories WHERE type = $1 AND "roomId" = $2`; - if (unique) { - sql += ` AND "unique" = true`; - } - - const { rows } = await client.query(sql, [tableName, roomId]); - return parseInt(rows[0].count); - } finally { - client.release(); - } - } - - async removeAllGoals(roomId: UUID): Promise { - const client = await this.pool.connect(); - try { - await client.query( - `DELETE FROM goals WHERE "roomId" = $1`, - [roomId] - ); - } finally { - client.release(); - } - } - - async getRoomsForParticipant(userId: UUID): Promise { - const client = await this.pool.connect(); - try { - const { rows } = await client.query( - `SELECT "roomId" FROM participants WHERE "userId" = $1`, - [userId] - ); - return rows.map((row) => row.roomId); - } finally { - client.release(); - } - } - - async getRoomsForParticipants(userIds: UUID[]): Promise { - const client = await this.pool.connect(); - try { - const placeholders = userIds.map((_, i) => `$${i + 1}`).join(", "); - const { rows } = await client.query( - `SELECT DISTINCT "roomId" FROM participants WHERE "userId" IN (${placeholders})`, - userIds - ); - return rows.map((row) => row.roomId); - } finally { - client.release(); - } - } - - async getActorDetails(params: { roomId: string }): Promise { - const sql = ` - SELECT - a.id, - a.name, - a.username, - COALESCE(a.details::jsonb, '{}'::jsonb) as details - FROM participants p - LEFT JOIN accounts a ON p."userId" = a.id - WHERE p."roomId" = $1 - `; - - try { - const result = await this.pool.query(sql, [params.roomId]); - return result.rows.map((row) => ({ - ...row, - details: row.details, // PostgreSQL automatically handles JSON parsing - })); - } catch (error) { - console.error("Error fetching actor details:", error); - throw new Error("Failed to fetch actor details"); - } - } -} - -export default PostgresDatabaseAdapter; \ No newline at end of file +export * from "./adapter.ts"; diff --git a/packages/adapter-postgres/tsconfig.json b/packages/adapter-postgres/tsconfig.json new file mode 100644 index 00000000000..eaa78145aa3 --- /dev/null +++ b/packages/adapter-postgres/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src" + }, + "include": ["src"] +} diff --git a/packages/adapter-postgres/tsup.config.ts b/packages/adapter-postgres/tsup.config.ts new file mode 100644 index 00000000000..e42bf4efeae --- /dev/null +++ b/packages/adapter-postgres/tsup.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + outDir: "dist", + sourcemap: true, + clean: true, + format: ["esm"], // Ensure you're targeting CommonJS + external: [ + "dotenv", // Externalize dotenv to prevent bundling + "fs", // Externalize fs to use Node.js built-in module + "path", // Externalize other built-ins if necessary + "@reflink/reflink", + "@node-llama-cpp", + "https", + "http", + "agentkeepalive", + // Add other modules you want to externalize + ], +}); diff --git a/packages/adapter-sqlite/package.json b/packages/adapter-sqlite/package.json index a9ada525d29..c749cdac8d6 100644 --- a/packages/adapter-sqlite/package.json +++ b/packages/adapter-sqlite/package.json @@ -14,7 +14,7 @@ "tsup": "^8.3.5" }, "scripts": { - "build": "echo 'No build step required'", + "build": "tsup --format esm --dts", "dev": "tsup --watch" }, "peerDependencies": { diff --git a/packages/adapter-sqlite/src/adapter.ts b/packages/adapter-sqlite/src/adapter.ts new file mode 100644 index 00000000000..d7ca8b5794e --- /dev/null +++ b/packages/adapter-sqlite/src/adapter.ts @@ -0,0 +1,649 @@ +import { DatabaseAdapter } from "@ai16z/eliza"; +import { embeddingZeroVector } from "@ai16z/eliza"; +import { + Account, + Actor, + GoalStatus, + Participant, + type Goal, + type Memory, + type Relationship, + type UUID, +} from "@ai16z/eliza"; +import { Database } from "better-sqlite3"; +import { v4 } from "uuid"; +import { load } from "./sqlite_vec.ts"; +import { sqliteTables } from "./sqliteTables.ts"; + +export class SqliteDatabaseAdapter extends DatabaseAdapter { + async getRoom(roomId: UUID): Promise { + const sql = "SELECT id FROM rooms WHERE id = ?"; + const room = this.db.prepare(sql).get(roomId) as + | { id: string } + | undefined; + return room ? (room.id as UUID) : null; + } + + async getParticipantsForAccount(userId: UUID): Promise { + const sql = ` + SELECT p.id, p.userId, p.roomId, p.last_message_read + FROM participants p + WHERE p.userId = ? + `; + const rows = this.db.prepare(sql).all(userId) as Participant[]; + return rows; + } + + async getParticipantsForRoom(roomId: UUID): Promise { + const sql = "SELECT userId FROM participants WHERE roomId = ?"; + const rows = this.db.prepare(sql).all(roomId) as { userId: string }[]; + return rows.map((row) => row.userId as UUID); + } + + async getParticipantUserState( + roomId: UUID, + userId: UUID + ): Promise<"FOLLOWED" | "MUTED" | null> { + const stmt = this.db.prepare( + "SELECT userState FROM participants WHERE roomId = ? AND userId = ?" + ); + const res = stmt.get(roomId, userId) as + | { userState: "FOLLOWED" | "MUTED" | null } + | undefined; + return res?.userState ?? null; + } + + async setParticipantUserState( + roomId: UUID, + userId: UUID, + state: "FOLLOWED" | "MUTED" | null + ): Promise { + const stmt = this.db.prepare( + "UPDATE participants SET userState = ? WHERE roomId = ? AND userId = ?" + ); + stmt.run(state, roomId, userId); + } + + constructor(db: Database) { + super(); + this.db = db; + load(db); + + // Check if the 'accounts' table exists as a representative table + const tableExists = this.db + .prepare( + "SELECT name FROM sqlite_master WHERE type='table' AND name='accounts'" + ) + .get(); + + if (!tableExists) { + // If the 'accounts' table doesn't exist, create all the tables + this.db.exec(sqliteTables); + } + } + + async getAccountById(userId: UUID): Promise { + const sql = "SELECT * FROM accounts WHERE id = ?"; + const account = this.db.prepare(sql).get(userId) as Account; + if (!account) return null; + if (account) { + if (typeof account.details === "string") { + account.details = JSON.parse( + account.details as unknown as string + ); + } + } + return account; + } + + async createAccount(account: Account): Promise { + try { + const sql = + "INSERT INTO accounts (id, name, username, email, avatarUrl, details) VALUES (?, ?, ?, ?, ?, ?)"; + this.db + .prepare(sql) + .run( + account.id ?? v4(), + account.name, + account.username, + account.email, + account.avatarUrl, + JSON.stringify(account.details) + ); + return true; + } catch (error) { + console.log("Error creating account", error); + return false; + } + } + + async getActorDetails(params: { roomId: UUID }): Promise { + const sql = ` + SELECT a.id, a.name, a.username, a.details + FROM participants p + LEFT JOIN accounts a ON p.userId = a.id + WHERE p.roomId = ? + `; + const rows = this.db + .prepare(sql) + .all(params.roomId) as (Actor | null)[]; + + return rows + .map((row) => { + if (row === null) { + return null; + } + return { + ...row, + details: + typeof row.details === "string" + ? JSON.parse(row.details) + : row.details, + }; + }) + .filter((row): row is Actor => row !== null); + } + + async getMemoriesByRoomIds(params: { + roomIds: UUID[]; + tableName: string; + agentId?: UUID; + }): Promise { + if (!params.tableName) { + // default to messages + params.tableName = "messages"; + } + const placeholders = params.roomIds.map(() => "?").join(", "); + let sql = `SELECT * FROM memories WHERE type = ? AND roomId IN (${placeholders})`; + let queryParams = [params.tableName, ...params.roomIds]; + + if (params.agentId) { + sql += ` AND agentId = ?`; + queryParams.push(params.agentId); + } + + const stmt = this.db.prepare(sql); + const rows = stmt.all(...queryParams) as (Memory & { + content: string; + })[]; + + return rows.map((row) => ({ + ...row, + content: JSON.parse(row.content), + })); + } + + async getMemoryById(memoryId: UUID): Promise { + const sql = "SELECT * FROM memories WHERE id = ?"; + const stmt = this.db.prepare(sql); + stmt.bind([memoryId]); + const memory = stmt.get() as Memory | undefined; + + if (memory) { + return { + ...memory, + content: JSON.parse(memory.content as unknown as string), + }; + } + + return null; + } + + async createMemory(memory: Memory, tableName: string): Promise { + // Delete any existing memory with the same ID first + const deleteSql = `DELETE FROM memories WHERE id = ? AND type = ?`; + this.db.prepare(deleteSql).run(memory.id, tableName); + + let isUnique = true; + + if (memory.embedding) { + // Check if a similar memory already exists + const similarMemories = await this.searchMemoriesByEmbedding( + memory.embedding, + { + tableName, + roomId: memory.roomId, + match_threshold: 0.95, // 5% similarity threshold + count: 1, + } + ); + + isUnique = similarMemories.length === 0; + } + + const content = JSON.stringify(memory.content); + const createdAt = memory.createdAt ?? Date.now(); + + // Insert the memory with the appropriate 'unique' value + const sql = `INSERT OR REPLACE INTO memories (id, type, content, embedding, userId, roomId, agentId, \`unique\`, createdAt) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`; + this.db.prepare(sql).run( + memory.id ?? v4(), + tableName, + content, + new Float32Array(memory.embedding ?? embeddingZeroVector), // Store as Float32Array + memory.userId, + memory.roomId, + memory.agentId, + isUnique ? 1 : 0, + createdAt + ); + } + + async searchMemories(params: { + tableName: string; + roomId: UUID; + agentId?: UUID; + embedding: number[]; + match_threshold: number; + match_count: number; + unique: boolean; + }): Promise { + const queryParams = [ + new Float32Array(params.embedding), // Ensure embedding is Float32Array + params.tableName, + params.roomId, + params.match_count, + ]; + + let sql = ` + SELECT *, vec_distance_L2(embedding, ?) AS similarity + FROM memories + WHERE type = ?`; + + if (params.unique) { + sql += " AND `unique` = 1"; + } + + if (params.agentId) { + sql += " AND agentId = ?"; + queryParams.push(params.agentId); + } + + sql += ` ORDER BY similarity ASC LIMIT ?`; // ASC for lower distance + // Updated queryParams order matches the placeholders + + const memories = this.db.prepare(sql).all(...queryParams) as (Memory & { + similarity: number; + })[]; + return memories.map((memory) => ({ + ...memory, + createdAt: + typeof memory.createdAt === "string" + ? Date.parse(memory.createdAt as string) + : memory.createdAt, + content: JSON.parse(memory.content as unknown as string), + })); + } + + async searchMemoriesByEmbedding( + embedding: number[], + params: { + match_threshold?: number; + count?: number; + roomId?: UUID; + agentId?: UUID; + unique?: boolean; + tableName: string; + } + ): Promise { + const queryParams = [ + // JSON.stringify(embedding), + new Float32Array(embedding), + params.tableName, + ]; + + let sql = ` + SELECT *, vec_distance_L2(embedding, ?) AS similarity + FROM memories + WHERE type = ?`; + + if (params.unique) { + sql += " AND `unique` = 1"; + } + if (params.agentId) { + sql += " AND agentId = ?"; + queryParams.push(params.agentId); + } + + if (params.roomId) { + sql += " AND roomId = ?"; + queryParams.push(params.roomId); + } + sql += ` ORDER BY similarity DESC`; + + if (params.count) { + sql += " LIMIT ?"; + queryParams.push(params.count.toString()); + } + + const memories = this.db.prepare(sql).all(...queryParams) as (Memory & { + similarity: number; + })[]; + return memories.map((memory) => ({ + ...memory, + createdAt: + typeof memory.createdAt === "string" + ? Date.parse(memory.createdAt as string) + : memory.createdAt, + content: JSON.parse(memory.content as unknown as string), + })); + } + + async getCachedEmbeddings(opts: { + query_table_name: string; + query_threshold: number; + query_input: string; + query_field_name: string; + query_field_sub_name: string; + query_match_count: number; + }): Promise<{ embedding: number[]; levenshtein_score: number }[]> { + const sql = ` + SELECT + embedding, + 0 as levenshtein_score -- Using 0 as placeholder score + FROM memories + WHERE type = ? + AND json_extract(content, '$.' || ? || '.' || ?) IS NOT NULL + LIMIT ? + `; + + const params = [ + opts.query_table_name, + opts.query_field_name, + opts.query_field_sub_name, + opts.query_match_count, + ]; + + const rows = this.db.prepare(sql).all(...params); + + return rows.map((row) => ({ + embedding: row.embedding, + levenshtein_score: 0, + })); + } + + async updateGoalStatus(params: { + goalId: UUID; + status: GoalStatus; + }): Promise { + const sql = "UPDATE goals SET status = ? WHERE id = ?"; + this.db.prepare(sql).run(params.status, params.goalId); + } + + async log(params: { + body: { [key: string]: unknown }; + userId: UUID; + roomId: UUID; + type: string; + }): Promise { + const sql = + "INSERT INTO logs (body, userId, roomId, type) VALUES (?, ?, ?, ?)"; + this.db + .prepare(sql) + .run( + JSON.stringify(params.body), + params.userId, + params.roomId, + params.type + ); + } + + async getMemories(params: { + roomId: UUID; + count?: number; + unique?: boolean; + tableName: string; + agentId?: UUID; + start?: number; + end?: number; + }): Promise { + if (!params.tableName) { + throw new Error("tableName is required"); + } + if (!params.roomId) { + throw new Error("roomId is required"); + } + let sql = `SELECT * FROM memories WHERE type = ? AND roomId = ?`; + + const queryParams = [params.tableName, params.roomId] as any[]; + + if (params.unique) { + sql += " AND `unique` = 1"; + } + + if (params.agentId) { + sql += " AND agentId = ?"; + queryParams.push(params.agentId); + } + + if (params.start) { + sql += ` AND createdAt >= ?`; + queryParams.push(params.start); + } + + if (params.end) { + sql += ` AND createdAt <= ?`; + queryParams.push(params.end); + } + + sql += " ORDER BY createdAt DESC"; + + if (params.count) { + sql += " LIMIT ?"; + queryParams.push(params.count); + } + + const memories = this.db.prepare(sql).all(...queryParams) as Memory[]; + + return memories.map((memory) => ({ + ...memory, + createdAt: + typeof memory.createdAt === "string" + ? Date.parse(memory.createdAt as string) + : memory.createdAt, + content: JSON.parse(memory.content as unknown as string), + })); + } + + async removeMemory(memoryId: UUID, tableName: string): Promise { + const sql = `DELETE FROM memories WHERE type = ? AND id = ?`; + this.db.prepare(sql).run(tableName, memoryId); + } + + async removeAllMemories(roomId: UUID, tableName: string): Promise { + const sql = `DELETE FROM memories WHERE type = ? AND roomId = ?`; + this.db.prepare(sql).run(tableName, roomId); + } + + async countMemories( + roomId: UUID, + unique = true, + tableName = "" + ): Promise { + if (!tableName) { + throw new Error("tableName is required"); + } + + let sql = `SELECT COUNT(*) as count FROM memories WHERE type = ? AND roomId = ?`; + const queryParams = [tableName, roomId] as string[]; + + if (unique) { + sql += " AND `unique` = 1"; + } + + return (this.db.prepare(sql).get(...queryParams) as { count: number }) + .count; + } + + async getGoals(params: { + roomId: UUID; + userId?: UUID | null; + onlyInProgress?: boolean; + count?: number; + }): Promise { + let sql = "SELECT * FROM goals WHERE roomId = ?"; + const queryParams = [params.roomId]; + + if (params.userId) { + sql += " AND userId = ?"; + queryParams.push(params.userId); + } + + if (params.onlyInProgress) { + sql += " AND status = 'IN_PROGRESS'"; + } + + if (params.count) { + sql += " LIMIT ?"; + // @ts-expect-error - queryParams is an array of strings + queryParams.push(params.count.toString()); + } + + const goals = this.db.prepare(sql).all(...queryParams) as Goal[]; + return goals.map((goal) => ({ + ...goal, + objectives: + typeof goal.objectives === "string" + ? JSON.parse(goal.objectives) + : goal.objectives, + })); + } + + async updateGoal(goal: Goal): Promise { + const sql = + "UPDATE goals SET name = ?, status = ?, objectives = ? WHERE id = ?"; + this.db + .prepare(sql) + .run( + goal.name, + goal.status, + JSON.stringify(goal.objectives), + goal.id + ); + } + + async createGoal(goal: Goal): Promise { + const sql = + "INSERT INTO goals (id, roomId, userId, name, status, objectives) VALUES (?, ?, ?, ?, ?, ?)"; + this.db + .prepare(sql) + .run( + goal.id ?? v4(), + goal.roomId, + goal.userId, + goal.name, + goal.status, + JSON.stringify(goal.objectives) + ); + } + + async removeGoal(goalId: UUID): Promise { + const sql = "DELETE FROM goals WHERE id = ?"; + this.db.prepare(sql).run(goalId); + } + + async removeAllGoals(roomId: UUID): Promise { + const sql = "DELETE FROM goals WHERE roomId = ?"; + this.db.prepare(sql).run(roomId); + } + + async createRoom(roomId?: UUID): Promise { + roomId = roomId || (v4() as UUID); + try { + const sql = "INSERT INTO rooms (id) VALUES (?)"; + this.db.prepare(sql).run(roomId ?? (v4() as UUID)); + } catch (error) { + console.log("Error creating room", error); + } + return roomId as UUID; + } + + async removeRoom(roomId: UUID): Promise { + const sql = "DELETE FROM rooms WHERE id = ?"; + this.db.prepare(sql).run(roomId); + } + + async getRoomsForParticipant(userId: UUID): Promise { + const sql = "SELECT roomId FROM participants WHERE userId = ?"; + const rows = this.db.prepare(sql).all(userId) as { roomId: string }[]; + return rows.map((row) => row.roomId as UUID); + } + + async getRoomsForParticipants(userIds: UUID[]): Promise { + // Assuming userIds is an array of UUID strings, prepare a list of placeholders + const placeholders = userIds.map(() => "?").join(", "); + // Construct the SQL query with the correct number of placeholders + const sql = `SELECT DISTINCT roomId FROM participants WHERE userId IN (${placeholders})`; + // Execute the query with the userIds array spread into arguments + const rows = this.db.prepare(sql).all(...userIds) as { + roomId: string; + }[]; + // Map and return the roomId values as UUIDs + return rows.map((row) => row.roomId as UUID); + } + + async addParticipant(userId: UUID, roomId: UUID): Promise { + try { + const sql = + "INSERT INTO participants (id, userId, roomId) VALUES (?, ?, ?)"; + this.db.prepare(sql).run(v4(), userId, roomId); + return true; + } catch (error) { + console.log("Error adding participant", error); + return false; + } + } + + async removeParticipant(userId: UUID, roomId: UUID): Promise { + try { + const sql = + "DELETE FROM participants WHERE userId = ? AND roomId = ?"; + this.db.prepare(sql).run(userId, roomId); + return true; + } catch (error) { + console.log("Error removing participant", error); + return false; + } + } + + async createRelationship(params: { + userA: UUID; + userB: UUID; + }): Promise { + if (!params.userA || !params.userB) { + throw new Error("userA and userB are required"); + } + const sql = + "INSERT INTO relationships (id, userA, userB, userId) VALUES (?, ?, ?, ?)"; + this.db + .prepare(sql) + .run(v4(), params.userA, params.userB, params.userA); + return true; + } + + async getRelationship(params: { + userA: UUID; + userB: UUID; + }): Promise { + const sql = + "SELECT * FROM relationships WHERE (userA = ? AND userB = ?) OR (userA = ? AND userB = ?)"; + return ( + (this.db + .prepare(sql) + .get( + params.userA, + params.userB, + params.userB, + params.userA + ) as Relationship) || null + ); + } + + async getRelationships(params: { userId: UUID }): Promise { + const sql = + "SELECT * FROM relationships WHERE (userA = ? OR userB = ?)"; + return this.db + .prepare(sql) + .all(params.userId, params.userId) as Relationship[]; + } +} diff --git a/packages/adapter-sqlite/src/index.ts b/packages/adapter-sqlite/src/index.ts index 047b8a54672..b35b6c21852 100644 --- a/packages/adapter-sqlite/src/index.ts +++ b/packages/adapter-sqlite/src/index.ts @@ -1,649 +1,3 @@ -import { DatabaseAdapter } from "@ai16z/eliza/src/database.ts"; -import { embeddingZeroVector } from "@ai16z/eliza/src/memory.ts"; -import { - Account, - Actor, - GoalStatus, - Participant, - type Goal, - type Memory, - type Relationship, - type UUID, -} from "@ai16z/eliza/src/types.ts"; -import { Database } from "better-sqlite3"; -import { v4 } from "uuid"; -import { load } from "./sqlite_vec.ts"; -import { sqliteTables } from "./sqliteTables.ts"; - -export class SqliteDatabaseAdapter extends DatabaseAdapter { - async getRoom(roomId: UUID): Promise { - const sql = "SELECT id FROM rooms WHERE id = ?"; - const room = this.db.prepare(sql).get(roomId) as - | { id: string } - | undefined; - return room ? (room.id as UUID) : null; - } - - async getParticipantsForAccount(userId: UUID): Promise { - const sql = ` - SELECT p.id, p.userId, p.roomId, p.last_message_read - FROM participants p - WHERE p.userId = ? - `; - const rows = this.db.prepare(sql).all(userId) as Participant[]; - return rows; - } - - async getParticipantsForRoom(roomId: UUID): Promise { - const sql = "SELECT userId FROM participants WHERE roomId = ?"; - const rows = this.db.prepare(sql).all(roomId) as { userId: string }[]; - return rows.map((row) => row.userId as UUID); - } - - async getParticipantUserState( - roomId: UUID, - userId: UUID - ): Promise<"FOLLOWED" | "MUTED" | null> { - const stmt = this.db.prepare( - "SELECT userState FROM participants WHERE roomId = ? AND userId = ?" - ); - const res = stmt.get(roomId, userId) as - | { userState: "FOLLOWED" | "MUTED" | null } - | undefined; - return res?.userState ?? null; - } - - async setParticipantUserState( - roomId: UUID, - userId: UUID, - state: "FOLLOWED" | "MUTED" | null - ): Promise { - const stmt = this.db.prepare( - "UPDATE participants SET userState = ? WHERE roomId = ? AND userId = ?" - ); - stmt.run(state, roomId, userId); - } - - constructor(db: Database) { - super(); - this.db = db; - load(db); - - // Check if the 'accounts' table exists as a representative table - const tableExists = this.db - .prepare( - "SELECT name FROM sqlite_master WHERE type='table' AND name='accounts'" - ) - .get(); - - if (!tableExists) { - // If the 'accounts' table doesn't exist, create all the tables - this.db.exec(sqliteTables); - } - } - - async getAccountById(userId: UUID): Promise { - const sql = "SELECT * FROM accounts WHERE id = ?"; - const account = this.db.prepare(sql).get(userId) as Account; - if (!account) return null; - if (account) { - if (typeof account.details === "string") { - account.details = JSON.parse( - account.details as unknown as string - ); - } - } - return account; - } - - async createAccount(account: Account): Promise { - try { - const sql = - "INSERT INTO accounts (id, name, username, email, avatarUrl, details) VALUES (?, ?, ?, ?, ?, ?)"; - this.db - .prepare(sql) - .run( - account.id ?? v4(), - account.name, - account.username, - account.email, - account.avatarUrl, - JSON.stringify(account.details) - ); - return true; - } catch (error) { - console.log("Error creating account", error); - return false; - } - } - - async getActorDetails(params: { roomId: UUID }): Promise { - const sql = ` - SELECT a.id, a.name, a.username, a.details - FROM participants p - LEFT JOIN accounts a ON p.userId = a.id - WHERE p.roomId = ? - `; - const rows = this.db - .prepare(sql) - .all(params.roomId) as (Actor | null)[]; - - return rows - .map((row) => { - if (row === null) { - return null; - } - return { - ...row, - details: - typeof row.details === "string" - ? JSON.parse(row.details) - : row.details, - }; - }) - .filter((row): row is Actor => row !== null); - } - - async getMemoriesByRoomIds(params: { - roomIds: UUID[]; - tableName: string; - agentId?: UUID; - }): Promise { - if (!params.tableName) { - // default to messages - params.tableName = "messages"; - } - const placeholders = params.roomIds.map(() => "?").join(", "); - let sql = `SELECT * FROM memories WHERE type = ? AND roomId IN (${placeholders})`; - let queryParams = [params.tableName, ...params.roomIds]; - - if (params.agentId) { - sql += ` AND agentId = ?`; - queryParams.push(params.agentId); - } - - const stmt = this.db.prepare(sql); - const rows = stmt.all(...queryParams) as (Memory & { - content: string; - })[]; - - return rows.map((row) => ({ - ...row, - content: JSON.parse(row.content), - })); - } - - async getMemoryById(memoryId: UUID): Promise { - const sql = "SELECT * FROM memories WHERE id = ?"; - const stmt = this.db.prepare(sql); - stmt.bind([memoryId]); - const memory = stmt.get() as Memory | undefined; - - if (memory) { - return { - ...memory, - content: JSON.parse(memory.content as unknown as string), - }; - } - - return null; - } - - async createMemory(memory: Memory, tableName: string): Promise { - // Delete any existing memory with the same ID first - const deleteSql = `DELETE FROM memories WHERE id = ? AND type = ?`; - this.db.prepare(deleteSql).run(memory.id, tableName); - - let isUnique = true; - - if (memory.embedding) { - // Check if a similar memory already exists - const similarMemories = await this.searchMemoriesByEmbedding( - memory.embedding, - { - tableName, - roomId: memory.roomId, - match_threshold: 0.95, // 5% similarity threshold - count: 1, - } - ); - - isUnique = similarMemories.length === 0; - } - - const content = JSON.stringify(memory.content); - const createdAt = memory.createdAt ?? Date.now(); - - // Insert the memory with the appropriate 'unique' value - const sql = `INSERT OR REPLACE INTO memories (id, type, content, embedding, userId, roomId, agentId, \`unique\`, createdAt) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`; - this.db.prepare(sql).run( - memory.id ?? v4(), - tableName, - content, - new Float32Array(memory.embedding ?? embeddingZeroVector), // Store as Float32Array - memory.userId, - memory.roomId, - memory.agentId, - isUnique ? 1 : 0, - createdAt - ); - } - - async searchMemories(params: { - tableName: string; - roomId: UUID; - agentId?: UUID; - embedding: number[]; - match_threshold: number; - match_count: number; - unique: boolean; - }): Promise { - const queryParams = [ - new Float32Array(params.embedding), // Ensure embedding is Float32Array - params.tableName, - params.roomId, - params.match_count, - ]; - - let sql = ` - SELECT *, vec_distance_L2(embedding, ?) AS similarity - FROM memories - WHERE type = ?`; - - if (params.unique) { - sql += " AND `unique` = 1"; - } - - if (params.agentId) { - sql += " AND agentId = ?"; - queryParams.push(params.agentId); - } - - sql += ` ORDER BY similarity ASC LIMIT ?`; // ASC for lower distance - // Updated queryParams order matches the placeholders - - const memories = this.db.prepare(sql).all(...queryParams) as (Memory & { - similarity: number; - })[]; - return memories.map((memory) => ({ - ...memory, - createdAt: - typeof memory.createdAt === "string" - ? Date.parse(memory.createdAt as string) - : memory.createdAt, - content: JSON.parse(memory.content as unknown as string), - })); - } - - async searchMemoriesByEmbedding( - embedding: number[], - params: { - match_threshold?: number; - count?: number; - roomId?: UUID; - agentId?: UUID; - unique?: boolean; - tableName: string; - } - ): Promise { - const queryParams = [ - // JSON.stringify(embedding), - new Float32Array(embedding), - params.tableName, - ]; - - let sql = ` - SELECT *, vec_distance_L2(embedding, ?) AS similarity - FROM memories - WHERE type = ?`; - - if (params.unique) { - sql += " AND `unique` = 1"; - } - if (params.agentId) { - sql += " AND agentId = ?"; - queryParams.push(params.agentId); - } - - if (params.roomId) { - sql += " AND roomId = ?"; - queryParams.push(params.roomId); - } - sql += ` ORDER BY similarity DESC`; - - if (params.count) { - sql += " LIMIT ?"; - queryParams.push(params.count.toString()); - } - - const memories = this.db.prepare(sql).all(...queryParams) as (Memory & { - similarity: number; - })[]; - return memories.map((memory) => ({ - ...memory, - createdAt: - typeof memory.createdAt === "string" - ? Date.parse(memory.createdAt as string) - : memory.createdAt, - content: JSON.parse(memory.content as unknown as string), - })); - } - - async getCachedEmbeddings(opts: { - query_table_name: string; - query_threshold: number; - query_input: string; - query_field_name: string; - query_field_sub_name: string; - query_match_count: number; - }): Promise<{ embedding: number[]; levenshtein_score: number }[]> { - const sql = ` - SELECT - embedding, - 0 as levenshtein_score -- Using 0 as placeholder score - FROM memories - WHERE type = ? - AND json_extract(content, '$.' || ? || '.' || ?) IS NOT NULL - LIMIT ? - `; - - const params = [ - opts.query_table_name, - opts.query_field_name, - opts.query_field_sub_name, - opts.query_match_count - ]; - - const rows = this.db.prepare(sql).all(...params); - - return rows.map((row) => ({ - embedding: row.embedding, - levenshtein_score: 0 - })); - } - - async updateGoalStatus(params: { - goalId: UUID; - status: GoalStatus; - }): Promise { - const sql = "UPDATE goals SET status = ? WHERE id = ?"; - this.db.prepare(sql).run(params.status, params.goalId); - } - - async log(params: { - body: { [key: string]: unknown }; - userId: UUID; - roomId: UUID; - type: string; - }): Promise { - const sql = - "INSERT INTO logs (body, userId, roomId, type) VALUES (?, ?, ?, ?)"; - this.db - .prepare(sql) - .run( - JSON.stringify(params.body), - params.userId, - params.roomId, - params.type - ); - } - - async getMemories(params: { - roomId: UUID; - count?: number; - unique?: boolean; - tableName: string; - agentId?: UUID; - start?: number; - end?: number; - }): Promise { - if (!params.tableName) { - throw new Error("tableName is required"); - } - if (!params.roomId) { - throw new Error("roomId is required"); - } - let sql = `SELECT * FROM memories WHERE type = ? AND roomId = ?`; - - const queryParams = [params.tableName, params.roomId] as any[]; - - if (params.unique) { - sql += " AND `unique` = 1"; - } - - if (params.agentId) { - sql += " AND agentId = ?"; - queryParams.push(params.agentId); - } - - if (params.start) { - sql += ` AND createdAt >= ?`; - queryParams.push(params.start); - } - - if (params.end) { - sql += ` AND createdAt <= ?`; - queryParams.push(params.end); - } - - sql += " ORDER BY createdAt DESC"; - - if (params.count) { - sql += " LIMIT ?"; - queryParams.push(params.count); - } - - const memories = this.db.prepare(sql).all(...queryParams) as Memory[]; - - return memories.map((memory) => ({ - ...memory, - createdAt: - typeof memory.createdAt === "string" - ? Date.parse(memory.createdAt as string) - : memory.createdAt, - content: JSON.parse(memory.content as unknown as string), - })); - } - - async removeMemory(memoryId: UUID, tableName: string): Promise { - const sql = `DELETE FROM memories WHERE type = ? AND id = ?`; - this.db.prepare(sql).run(tableName, memoryId); - } - - async removeAllMemories(roomId: UUID, tableName: string): Promise { - const sql = `DELETE FROM memories WHERE type = ? AND roomId = ?`; - this.db.prepare(sql).run(tableName, roomId); - } - - async countMemories( - roomId: UUID, - unique = true, - tableName = "" - ): Promise { - if (!tableName) { - throw new Error("tableName is required"); - } - - let sql = `SELECT COUNT(*) as count FROM memories WHERE type = ? AND roomId = ?`; - const queryParams = [tableName, roomId] as string[]; - - if (unique) { - sql += " AND `unique` = 1"; - } - - return (this.db.prepare(sql).get(...queryParams) as { count: number }) - .count; - } - - async getGoals(params: { - roomId: UUID; - userId?: UUID | null; - onlyInProgress?: boolean; - count?: number; - }): Promise { - let sql = "SELECT * FROM goals WHERE roomId = ?"; - const queryParams = [params.roomId]; - - if (params.userId) { - sql += " AND userId = ?"; - queryParams.push(params.userId); - } - - if (params.onlyInProgress) { - sql += " AND status = 'IN_PROGRESS'"; - } - - if (params.count) { - sql += " LIMIT ?"; - // @ts-expect-error - queryParams is an array of strings - queryParams.push(params.count.toString()); - } - - const goals = this.db.prepare(sql).all(...queryParams) as Goal[]; - return goals.map((goal) => ({ - ...goal, - objectives: - typeof goal.objectives === "string" - ? JSON.parse(goal.objectives) - : goal.objectives, - })); - } - - async updateGoal(goal: Goal): Promise { - const sql = - "UPDATE goals SET name = ?, status = ?, objectives = ? WHERE id = ?"; - this.db - .prepare(sql) - .run( - goal.name, - goal.status, - JSON.stringify(goal.objectives), - goal.id - ); - } - - async createGoal(goal: Goal): Promise { - const sql = - "INSERT INTO goals (id, roomId, userId, name, status, objectives) VALUES (?, ?, ?, ?, ?, ?)"; - this.db - .prepare(sql) - .run( - goal.id ?? v4(), - goal.roomId, - goal.userId, - goal.name, - goal.status, - JSON.stringify(goal.objectives) - ); - } - - async removeGoal(goalId: UUID): Promise { - const sql = "DELETE FROM goals WHERE id = ?"; - this.db.prepare(sql).run(goalId); - } - - async removeAllGoals(roomId: UUID): Promise { - const sql = "DELETE FROM goals WHERE roomId = ?"; - this.db.prepare(sql).run(roomId); - } - - async createRoom(roomId?: UUID): Promise { - roomId = roomId || (v4() as UUID); - try { - const sql = "INSERT INTO rooms (id) VALUES (?)"; - this.db.prepare(sql).run(roomId ?? (v4() as UUID)); - } catch (error) { - console.log("Error creating room", error); - } - return roomId as UUID; - } - - async removeRoom(roomId: UUID): Promise { - const sql = "DELETE FROM rooms WHERE id = ?"; - this.db.prepare(sql).run(roomId); - } - - async getRoomsForParticipant(userId: UUID): Promise { - const sql = "SELECT roomId FROM participants WHERE userId = ?"; - const rows = this.db.prepare(sql).all(userId) as { roomId: string }[]; - return rows.map((row) => row.roomId as UUID); - } - - async getRoomsForParticipants(userIds: UUID[]): Promise { - // Assuming userIds is an array of UUID strings, prepare a list of placeholders - const placeholders = userIds.map(() => "?").join(", "); - // Construct the SQL query with the correct number of placeholders - const sql = `SELECT DISTINCT roomId FROM participants WHERE userId IN (${placeholders})`; - // Execute the query with the userIds array spread into arguments - const rows = this.db.prepare(sql).all(...userIds) as { - roomId: string; - }[]; - // Map and return the roomId values as UUIDs - return rows.map((row) => row.roomId as UUID); - } - - async addParticipant(userId: UUID, roomId: UUID): Promise { - try { - const sql = - "INSERT INTO participants (id, userId, roomId) VALUES (?, ?, ?)"; - this.db.prepare(sql).run(v4(), userId, roomId); - return true; - } catch (error) { - console.log("Error adding participant", error); - return false; - } - } - - async removeParticipant(userId: UUID, roomId: UUID): Promise { - try { - const sql = - "DELETE FROM participants WHERE userId = ? AND roomId = ?"; - this.db.prepare(sql).run(userId, roomId); - return true; - } catch (error) { - console.log("Error removing participant", error); - return false; - } - } - - async createRelationship(params: { - userA: UUID; - userB: UUID; - }): Promise { - if (!params.userA || !params.userB) { - throw new Error("userA and userB are required"); - } - const sql = - "INSERT INTO relationships (id, userA, userB, userId) VALUES (?, ?, ?, ?)"; - this.db - .prepare(sql) - .run(v4(), params.userA, params.userB, params.userA); - return true; - } - - async getRelationship(params: { - userA: UUID; - userB: UUID; - }): Promise { - const sql = - "SELECT * FROM relationships WHERE (userA = ? AND userB = ?) OR (userA = ? AND userB = ?)"; - return ( - (this.db - .prepare(sql) - .get( - params.userA, - params.userB, - params.userB, - params.userA - ) as Relationship) || null - ); - } - - async getRelationships(params: { userId: UUID }): Promise { - const sql = - "SELECT * FROM relationships WHERE (userA = ? OR userB = ?)"; - return this.db - .prepare(sql) - .all(params.userId, params.userId) as Relationship[]; - } -} +export * from "./adapter.ts"; +export * from "./sqliteTables.ts"; +export * from "./sqlite_vec.ts"; diff --git a/packages/adapter-sqlite/src/sqlite_vec.ts b/packages/adapter-sqlite/src/sqlite_vec.ts index c033f5ceba1..fa47613bb94 100644 --- a/packages/adapter-sqlite/src/sqlite_vec.ts +++ b/packages/adapter-sqlite/src/sqlite_vec.ts @@ -1,6 +1,6 @@ import * as sqliteVec from "sqlite-vec"; import { Database } from "better-sqlite3"; -import { elizaLogger } from "../../core/src/index.ts"; +import { elizaLogger } from "@ai16z/eliza"; // Loads the sqlite-vec extensions into the provided SQLite database export function loadVecExtensions(db: Database): void { diff --git a/packages/adapter-sqlite/tsconfig.json b/packages/adapter-sqlite/tsconfig.json new file mode 100644 index 00000000000..eaa78145aa3 --- /dev/null +++ b/packages/adapter-sqlite/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src" + }, + "include": ["src"] +} diff --git a/packages/adapter-sqlite/tsup.config.ts b/packages/adapter-sqlite/tsup.config.ts new file mode 100644 index 00000000000..3383002de17 --- /dev/null +++ b/packages/adapter-sqlite/tsup.config.ts @@ -0,0 +1,21 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + outDir: "dist", + sourcemap: true, + clean: true, + format: ["esm"], // Ensure you're targeting CommonJS + external: [ + "dotenv", // Externalize dotenv to prevent bundling + "fs", // Externalize fs to use Node.js built-in module + "path", // Externalize other built-ins if necessary + "@reflink/reflink", + "@node-llama-cpp", + "https", + "http", + "agentkeepalive", + "@anush008/tokenizers", + // Add other modules you want to externalize + ], +}); diff --git a/packages/adapter-sqljs/package.json b/packages/adapter-sqljs/package.json index e771b9a7e56..1dad4ec7050 100644 --- a/packages/adapter-sqljs/package.json +++ b/packages/adapter-sqljs/package.json @@ -14,7 +14,7 @@ "tsup": "^8.3.5" }, "scripts": { - "build": "echo 'No build step required'", + "build": "tsup --format esm --dts", "dev": "tsup --watch" }, "peerDependencies": { diff --git a/packages/adapter-sqljs/src/adapter.ts b/packages/adapter-sqljs/src/adapter.ts new file mode 100644 index 00000000000..6bc01625b21 --- /dev/null +++ b/packages/adapter-sqljs/src/adapter.ts @@ -0,0 +1,746 @@ +import { v4 } from "uuid"; + +import { DatabaseAdapter } from "@ai16z/eliza/src/database.ts"; +import { + Account, + Actor, + GoalStatus, + type Goal, + type Memory, + type Relationship, + type UUID, + Participant, +} from "@ai16z/eliza/src/types.ts"; +import { sqliteTables } from "./sqliteTables.ts"; +import { Database } from "./types.ts"; + +export class SqlJsDatabaseAdapter extends DatabaseAdapter { + async getRoom(roomId: UUID): Promise { + const sql = "SELECT id FROM rooms WHERE id = ?"; + const stmt = this.db.prepare(sql); + stmt.bind([roomId]); + const room = stmt.getAsObject() as { id: string } | undefined; + stmt.free(); + return room ? (room.id as UUID) : null; + } + + async getParticipantsForAccount(userId: UUID): Promise { + const sql = ` + SELECT p.id, p.userId, p.roomId, p.last_message_read + FROM participants p + WHERE p.userId = ? + `; + const stmt = this.db.prepare(sql); + stmt.bind([userId]); + const participants: Participant[] = []; + while (stmt.step()) { + const participant = stmt.getAsObject() as unknown as Participant; + participants.push(participant); + } + stmt.free(); + return participants; + } + + async getParticipantUserState( + roomId: UUID, + userId: UUID + ): Promise<"FOLLOWED" | "MUTED" | null> { + const sql = + "SELECT userState FROM participants WHERE roomId = ? AND userId = ?"; + const stmt = this.db.prepare(sql); + stmt.bind([roomId, userId]); + const result = stmt.getAsObject() as { + userState: "FOLLOWED" | "MUTED" | null; + }; + stmt.free(); + return result.userState ?? null; + } + + async getMemoriesByRoomIds(params: { + roomIds: UUID[]; + tableName: string; + agentId?: UUID; + }): Promise { + const placeholders = params.roomIds.map(() => "?").join(", "); + let sql = `SELECT * FROM memories WHERE type = ? AND roomId IN (${placeholders})`; + const stmt = this.db.prepare(sql); + const queryParams = [params.tableName, ...params.roomIds]; + if (params.agentId) { + sql += " AND userId = ?"; + queryParams.push(params.agentId); + } + stmt.bind(queryParams); + + const memories: Memory[] = []; + while (stmt.step()) { + const memory = stmt.getAsObject() as unknown as Memory; + memories.push({ + ...memory, + content: JSON.parse(memory.content as unknown as string), + }); + } + stmt.free(); + return memories; + } + + async setParticipantUserState( + roomId: UUID, + userId: UUID, + state: "FOLLOWED" | "MUTED" | null + ): Promise { + const sql = + "UPDATE participants SET userState = ? WHERE roomId = ? AND userId = ?"; + const stmt = this.db.prepare(sql); + stmt.bind([state, roomId, userId]); + stmt.step(); + stmt.free(); + } + + async getParticipantsForRoom(roomId: UUID): Promise { + const sql = "SELECT userId FROM participants WHERE roomId = ?"; + const stmt = this.db.prepare(sql); + stmt.bind([roomId]); + const userIds: UUID[] = []; + while (stmt.step()) { + const row = stmt.getAsObject() as { userId: string }; + userIds.push(row.userId as UUID); + } + stmt.free(); + return userIds; + } + + constructor(db: Database) { + super(); + this.db = db; + + // Check if the 'accounts' table exists as a representative table + const tableExists = this.db.exec( + "SELECT name FROM sqlite_master WHERE type='table' AND name='accounts'" + )[0]; + + if (!tableExists) { + // If the 'accounts' table doesn't exist, create all the tables + this.db.exec(sqliteTables); + } + } + + async getAccountById(userId: UUID): Promise { + const sql = "SELECT * FROM accounts WHERE id = ?"; + const stmt = this.db.prepare(sql); + stmt.bind([userId]); + const account = stmt.getAsObject() as unknown as Account | undefined; + + if (account && typeof account.details === "string") { + account.details = JSON.parse(account.details); + } + + stmt.free(); + return account || null; + } + + async createAccount(account: Account): Promise { + try { + const sql = ` + INSERT INTO accounts (id, name, username, email, avatarUrl, details) + VALUES (?, ?, ?, ?, ?, ?) + `; + const stmt = this.db.prepare(sql); + stmt.run([ + account.id ?? v4(), + account.name, + account.username || "", + account.email || "", + account.avatarUrl || "", + JSON.stringify(account.details), + ]); + stmt.free(); + return true; + } catch (error) { + console.log("Error creating account", error); + return false; + } + } + + async getActorById(params: { roomId: UUID }): Promise { + const sql = ` + SELECT a.id, a.name, a.username, a.details + FROM participants p + LEFT JOIN accounts a ON p.userId = a.id + WHERE p.roomId = ? + `; + const stmt = this.db.prepare(sql); + stmt.bind([params.roomId]); + const rows: Actor[] = []; + while (stmt.step()) { + const row = stmt.getAsObject() as unknown as Actor; + rows.push({ + ...row, + details: + typeof row.details === "string" + ? JSON.parse(row.details) + : row.details, + }); + } + stmt.free(); + return rows; + } + + async getActorDetails(params: { roomId: UUID }): Promise { + const sql = ` + SELECT a.id, a.name, a.username, a.details + FROM participants p + LEFT JOIN accounts a ON p.userId = a.id + WHERE p.roomId = ? + `; + const stmt = this.db.prepare(sql); + stmt.bind([params.roomId]); + const rows: Actor[] = []; + while (stmt.step()) { + const row = stmt.getAsObject() as unknown as Actor; + rows.push({ + ...row, + details: + typeof row.details === "string" + ? JSON.parse(row.details) + : row.details, + }); + } + stmt.free(); + return rows; + } + + async getMemoryById(id: UUID): Promise { + const sql = "SELECT * FROM memories WHERE id = ?"; + const stmt = this.db.prepare(sql); + stmt.bind([id]); + const memory = stmt.getAsObject() as unknown as Memory | undefined; + stmt.free(); + return memory || null; + } + + async createMemory(memory: Memory, tableName: string): Promise { + let isUnique = true; + if (memory.embedding) { + // Check if a similar memory already exists + const similarMemories = await this.searchMemoriesByEmbedding( + memory.embedding, + { + tableName, + roomId: memory.roomId, + match_threshold: 0.95, // 5% similarity threshold + count: 1, + } + ); + + isUnique = similarMemories.length === 0; + } + + // Insert the memory with the appropriate 'unique' value + const sql = `INSERT INTO memories (id, type, content, embedding, userId, roomId, agentId, \`unique\`, createdAt) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`; + const stmt = this.db.prepare(sql); + + const createdAt = memory.createdAt ?? Date.now(); + + stmt.run([ + memory.id ?? v4(), + tableName, + JSON.stringify(memory.content), + JSON.stringify(memory.embedding), + memory.userId, + memory.roomId, + memory.agentId, + isUnique ? 1 : 0, + createdAt, + ]); + stmt.free(); + } + + async searchMemories(params: { + tableName: string; + roomId: UUID; + embedding: number[]; + match_threshold: number; + match_count: number; + unique: boolean; + }): Promise { + let sql = + ` + SELECT *` + + // TODO: Uncomment when we compile sql.js with vss + // `, (1 - vss_distance_l2(embedding, ?)) AS similarity` + + ` FROM memories + WHERE type = ? + AND roomId = ?`; + + if (params.unique) { + sql += " AND `unique` = 1"; + } + // TODO: Uncomment when we compile sql.js with vss + // sql += ` ORDER BY similarity DESC LIMIT ?`; + const stmt = this.db.prepare(sql); + stmt.bind([ + // JSON.stringify(params.embedding), + params.tableName, + params.roomId, + // params.match_count, + ]); + const memories: (Memory & { similarity: number })[] = []; + while (stmt.step()) { + const memory = stmt.getAsObject() as unknown as Memory & { + similarity: number; + }; + memories.push({ + ...memory, + content: JSON.parse(memory.content as unknown as string), + }); + } + stmt.free(); + return memories; + } + + async searchMemoriesByEmbedding( + _embedding: number[], + params: { + match_threshold?: number; + count?: number; + roomId?: UUID; + agentId?: UUID; + unique?: boolean; + tableName: string; + } + ): Promise { + let sql = + `SELECT *` + + // TODO: Uncomment when we compile sql.js with vss + // `, (1 - vss_distance_l2(embedding, ?)) AS similarity`+ + ` FROM memories + WHERE type = ?`; + + if (params.unique) { + sql += " AND `unique` = 1"; + } + if (params.roomId) { + sql += " AND roomId = ?"; + } + // TODO: Test this + if (params.agentId) { + sql += " AND userId = ?"; + } + // TODO: Uncomment when we compile sql.js with vss + // sql += ` ORDER BY similarity DESC`; + + if (params.count) { + sql += " LIMIT ?"; + } + + const stmt = this.db.prepare(sql); + const bindings = [ + // JSON.stringify(embedding), + params.tableName, + ]; + if (params.roomId) { + bindings.push(params.roomId); + } + if (params.count) { + bindings.push(params.count.toString()); + } + + stmt.bind(bindings); + const memories: (Memory & { similarity: number })[] = []; + while (stmt.step()) { + const memory = stmt.getAsObject() as unknown as Memory & { + similarity: number; + }; + memories.push({ + ...memory, + content: JSON.parse(memory.content as unknown as string), + }); + } + stmt.free(); + return memories; + } + + async getCachedEmbeddings(opts: { + query_table_name: string; + query_threshold: number; + query_input: string; + query_field_name: string; + query_field_sub_name: string; + query_match_count: number; + }): Promise< + { + embedding: number[]; + levenshtein_score: number; + }[] + > { + const sql = + ` + SELECT * + FROM memories + WHERE type = ?` + + // `AND vss_search(${opts.query_field_name}, ?) + // ORDER BY vss_search(${opts.query_field_name}, ?) DESC` + + ` LIMIT ? + `; + const stmt = this.db.prepare(sql); + stmt.bind([ + opts.query_table_name, + // opts.query_input, + // opts.query_input, + opts.query_match_count, + ]); + const memories: Memory[] = []; + while (stmt.step()) { + const memory = stmt.getAsObject() as unknown as Memory; + memories.push(memory); + } + stmt.free(); + + return memories.map((memory) => ({ + ...memory, + createdAt: memory.createdAt ?? Date.now(), + embedding: JSON.parse(memory.embedding as unknown as string), + levenshtein_score: 0, + })); + } + + async updateGoalStatus(params: { + goalId: UUID; + status: GoalStatus; + }): Promise { + const sql = "UPDATE goals SET status = ? WHERE id = ?"; + const stmt = this.db.prepare(sql); + stmt.run([params.status, params.goalId]); + stmt.free(); + } + + async log(params: { + body: { [key: string]: unknown }; + userId: UUID; + roomId: UUID; + type: string; + }): Promise { + const sql = + "INSERT INTO logs (body, userId, roomId, type) VALUES (?, ?, ?, ?)"; + const stmt = this.db.prepare(sql); + stmt.run([ + JSON.stringify(params.body), + params.userId, + params.roomId, + params.type, + ]); + stmt.free(); + } + + async getMemories(params: { + roomId: UUID; + count?: number; + unique?: boolean; + tableName: string; + agentId?: UUID; + start?: number; + end?: number; + }): Promise { + if (!params.tableName) { + throw new Error("tableName is required"); + } + if (!params.roomId) { + throw new Error("roomId is required"); + } + let sql = `SELECT * FROM memories WHERE type = ? AND roomId = ?`; + + if (params.start) { + sql += ` AND createdAt >= ?`; + } + + if (params.end) { + sql += ` AND createdAt <= ?`; + } + + if (params.unique) { + sql += " AND `unique` = 1"; + } + + if (params.agentId) { + sql += " AND agentId = ?"; + } + + sql += " ORDER BY createdAt DESC"; + + if (params.count) { + sql += " LIMIT ?"; + } + + const stmt = this.db.prepare(sql); + stmt.bind([ + params.tableName, + params.roomId, + ...(params.start ? [params.start] : []), + ...(params.end ? [params.end] : []), + ...(params.agentId ? [params.agentId] : []), + ...(params.count ? [params.count] : []), + ]); + const memories: Memory[] = []; + while (stmt.step()) { + const memory = stmt.getAsObject() as unknown as Memory; + memories.push({ + ...memory, + content: JSON.parse(memory.content as unknown as string), + }); + } + stmt.free(); + return memories; + } + + async removeMemory(memoryId: UUID, tableName: string): Promise { + const sql = `DELETE FROM memories WHERE type = ? AND id = ?`; + const stmt = this.db.prepare(sql); + stmt.run([tableName, memoryId]); + stmt.free(); + } + + async removeAllMemories(roomId: UUID, tableName: string): Promise { + const sql = `DELETE FROM memories WHERE type = ? AND roomId = ?`; + const stmt = this.db.prepare(sql); + stmt.run([tableName, roomId]); + stmt.free(); + } + + async countMemories( + roomId: UUID, + unique = true, + tableName = "" + ): Promise { + if (!tableName) { + throw new Error("tableName is required"); + } + + let sql = `SELECT COUNT(*) as count FROM memories WHERE type = ? AND roomId = ?`; + if (unique) { + sql += " AND `unique` = 1"; + } + + const stmt = this.db.prepare(sql); + stmt.bind([tableName, roomId]); + + let count = 0; + if (stmt.step()) { + const result = stmt.getAsObject() as { count: number }; + count = result.count; + } + + stmt.free(); + return count; + } + + async getGoals(params: { + roomId: UUID; + userId?: UUID | null; + onlyInProgress?: boolean; + count?: number; + }): Promise { + let sql = "SELECT * FROM goals WHERE roomId = ?"; + const bindings: (string | number)[] = [params.roomId]; + + if (params.userId) { + sql += " AND userId = ?"; + bindings.push(params.userId); + } + + if (params.onlyInProgress) { + sql += " AND status = 'IN_PROGRESS'"; + } + + if (params.count) { + sql += " LIMIT ?"; + bindings.push(params.count.toString()); + } + + const stmt = this.db.prepare(sql); + stmt.bind(bindings); + const goals: Goal[] = []; + while (stmt.step()) { + const goal = stmt.getAsObject() as unknown as Goal; + goals.push({ + ...goal, + objectives: + typeof goal.objectives === "string" + ? JSON.parse(goal.objectives) + : goal.objectives, + }); + } + stmt.free(); + return goals; + } + + async updateGoal(goal: Goal): Promise { + const sql = + "UPDATE goals SET name = ?, status = ?, objectives = ? WHERE id = ?"; + const stmt = this.db.prepare(sql); + stmt.run([ + goal.name, + goal.status, + JSON.stringify(goal.objectives), + goal.id as string, + ]); + stmt.free(); + } + + async createGoal(goal: Goal): Promise { + const sql = + "INSERT INTO goals (id, roomId, userId, name, status, objectives) VALUES (?, ?, ?, ?, ?, ?)"; + const stmt = this.db.prepare(sql); + stmt.run([ + goal.id ?? v4(), + goal.roomId, + goal.userId, + goal.name, + goal.status, + JSON.stringify(goal.objectives), + ]); + stmt.free(); + } + + async removeGoal(goalId: UUID): Promise { + const sql = "DELETE FROM goals WHERE id = ?"; + const stmt = this.db.prepare(sql); + stmt.run([goalId]); + stmt.free(); + } + + async removeAllGoals(roomId: UUID): Promise { + const sql = "DELETE FROM goals WHERE roomId = ?"; + const stmt = this.db.prepare(sql); + stmt.run([roomId]); + stmt.free(); + } + + async createRoom(roomId?: UUID): Promise { + roomId = roomId || (v4() as UUID); + try { + const sql = "INSERT INTO rooms (id) VALUES (?)"; + const stmt = this.db.prepare(sql); + stmt.run([roomId ?? (v4() as UUID)]); + stmt.free(); + } catch (error) { + console.log("Error creating room", error); + } + return roomId as UUID; + } + + async removeRoom(roomId: UUID): Promise { + const sql = "DELETE FROM rooms WHERE id = ?"; + const stmt = this.db.prepare(sql); + stmt.run([roomId]); + stmt.free(); + } + + async getRoomsForParticipant(userId: UUID): Promise { + const sql = "SELECT roomId FROM participants WHERE userId = ?"; + const stmt = this.db.prepare(sql); + stmt.bind([userId]); + const rows: { roomId: string }[] = []; + while (stmt.step()) { + const row = stmt.getAsObject() as unknown as { roomId: string }; + rows.push(row); + } + stmt.free(); + return rows.map((row) => row.roomId as UUID); + } + + async getRoomsForParticipants(userIds: UUID[]): Promise { + // Assuming userIds is an array of UUID strings, prepare a list of placeholders + const placeholders = userIds.map(() => "?").join(", "); + // Construct the SQL query with the correct number of placeholders + const sql = `SELECT roomId FROM participants WHERE userId IN (${placeholders})`; + const stmt = this.db.prepare(sql); + // Execute the query with the userIds array spread into arguments + stmt.bind(userIds); + const rows: { roomId: string }[] = []; + while (stmt.step()) { + const row = stmt.getAsObject() as unknown as { roomId: string }; + rows.push(row); + } + stmt.free(); + // Map and return the roomId values as UUIDs + return rows.map((row) => row.roomId as UUID); + } + + async addParticipant(userId: UUID, roomId: UUID): Promise { + try { + const sql = + "INSERT INTO participants (id, userId, roomId) VALUES (?, ?, ?)"; + const stmt = this.db.prepare(sql); + stmt.run([v4(), userId, roomId]); + stmt.free(); + return true; + } catch (error) { + console.log("Error adding participant", error); + return false; + } + } + + async removeParticipant(userId: UUID, roomId: UUID): Promise { + try { + const sql = + "DELETE FROM participants WHERE userId = ? AND roomId = ?"; + const stmt = this.db.prepare(sql); + stmt.run([userId, roomId]); + stmt.free(); + return true; + } catch (error) { + console.log("Error removing participant", error); + return false; + } + } + + async createRelationship(params: { + userA: UUID; + userB: UUID; + }): Promise { + if (!params.userA || !params.userB) { + throw new Error("userA and userB are required"); + } + const sql = + "INSERT INTO relationships (id, userA, userB, userId) VALUES (?, ?, ?, ?)"; + const stmt = this.db.prepare(sql); + stmt.run([v4(), params.userA, params.userB, params.userA]); + stmt.free(); + return true; + } + + async getRelationship(params: { + userA: UUID; + userB: UUID; + }): Promise { + let relationship: Relationship | null = null; + try { + const sql = + "SELECT * FROM relationships WHERE (userA = ? AND userB = ?) OR (userA = ? AND userB = ?)"; + const stmt = this.db.prepare(sql); + stmt.bind([params.userA, params.userB, params.userB, params.userA]); + + if (stmt.step()) { + relationship = stmt.getAsObject() as unknown as Relationship; + } + stmt.free(); + } catch (error) { + console.log("Error fetching relationship", error); + } + return relationship; + } + + async getRelationships(params: { userId: UUID }): Promise { + const sql = + "SELECT * FROM relationships WHERE (userA = ? OR userB = ?)"; + const stmt = this.db.prepare(sql); + stmt.bind([params.userId, params.userId]); + const relationships: Relationship[] = []; + while (stmt.step()) { + const relationship = stmt.getAsObject() as unknown as Relationship; + relationships.push(relationship); + } + stmt.free(); + return relationships; + } +} diff --git a/packages/adapter-sqljs/src/index.ts b/packages/adapter-sqljs/src/index.ts index 6bc01625b21..2262fae9a43 100644 --- a/packages/adapter-sqljs/src/index.ts +++ b/packages/adapter-sqljs/src/index.ts @@ -1,746 +1,3 @@ -import { v4 } from "uuid"; - -import { DatabaseAdapter } from "@ai16z/eliza/src/database.ts"; -import { - Account, - Actor, - GoalStatus, - type Goal, - type Memory, - type Relationship, - type UUID, - Participant, -} from "@ai16z/eliza/src/types.ts"; -import { sqliteTables } from "./sqliteTables.ts"; -import { Database } from "./types.ts"; - -export class SqlJsDatabaseAdapter extends DatabaseAdapter { - async getRoom(roomId: UUID): Promise { - const sql = "SELECT id FROM rooms WHERE id = ?"; - const stmt = this.db.prepare(sql); - stmt.bind([roomId]); - const room = stmt.getAsObject() as { id: string } | undefined; - stmt.free(); - return room ? (room.id as UUID) : null; - } - - async getParticipantsForAccount(userId: UUID): Promise { - const sql = ` - SELECT p.id, p.userId, p.roomId, p.last_message_read - FROM participants p - WHERE p.userId = ? - `; - const stmt = this.db.prepare(sql); - stmt.bind([userId]); - const participants: Participant[] = []; - while (stmt.step()) { - const participant = stmt.getAsObject() as unknown as Participant; - participants.push(participant); - } - stmt.free(); - return participants; - } - - async getParticipantUserState( - roomId: UUID, - userId: UUID - ): Promise<"FOLLOWED" | "MUTED" | null> { - const sql = - "SELECT userState FROM participants WHERE roomId = ? AND userId = ?"; - const stmt = this.db.prepare(sql); - stmt.bind([roomId, userId]); - const result = stmt.getAsObject() as { - userState: "FOLLOWED" | "MUTED" | null; - }; - stmt.free(); - return result.userState ?? null; - } - - async getMemoriesByRoomIds(params: { - roomIds: UUID[]; - tableName: string; - agentId?: UUID; - }): Promise { - const placeholders = params.roomIds.map(() => "?").join(", "); - let sql = `SELECT * FROM memories WHERE type = ? AND roomId IN (${placeholders})`; - const stmt = this.db.prepare(sql); - const queryParams = [params.tableName, ...params.roomIds]; - if (params.agentId) { - sql += " AND userId = ?"; - queryParams.push(params.agentId); - } - stmt.bind(queryParams); - - const memories: Memory[] = []; - while (stmt.step()) { - const memory = stmt.getAsObject() as unknown as Memory; - memories.push({ - ...memory, - content: JSON.parse(memory.content as unknown as string), - }); - } - stmt.free(); - return memories; - } - - async setParticipantUserState( - roomId: UUID, - userId: UUID, - state: "FOLLOWED" | "MUTED" | null - ): Promise { - const sql = - "UPDATE participants SET userState = ? WHERE roomId = ? AND userId = ?"; - const stmt = this.db.prepare(sql); - stmt.bind([state, roomId, userId]); - stmt.step(); - stmt.free(); - } - - async getParticipantsForRoom(roomId: UUID): Promise { - const sql = "SELECT userId FROM participants WHERE roomId = ?"; - const stmt = this.db.prepare(sql); - stmt.bind([roomId]); - const userIds: UUID[] = []; - while (stmt.step()) { - const row = stmt.getAsObject() as { userId: string }; - userIds.push(row.userId as UUID); - } - stmt.free(); - return userIds; - } - - constructor(db: Database) { - super(); - this.db = db; - - // Check if the 'accounts' table exists as a representative table - const tableExists = this.db.exec( - "SELECT name FROM sqlite_master WHERE type='table' AND name='accounts'" - )[0]; - - if (!tableExists) { - // If the 'accounts' table doesn't exist, create all the tables - this.db.exec(sqliteTables); - } - } - - async getAccountById(userId: UUID): Promise { - const sql = "SELECT * FROM accounts WHERE id = ?"; - const stmt = this.db.prepare(sql); - stmt.bind([userId]); - const account = stmt.getAsObject() as unknown as Account | undefined; - - if (account && typeof account.details === "string") { - account.details = JSON.parse(account.details); - } - - stmt.free(); - return account || null; - } - - async createAccount(account: Account): Promise { - try { - const sql = ` - INSERT INTO accounts (id, name, username, email, avatarUrl, details) - VALUES (?, ?, ?, ?, ?, ?) - `; - const stmt = this.db.prepare(sql); - stmt.run([ - account.id ?? v4(), - account.name, - account.username || "", - account.email || "", - account.avatarUrl || "", - JSON.stringify(account.details), - ]); - stmt.free(); - return true; - } catch (error) { - console.log("Error creating account", error); - return false; - } - } - - async getActorById(params: { roomId: UUID }): Promise { - const sql = ` - SELECT a.id, a.name, a.username, a.details - FROM participants p - LEFT JOIN accounts a ON p.userId = a.id - WHERE p.roomId = ? - `; - const stmt = this.db.prepare(sql); - stmt.bind([params.roomId]); - const rows: Actor[] = []; - while (stmt.step()) { - const row = stmt.getAsObject() as unknown as Actor; - rows.push({ - ...row, - details: - typeof row.details === "string" - ? JSON.parse(row.details) - : row.details, - }); - } - stmt.free(); - return rows; - } - - async getActorDetails(params: { roomId: UUID }): Promise { - const sql = ` - SELECT a.id, a.name, a.username, a.details - FROM participants p - LEFT JOIN accounts a ON p.userId = a.id - WHERE p.roomId = ? - `; - const stmt = this.db.prepare(sql); - stmt.bind([params.roomId]); - const rows: Actor[] = []; - while (stmt.step()) { - const row = stmt.getAsObject() as unknown as Actor; - rows.push({ - ...row, - details: - typeof row.details === "string" - ? JSON.parse(row.details) - : row.details, - }); - } - stmt.free(); - return rows; - } - - async getMemoryById(id: UUID): Promise { - const sql = "SELECT * FROM memories WHERE id = ?"; - const stmt = this.db.prepare(sql); - stmt.bind([id]); - const memory = stmt.getAsObject() as unknown as Memory | undefined; - stmt.free(); - return memory || null; - } - - async createMemory(memory: Memory, tableName: string): Promise { - let isUnique = true; - if (memory.embedding) { - // Check if a similar memory already exists - const similarMemories = await this.searchMemoriesByEmbedding( - memory.embedding, - { - tableName, - roomId: memory.roomId, - match_threshold: 0.95, // 5% similarity threshold - count: 1, - } - ); - - isUnique = similarMemories.length === 0; - } - - // Insert the memory with the appropriate 'unique' value - const sql = `INSERT INTO memories (id, type, content, embedding, userId, roomId, agentId, \`unique\`, createdAt) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`; - const stmt = this.db.prepare(sql); - - const createdAt = memory.createdAt ?? Date.now(); - - stmt.run([ - memory.id ?? v4(), - tableName, - JSON.stringify(memory.content), - JSON.stringify(memory.embedding), - memory.userId, - memory.roomId, - memory.agentId, - isUnique ? 1 : 0, - createdAt, - ]); - stmt.free(); - } - - async searchMemories(params: { - tableName: string; - roomId: UUID; - embedding: number[]; - match_threshold: number; - match_count: number; - unique: boolean; - }): Promise { - let sql = - ` - SELECT *` + - // TODO: Uncomment when we compile sql.js with vss - // `, (1 - vss_distance_l2(embedding, ?)) AS similarity` + - ` FROM memories - WHERE type = ? - AND roomId = ?`; - - if (params.unique) { - sql += " AND `unique` = 1"; - } - // TODO: Uncomment when we compile sql.js with vss - // sql += ` ORDER BY similarity DESC LIMIT ?`; - const stmt = this.db.prepare(sql); - stmt.bind([ - // JSON.stringify(params.embedding), - params.tableName, - params.roomId, - // params.match_count, - ]); - const memories: (Memory & { similarity: number })[] = []; - while (stmt.step()) { - const memory = stmt.getAsObject() as unknown as Memory & { - similarity: number; - }; - memories.push({ - ...memory, - content: JSON.parse(memory.content as unknown as string), - }); - } - stmt.free(); - return memories; - } - - async searchMemoriesByEmbedding( - _embedding: number[], - params: { - match_threshold?: number; - count?: number; - roomId?: UUID; - agentId?: UUID; - unique?: boolean; - tableName: string; - } - ): Promise { - let sql = - `SELECT *` + - // TODO: Uncomment when we compile sql.js with vss - // `, (1 - vss_distance_l2(embedding, ?)) AS similarity`+ - ` FROM memories - WHERE type = ?`; - - if (params.unique) { - sql += " AND `unique` = 1"; - } - if (params.roomId) { - sql += " AND roomId = ?"; - } - // TODO: Test this - if (params.agentId) { - sql += " AND userId = ?"; - } - // TODO: Uncomment when we compile sql.js with vss - // sql += ` ORDER BY similarity DESC`; - - if (params.count) { - sql += " LIMIT ?"; - } - - const stmt = this.db.prepare(sql); - const bindings = [ - // JSON.stringify(embedding), - params.tableName, - ]; - if (params.roomId) { - bindings.push(params.roomId); - } - if (params.count) { - bindings.push(params.count.toString()); - } - - stmt.bind(bindings); - const memories: (Memory & { similarity: number })[] = []; - while (stmt.step()) { - const memory = stmt.getAsObject() as unknown as Memory & { - similarity: number; - }; - memories.push({ - ...memory, - content: JSON.parse(memory.content as unknown as string), - }); - } - stmt.free(); - return memories; - } - - async getCachedEmbeddings(opts: { - query_table_name: string; - query_threshold: number; - query_input: string; - query_field_name: string; - query_field_sub_name: string; - query_match_count: number; - }): Promise< - { - embedding: number[]; - levenshtein_score: number; - }[] - > { - const sql = - ` - SELECT * - FROM memories - WHERE type = ?` + - // `AND vss_search(${opts.query_field_name}, ?) - // ORDER BY vss_search(${opts.query_field_name}, ?) DESC` + - ` LIMIT ? - `; - const stmt = this.db.prepare(sql); - stmt.bind([ - opts.query_table_name, - // opts.query_input, - // opts.query_input, - opts.query_match_count, - ]); - const memories: Memory[] = []; - while (stmt.step()) { - const memory = stmt.getAsObject() as unknown as Memory; - memories.push(memory); - } - stmt.free(); - - return memories.map((memory) => ({ - ...memory, - createdAt: memory.createdAt ?? Date.now(), - embedding: JSON.parse(memory.embedding as unknown as string), - levenshtein_score: 0, - })); - } - - async updateGoalStatus(params: { - goalId: UUID; - status: GoalStatus; - }): Promise { - const sql = "UPDATE goals SET status = ? WHERE id = ?"; - const stmt = this.db.prepare(sql); - stmt.run([params.status, params.goalId]); - stmt.free(); - } - - async log(params: { - body: { [key: string]: unknown }; - userId: UUID; - roomId: UUID; - type: string; - }): Promise { - const sql = - "INSERT INTO logs (body, userId, roomId, type) VALUES (?, ?, ?, ?)"; - const stmt = this.db.prepare(sql); - stmt.run([ - JSON.stringify(params.body), - params.userId, - params.roomId, - params.type, - ]); - stmt.free(); - } - - async getMemories(params: { - roomId: UUID; - count?: number; - unique?: boolean; - tableName: string; - agentId?: UUID; - start?: number; - end?: number; - }): Promise { - if (!params.tableName) { - throw new Error("tableName is required"); - } - if (!params.roomId) { - throw new Error("roomId is required"); - } - let sql = `SELECT * FROM memories WHERE type = ? AND roomId = ?`; - - if (params.start) { - sql += ` AND createdAt >= ?`; - } - - if (params.end) { - sql += ` AND createdAt <= ?`; - } - - if (params.unique) { - sql += " AND `unique` = 1"; - } - - if (params.agentId) { - sql += " AND agentId = ?"; - } - - sql += " ORDER BY createdAt DESC"; - - if (params.count) { - sql += " LIMIT ?"; - } - - const stmt = this.db.prepare(sql); - stmt.bind([ - params.tableName, - params.roomId, - ...(params.start ? [params.start] : []), - ...(params.end ? [params.end] : []), - ...(params.agentId ? [params.agentId] : []), - ...(params.count ? [params.count] : []), - ]); - const memories: Memory[] = []; - while (stmt.step()) { - const memory = stmt.getAsObject() as unknown as Memory; - memories.push({ - ...memory, - content: JSON.parse(memory.content as unknown as string), - }); - } - stmt.free(); - return memories; - } - - async removeMemory(memoryId: UUID, tableName: string): Promise { - const sql = `DELETE FROM memories WHERE type = ? AND id = ?`; - const stmt = this.db.prepare(sql); - stmt.run([tableName, memoryId]); - stmt.free(); - } - - async removeAllMemories(roomId: UUID, tableName: string): Promise { - const sql = `DELETE FROM memories WHERE type = ? AND roomId = ?`; - const stmt = this.db.prepare(sql); - stmt.run([tableName, roomId]); - stmt.free(); - } - - async countMemories( - roomId: UUID, - unique = true, - tableName = "" - ): Promise { - if (!tableName) { - throw new Error("tableName is required"); - } - - let sql = `SELECT COUNT(*) as count FROM memories WHERE type = ? AND roomId = ?`; - if (unique) { - sql += " AND `unique` = 1"; - } - - const stmt = this.db.prepare(sql); - stmt.bind([tableName, roomId]); - - let count = 0; - if (stmt.step()) { - const result = stmt.getAsObject() as { count: number }; - count = result.count; - } - - stmt.free(); - return count; - } - - async getGoals(params: { - roomId: UUID; - userId?: UUID | null; - onlyInProgress?: boolean; - count?: number; - }): Promise { - let sql = "SELECT * FROM goals WHERE roomId = ?"; - const bindings: (string | number)[] = [params.roomId]; - - if (params.userId) { - sql += " AND userId = ?"; - bindings.push(params.userId); - } - - if (params.onlyInProgress) { - sql += " AND status = 'IN_PROGRESS'"; - } - - if (params.count) { - sql += " LIMIT ?"; - bindings.push(params.count.toString()); - } - - const stmt = this.db.prepare(sql); - stmt.bind(bindings); - const goals: Goal[] = []; - while (stmt.step()) { - const goal = stmt.getAsObject() as unknown as Goal; - goals.push({ - ...goal, - objectives: - typeof goal.objectives === "string" - ? JSON.parse(goal.objectives) - : goal.objectives, - }); - } - stmt.free(); - return goals; - } - - async updateGoal(goal: Goal): Promise { - const sql = - "UPDATE goals SET name = ?, status = ?, objectives = ? WHERE id = ?"; - const stmt = this.db.prepare(sql); - stmt.run([ - goal.name, - goal.status, - JSON.stringify(goal.objectives), - goal.id as string, - ]); - stmt.free(); - } - - async createGoal(goal: Goal): Promise { - const sql = - "INSERT INTO goals (id, roomId, userId, name, status, objectives) VALUES (?, ?, ?, ?, ?, ?)"; - const stmt = this.db.prepare(sql); - stmt.run([ - goal.id ?? v4(), - goal.roomId, - goal.userId, - goal.name, - goal.status, - JSON.stringify(goal.objectives), - ]); - stmt.free(); - } - - async removeGoal(goalId: UUID): Promise { - const sql = "DELETE FROM goals WHERE id = ?"; - const stmt = this.db.prepare(sql); - stmt.run([goalId]); - stmt.free(); - } - - async removeAllGoals(roomId: UUID): Promise { - const sql = "DELETE FROM goals WHERE roomId = ?"; - const stmt = this.db.prepare(sql); - stmt.run([roomId]); - stmt.free(); - } - - async createRoom(roomId?: UUID): Promise { - roomId = roomId || (v4() as UUID); - try { - const sql = "INSERT INTO rooms (id) VALUES (?)"; - const stmt = this.db.prepare(sql); - stmt.run([roomId ?? (v4() as UUID)]); - stmt.free(); - } catch (error) { - console.log("Error creating room", error); - } - return roomId as UUID; - } - - async removeRoom(roomId: UUID): Promise { - const sql = "DELETE FROM rooms WHERE id = ?"; - const stmt = this.db.prepare(sql); - stmt.run([roomId]); - stmt.free(); - } - - async getRoomsForParticipant(userId: UUID): Promise { - const sql = "SELECT roomId FROM participants WHERE userId = ?"; - const stmt = this.db.prepare(sql); - stmt.bind([userId]); - const rows: { roomId: string }[] = []; - while (stmt.step()) { - const row = stmt.getAsObject() as unknown as { roomId: string }; - rows.push(row); - } - stmt.free(); - return rows.map((row) => row.roomId as UUID); - } - - async getRoomsForParticipants(userIds: UUID[]): Promise { - // Assuming userIds is an array of UUID strings, prepare a list of placeholders - const placeholders = userIds.map(() => "?").join(", "); - // Construct the SQL query with the correct number of placeholders - const sql = `SELECT roomId FROM participants WHERE userId IN (${placeholders})`; - const stmt = this.db.prepare(sql); - // Execute the query with the userIds array spread into arguments - stmt.bind(userIds); - const rows: { roomId: string }[] = []; - while (stmt.step()) { - const row = stmt.getAsObject() as unknown as { roomId: string }; - rows.push(row); - } - stmt.free(); - // Map and return the roomId values as UUIDs - return rows.map((row) => row.roomId as UUID); - } - - async addParticipant(userId: UUID, roomId: UUID): Promise { - try { - const sql = - "INSERT INTO participants (id, userId, roomId) VALUES (?, ?, ?)"; - const stmt = this.db.prepare(sql); - stmt.run([v4(), userId, roomId]); - stmt.free(); - return true; - } catch (error) { - console.log("Error adding participant", error); - return false; - } - } - - async removeParticipant(userId: UUID, roomId: UUID): Promise { - try { - const sql = - "DELETE FROM participants WHERE userId = ? AND roomId = ?"; - const stmt = this.db.prepare(sql); - stmt.run([userId, roomId]); - stmt.free(); - return true; - } catch (error) { - console.log("Error removing participant", error); - return false; - } - } - - async createRelationship(params: { - userA: UUID; - userB: UUID; - }): Promise { - if (!params.userA || !params.userB) { - throw new Error("userA and userB are required"); - } - const sql = - "INSERT INTO relationships (id, userA, userB, userId) VALUES (?, ?, ?, ?)"; - const stmt = this.db.prepare(sql); - stmt.run([v4(), params.userA, params.userB, params.userA]); - stmt.free(); - return true; - } - - async getRelationship(params: { - userA: UUID; - userB: UUID; - }): Promise { - let relationship: Relationship | null = null; - try { - const sql = - "SELECT * FROM relationships WHERE (userA = ? AND userB = ?) OR (userA = ? AND userB = ?)"; - const stmt = this.db.prepare(sql); - stmt.bind([params.userA, params.userB, params.userB, params.userA]); - - if (stmt.step()) { - relationship = stmt.getAsObject() as unknown as Relationship; - } - stmt.free(); - } catch (error) { - console.log("Error fetching relationship", error); - } - return relationship; - } - - async getRelationships(params: { userId: UUID }): Promise { - const sql = - "SELECT * FROM relationships WHERE (userA = ? OR userB = ?)"; - const stmt = this.db.prepare(sql); - stmt.bind([params.userId, params.userId]); - const relationships: Relationship[] = []; - while (stmt.step()) { - const relationship = stmt.getAsObject() as unknown as Relationship; - relationships.push(relationship); - } - stmt.free(); - return relationships; - } -} +export * from "./adapter.ts"; +export * from "./sqliteTables.ts"; +export * from "./types.ts"; diff --git a/packages/adapter-sqljs/tsconfig.json b/packages/adapter-sqljs/tsconfig.json new file mode 100644 index 00000000000..eaa78145aa3 --- /dev/null +++ b/packages/adapter-sqljs/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src" + }, + "include": ["src"] +} diff --git a/packages/adapter-sqljs/tsup.config.ts b/packages/adapter-sqljs/tsup.config.ts new file mode 100644 index 00000000000..e42bf4efeae --- /dev/null +++ b/packages/adapter-sqljs/tsup.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + outDir: "dist", + sourcemap: true, + clean: true, + format: ["esm"], // Ensure you're targeting CommonJS + external: [ + "dotenv", // Externalize dotenv to prevent bundling + "fs", // Externalize fs to use Node.js built-in module + "path", // Externalize other built-ins if necessary + "@reflink/reflink", + "@node-llama-cpp", + "https", + "http", + "agentkeepalive", + // Add other modules you want to externalize + ], +}); diff --git a/packages/adapter-supabase/package.json b/packages/adapter-supabase/package.json index 6e38b636234..24d8f5bc83f 100644 --- a/packages/adapter-supabase/package.json +++ b/packages/adapter-supabase/package.json @@ -12,7 +12,7 @@ "tsup": "^8.3.5" }, "scripts": { - "build": "echo 'No build step required'", + "build": "tsup --format esm --dts", "dev": "tsup --watch" }, "peerDependencies": { diff --git a/packages/adapter-supabase/tsconfig.json b/packages/adapter-supabase/tsconfig.json new file mode 100644 index 00000000000..eaa78145aa3 --- /dev/null +++ b/packages/adapter-supabase/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src" + }, + "include": ["src"] +} diff --git a/packages/adapter-supabase/tsup.config.ts b/packages/adapter-supabase/tsup.config.ts new file mode 100644 index 00000000000..e42bf4efeae --- /dev/null +++ b/packages/adapter-supabase/tsup.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + outDir: "dist", + sourcemap: true, + clean: true, + format: ["esm"], // Ensure you're targeting CommonJS + external: [ + "dotenv", // Externalize dotenv to prevent bundling + "fs", // Externalize fs to use Node.js built-in module + "path", // Externalize other built-ins if necessary + "@reflink/reflink", + "@node-llama-cpp", + "https", + "http", + "agentkeepalive", + // Add other modules you want to externalize + ], +}); diff --git a/packages/agent/tsconfig.json b/packages/agent/tsconfig.json index 9294a4fa6db..ea7ea435e3e 100644 --- a/packages/agent/tsconfig.json +++ b/packages/agent/tsconfig.json @@ -3,8 +3,6 @@ "compilerOptions": { "outDir": "dist", "rootDir": ".", - "module": "ESNext", - "moduleResolution": "Bundler", "types": ["node"] }, "include": ["src"] diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index b1ed027b8cc..d5ca130d4e0 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -17,3 +17,4 @@ export * from "./runtime.ts"; export * from "./settings.ts"; export * from "./types.ts"; export * from "./logger.ts"; +export * from "./uuid.ts"; diff --git a/packages/core/src/tests/actions.test.d.ts b/packages/core/src/tests/actions.test.d.ts deleted file mode 100644 index cb0ff5c3b54..00000000000 --- a/packages/core/src/tests/actions.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/browser.test.ts b/packages/core/src/tests/browser.test.ts deleted file mode 100644 index b8c5d1fc940..00000000000 --- a/packages/core/src/tests/browser.test.ts +++ /dev/null @@ -1,98 +0,0 @@ -import dotenv from "dotenv"; -import { createRuntime } from "../test_resources/createRuntime.ts"; -import { BrowserService } from "./browser.ts"; - -dotenv.config(); - -describe("BrowserService", () => { - let browserService: BrowserService; - - beforeAll(async () => { - const { runtime } = await createRuntime({ - env: process.env as Record, - actions: [], - }); - browserService = BrowserService.getInstance(runtime); - await browserService.initialize(); - }); - - afterAll(async () => { - await browserService.closeBrowser(); - }); - - test("should initialize and close browser", async () => { - const { runtime } = await createRuntime({ - env: process.env as Record, - actions: [], - }); - const newBrowserService = BrowserService.getInstance(runtime); - await expect(newBrowserService.initialize()).resolves.not.toThrow(); - await expect(newBrowserService.closeBrowser()).resolves.not.toThrow(); - }); - - test("should fetch content from a simple website", async () => { - const content = await browserService.getPageContent( - "https://example.com" - ); - expect(content).toContain("Example Domain"); - }, 30000); - - test("should fetch content from a news website", async () => { - const content = await browserService.getPageContent( - "https://news.ycombinator.com" - ); - expect(content).toContain("Hacker News"); - }, 30000); - - test("should handle a website with potential CAPTCHA (GitHub)", async () => { - const content = - await browserService.getPageContent("https://github.com"); - expect(content).toContain("GitHub"); - }, 60000); - - test("should fetch content from a website that might be blocked (Wikipedia)", async () => { - const content = await browserService.getPageContent( - "https://en.wikipedia.org/wiki/Main_Page" - ); - expect(content).toContain("Wikipedia"); - }, 30000); - - test("should handle a 404 error and try alternative sources", async () => { - const content = await browserService.getPageContent( - "https://example.com/nonexistent-page" - ); - expect(content).not.toBe(""); - expect(content).toContain("search"); // Expecting to fall back to a search result - }, 60000); - - test("should handle network errors gracefully", async () => { - await expect( - browserService.getPageContent( - "https://thisisaninvalidurlthatdoesnotexist.com" - ) - ).rejects.toThrow("Failed to fetch content from alternative sources"); - }, 60000); - - test("should block ads on ad-heavy website", async () => { - const content = await browserService.getPageContent( - "https://www.cnn.com" - ); - expect(content).not.toContain("Advertisement"); - }, 60000); - - test("should handle a website with reCAPTCHA", async () => { - const content = await browserService.getPageContent( - "https://www.google.com/recaptcha/api2/demo" - ); - expect(content).toContain("reCAPTCHA"); - // Note: Full CAPTCHA solving can't be reliably tested without manual intervention - }, 60000); - - test("should handle a website with hCAPTCHA", async () => { - const content = await browserService.getPageContent( - "https://accounts.hcaptcha.com/demo" - ); - expect(content).toContain("hCaptcha"); - // Note: Full CAPTCHA solving can't be reliably tested without manual intervention - }, 60000); -}); diff --git a/packages/core/src/tests/continue.test.d.ts b/packages/core/src/tests/continue.test.d.ts deleted file mode 100644 index cb0ff5c3b54..00000000000 --- a/packages/core/src/tests/continue.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/continue.test.ts b/packages/core/src/tests/continue.test.ts deleted file mode 100644 index 07663f9388a..00000000000 --- a/packages/core/src/tests/continue.test.ts +++ /dev/null @@ -1,233 +0,0 @@ -import dotenv from "dotenv"; -import { Content, IAgentRuntime, Memory, type UUID } from "../src/types.ts"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { Goodbye1 } from "../src/test_resources/data.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { populateMemories } from "../src/test_resources/populateMemories.ts"; -import { runAiTest } from "../src/test_resources/runAiTest.ts"; -import { type User } from "../src/test_resources/types.ts"; -import action from "../src/actions/continue.ts"; -import ignore from "../src/actions/ignore.ts"; -import { MemoryManager } from "@ai16z/eliza/src/memory.ts"; - -dotenv.config({ path: ".dev.vars" }); - -const GetContinueExample1 = (_userId: UUID) => [ - { - userId: zeroUuid, - content: { - text: "Hmm, let think for a second, I was going to tell you about something...", - action: "CONTINUE", - }, - }, - { - userId: zeroUuid, - content: { - text: "I remember now, I was going to tell you about my favorite food, which is pizza.", - action: "CONTINUE", - }, - }, - { - userId: zeroUuid, - content: { - text: "I love pizza, it's so delicious.", - action: "CONTINUE", - }, - }, -]; - -describe("User Profile", () => { - let user: User; - let runtime: IAgentRuntime; - let roomId: UUID = zeroUuid; - - afterAll(async () => { - await cleanup(); - }); - - beforeAll(async () => { - const setup = await createRuntime({ - env: process.env as Record, - actions: [action, ignore], - }); - user = setup.session.user; - runtime = setup.runtime; - - const data = await getOrCreateRelationship({ - runtime, - userA: user.id as UUID, - userB: zeroUuid, - }); - - roomId = data.roomId; - - await cleanup(); - }); - - beforeEach(async () => { - await cleanup(); - }); - - async function cleanup() { - const factsManager = new MemoryManager({ - runtime, - tableName: "facts", - }); - - await factsManager.removeAllMemories(roomId); - await runtime.messageManager.removeAllMemories(roomId); - } - - // test validate function response - - test("Test validate function response", async () => { - await runAiTest("Test validate function response", async () => { - const message: Memory = { - userId: user.id as UUID, - content: { text: "Hello" }, - roomId: roomId as UUID, - }; - - const validate = action.validate!; - - const result = await validate(runtime, message); - - // try again with GetContinueExample1, expect to be false - await populateMemories(runtime, user, roomId, [ - GetContinueExample1, - ]); - - const message2: Memory = { - userId: zeroUuid as UUID, - content: { - text: "Hello", - action: "CONTINUE", - }, - roomId: roomId as UUID, - }; - - const result2 = await validate(runtime, message2); - - return result === true && result2 === false; - }); - }, 60000); - - test("Test repetition check on continue", async () => { - await runAiTest("Test repetition check on continue", async () => { - const message: Memory = { - userId: zeroUuid as UUID, - content: { - text: "Hmm, let think for a second, I was going to tell you about something...", - action: "CONTINUE", - }, - roomId, - }; - - const handler = action.handler!; - - await populateMemories(runtime, user, roomId, [ - GetContinueExample1, - ]); - - const result = (await handler(runtime, message)) as Content; - - return result.action !== "CONTINUE"; - }); - }, 60000); - - test("Test multiple continue messages in a conversation", async () => { - await runAiTest( - "Test multiple continue messages in a conversation", - async () => { - const message: Memory = { - userId: user?.id as UUID, - content: { - text: "Write a short story in three parts, using the CONTINUE action for each part.", - }, - roomId: roomId, - }; - - const initialMessageCount = - await runtime.messageManager.countMemories(roomId, false); - - await action.handler!(runtime, message); - - const finalMessageCount = - await runtime.messageManager.countMemories(roomId, false); - - const agentMessages = await runtime.messageManager.getMemories({ - roomId, - agentId: runtime.agentId, - count: finalMessageCount - initialMessageCount, - unique: false, - }); - - const continueMessages = agentMessages.filter( - (m) => - m.userId === zeroUuid && - (m.content as Content).action === "CONTINUE" - ); - - // Check if the agent sent more than one message - const sentMultipleMessages = - finalMessageCount - initialMessageCount > 2; - - // Check if the agent used the CONTINUE action for each part - const usedContinueAction = continueMessages.length === 3; - // Check if the agent's responses are not empty - const responsesNotEmpty = agentMessages.every( - (m) => (m.content as Content).text !== "" - ); - - return ( - sentMultipleMessages && - usedContinueAction && - responsesNotEmpty - ); - } - ); - }, 60000); - - test("Test if message is added to database", async () => { - await runAiTest("Test if message is added to database", async () => { - const message: Memory = { - userId: user?.id as UUID, - content: { - text: "Tell me more about your favorite food.", - }, - roomId: roomId as UUID, - }; - - const initialMessageCount = - await runtime.messageManager.countMemories(roomId, false); - - await action.handler!(runtime, message); - - const finalMessageCount = - await runtime.messageManager.countMemories(roomId, false); - - return finalMessageCount - initialMessageCount === 2; - }); - }, 60000); - test("Test if not continue", async () => { - await runAiTest("Test if not continue", async () => { - // this is basically the same test as the one in ignore.test - const message: Memory = { - userId: user?.id as UUID, - content: { text: "Bye" }, - roomId: roomId as UUID, - }; - - const handler = action.handler!; - - await populateMemories(runtime, user, roomId, [Goodbye1]); - - const result = (await handler(runtime, message)) as Content; - - return result.action === "IGNORE"; - }); - }, 60000); - - // test conditions where we would expect a wait or an ignore -}); diff --git a/packages/core/src/tests/evaluation.test.d.ts b/packages/core/src/tests/evaluation.test.d.ts deleted file mode 100644 index cb0ff5c3b54..00000000000 --- a/packages/core/src/tests/evaluation.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/fact.test.d.ts b/packages/core/src/tests/fact.test.d.ts deleted file mode 100644 index cb0ff5c3b54..00000000000 --- a/packages/core/src/tests/fact.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/goal.test.d.ts b/packages/core/src/tests/goal.test.d.ts deleted file mode 100644 index cb0ff5c3b54..00000000000 --- a/packages/core/src/tests/goal.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/goals.test.d.ts b/packages/core/src/tests/goals.test.d.ts deleted file mode 100644 index cb0ff5c3b54..00000000000 --- a/packages/core/src/tests/goals.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/ignore.test.d.ts b/packages/core/src/tests/ignore.test.d.ts deleted file mode 100644 index cb0ff5c3b54..00000000000 --- a/packages/core/src/tests/ignore.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/memory.test.d.ts b/packages/core/src/tests/memory.test.d.ts deleted file mode 100644 index cb0ff5c3b54..00000000000 --- a/packages/core/src/tests/memory.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/messages.test.d.ts b/packages/core/src/tests/messages.test.d.ts deleted file mode 100644 index cb0ff5c3b54..00000000000 --- a/packages/core/src/tests/messages.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/providers.test.d.ts b/packages/core/src/tests/providers.test.d.ts deleted file mode 100644 index cb0ff5c3b54..00000000000 --- a/packages/core/src/tests/providers.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/relationships.test.d.ts b/packages/core/src/tests/relationships.test.d.ts deleted file mode 100644 index cb0ff5c3b54..00000000000 --- a/packages/core/src/tests/relationships.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/runtime.test.d.ts b/packages/core/src/tests/runtime.test.d.ts deleted file mode 100644 index cb0ff5c3b54..00000000000 --- a/packages/core/src/tests/runtime.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/time.test.d.ts b/packages/core/src/tests/time.test.d.ts deleted file mode 100644 index cb0ff5c3b54..00000000000 --- a/packages/core/src/tests/time.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/token.test.d.ts b/packages/core/src/tests/token.test.d.ts deleted file mode 100644 index cb0ff5c3b54..00000000000 --- a/packages/core/src/tests/token.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/packages/core/src/tests/token.test.ts b/packages/core/src/tests/token.test.ts deleted file mode 100644 index 46abfe6f8a1..00000000000 --- a/packages/core/src/tests/token.test.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { createRuntime } from "../src/test_resources/createRuntime"; -import { TokenProvider } from "../src/providers/token"; -import NodeCache from "node-cache"; - -// Mock the dependencies -jest.mock("cross-fetch"); -jest.mock("fs"); -jest.mock("node-cache"); - -describe("TokenProvider Tests", () => { - // let connection: Connection; - let tokenProvider: TokenProvider; - - beforeEach(() => { - // Initialize the connection and token provider before each test - // connection = new Connection("https://api.mainnet-beta.solana.com"); - tokenProvider = new TokenProvider( - "2weMjPLLybRMMva1fM3U31goWWrCpF59CHWNhnCJ9Vyh" - ); - }); - - test("should fetch token security data", async () => { - const { runtime } = await createRuntime({ - conversationLength: 10, - }); - - // Mock the response for the fetchTokenSecurity call - const mockFetchResponse = { - success: true, - data: { - ownerBalance: "100", - creatorBalance: "50", - ownerPercentage: 10, - creatorPercentage: 5, - top10HolderBalance: "200", - top10HolderPercent: 20, - }, - }; - - // Mock fetchWithRetry function - const fetchSpy = jest - .spyOn(tokenProvider as any, "fetchWithRetry") - .mockResolvedValue(mockFetchResponse); - - // Run the fetchTokenSecurity method - // const securityData = await tokenProvider.fetchTokenSecurity(); - - // Check if the data returned is correct - // expect(securityData).toEqual({ - // ownerBalance: "100", - // creatorBalance: "50", - // ownerPercentage: 10, - // creatorPercentage: 5, - // top10HolderBalance: "200", - // top10HolderPercent: 20, - // }); - //console.log the securityData - // console.log({ securityData }); - - // const holderList = await tokenProvider.fetchHolderList(); - - // console.log({ holderList }); - - // const tradeData = await tokenProvider.fetchTokenTradeData(); - // console.log({ tradeData }); - - // const dexScreenerData = await tokenProvider.fetchDexScreenerData(); - // console.log({ dexScreenerData }); - - const tokenReport = - await tokenProvider.getFormattedTokenReport(runtime); - console.log({ tokenReport }); - - // Ensure the mock was called - expect(fetchSpy).toHaveBeenCalled(); - }); -}); diff --git a/packages/core/src/tests/utils.test.ts b/packages/core/src/tests/utils.test.ts deleted file mode 100644 index a7d4888899b..00000000000 --- a/packages/core/src/tests/utils.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -import Database from "better-sqlite3"; -import fs from "fs"; -import path from "path"; -import { fileURLToPath } from "url"; -import { TwitterInteractionClient } from "../src/clients/twitter/interactions.ts"; -import { SqliteDatabaseAdapter } from "../src/adapters/sqlite.ts"; -import { defaultCharacter } from "../src/defaultCharacter.ts"; -import { buildConversationThread } from "../src/clients/twitter/utils.ts"; -import { AgentRuntime } from "../src/runtime.ts"; -import settings from "../src/settings.ts"; -import { ModelProviderName } from "../src/types.ts"; - -// const __dirname = path.dirname(new URL(".", import.meta.url).pathname); - -const __dirname = path.dirname(fileURLToPath(import.meta.url)); - -describe("buildConversationThread", () => { - let runtime: AgentRuntime; - let client: TwitterInteractionClient; - - beforeAll(async () => { - // Create an instance of the AgentRuntime - runtime = new AgentRuntime({ - databaseAdapter: new SqliteDatabaseAdapter( - new Database(":memory:") - ), - token: settings.OPENAI_API_KEY as string, - evaluators: [], - modelProvider: ModelProviderName.OPENAI, - character: defaultCharacter, - providers: [], - actions: [], - }); - - // Create an instance of the TwitterPostClient - client = new TwitterInteractionClient(runtime); - - // Load cached Twitter credentials - const cookiesFilePath = path.join( - __dirname, - "../../../tweetcache/" + - runtime.getSetting("TWITTER_USERNAME") + - "_cookies.json" - ); - console.log("Cookies file path:", cookiesFilePath); - if (fs.existsSync(cookiesFilePath)) { - const cookiesArray = JSON.parse( - fs.readFileSync(cookiesFilePath, "utf-8") - ); - client.setCookiesFromArray(cookiesArray); - } else { - throw new Error( - "Twitter credentials not found. Please provide valid cookies.json." - ); - } - }); - - it("should build a conversation thread from a tweet ID", async () => { - const tweetId = "1830058678197895517"; - - // Fetch the tweet from the API - const tweet = await client.getTweet(tweetId); - console.log("Original tweet:", JSON.stringify(tweet, null, 2)); - - // Build the conversation thread - const thread = await buildConversationThread(tweet, client); - - console.log("Generated conversation thread:"); - console.log(thread); - - // Add assertions based on the expected structure and content of the thread - // expect(thread.includes("By: Aya Bochman (@ayaboch)")).toBe(true); - // expect(thread.includes("@ayaboch @DanBochman You should do nothing. Its opensource code, you have too much to lose by fighting this fight, this post will get u blacklisted be aware")).toBe(true); - // expect(thread.includes("@BLUECOW009 @ayaboch @DanBochman That's not how it works")).toBe(true); - }, 30000); -}); diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 84cf46532cd..02e95cf8df5 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -4,23 +4,8 @@ "target": "ESNext", "module": "ESNext", "lib": ["ESNext", "dom"], - "moduleResolution": "Bundler", "outDir": "./dist", "rootDir": "./src", - "strict": false, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": false, - "allowImportingTsExtensions": true, - "declaration": true, - "emitDeclarationOnly": true, - "resolveJsonModule": true, - "noImplicitAny": false, - "allowJs": true, - "checkJs": false, - "noEmitOnError": false, - "moduleDetection": "force", - "allowArbitraryExtensions": true, "typeRoots": [ "./node_modules/@types", "./types", @@ -28,5 +13,5 @@ ] }, "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "src/**/*.d.ts", "types/**/*.test.ts"] + "exclude": ["node_modules", "dist"] } diff --git a/packages/plugin-bootstrap/src/index.ts b/packages/plugin-bootstrap/src/index.ts index 439265fdebb..9d873a22fb1 100644 --- a/packages/plugin-bootstrap/src/index.ts +++ b/packages/plugin-bootstrap/src/index.ts @@ -1,4 +1,8 @@ -import { Plugin } from "@ai16z/eliza/src/types.ts"; +export * from "./actions/index.ts"; +export * from "./evaluators/index.ts"; +export * from "./providers/index.ts"; + +import { Plugin } from "@ai16z/eliza"; import { continueAction } from "./actions/continue.ts"; import { followRoomAction } from "./actions/followRoom.ts"; import { ignoreAction } from "./actions/ignore.ts"; diff --git a/packages/plugin-bootstrap/tsconfig.json b/packages/plugin-bootstrap/tsconfig.json index 9294a4fa6db..ea7ea435e3e 100644 --- a/packages/plugin-bootstrap/tsconfig.json +++ b/packages/plugin-bootstrap/tsconfig.json @@ -3,8 +3,6 @@ "compilerOptions": { "outDir": "dist", "rootDir": ".", - "module": "ESNext", - "moduleResolution": "Bundler", "types": ["node"] }, "include": ["src"] diff --git a/packages/plugin-image-generation/tsconfig.json b/packages/plugin-image-generation/tsconfig.json index 9294a4fa6db..ea7ea435e3e 100644 --- a/packages/plugin-image-generation/tsconfig.json +++ b/packages/plugin-image-generation/tsconfig.json @@ -3,8 +3,6 @@ "compilerOptions": { "outDir": "dist", "rootDir": ".", - "module": "ESNext", - "moduleResolution": "Bundler", "types": ["node"] }, "include": ["src"] diff --git a/packages/plugin-node/src/index.ts b/packages/plugin-node/src/index.ts index 1f1f694a38e..95f1b3e733c 100644 --- a/packages/plugin-node/src/index.ts +++ b/packages/plugin-node/src/index.ts @@ -1,3 +1,11 @@ +export * from "./services/browser.ts"; +export * from "./services/image.ts"; +export * from "./services/llama.ts"; +export * from "./services/pdf.ts"; +export * from "./services/speech.ts"; +export * from "./services/transcription.ts"; +export * from "./services/video.ts"; + import { Plugin } from "@ai16z/eliza/src/types.ts"; import { BrowserService } from "./services/browser.ts"; import { ImageDescriptionService } from "./services/image.ts"; diff --git a/packages/plugin-node/tsconfig.json b/packages/plugin-node/tsconfig.json index 9294a4fa6db..ea7ea435e3e 100644 --- a/packages/plugin-node/tsconfig.json +++ b/packages/plugin-node/tsconfig.json @@ -3,8 +3,6 @@ "compilerOptions": { "outDir": "dist", "rootDir": ".", - "module": "ESNext", - "moduleResolution": "Bundler", "types": ["node"] }, "include": ["src"] diff --git a/packages/plugin-solana/src/index.ts b/packages/plugin-solana/src/index.ts index 440b557f24a..dc65ac0bf88 100644 --- a/packages/plugin-solana/src/index.ts +++ b/packages/plugin-solana/src/index.ts @@ -1,3 +1,5 @@ +export * from "./providers/token.ts"; + import { Plugin } from "@ai16z/eliza/src/types.ts"; // import { executeSwap } from "./actions/swap.ts"; // import take_order from "./actions/takeOrder"; @@ -16,9 +18,7 @@ export const solanaPlugin: Plugin = { // executeSwapForDAO, // take_order, ], - evaluators: [ - trustEvaluator - ], + evaluators: [trustEvaluator], providers: [walletProvider, trustScoreProvider], }; diff --git a/packages/test/package.json b/packages/test/package.json new file mode 100644 index 00000000000..70e42406c82 --- /dev/null +++ b/packages/test/package.json @@ -0,0 +1,31 @@ +{ + "name": "@ai16z/plugin-solana", + "version": "0.0.1", + "main": "dist/index.js", + "type": "module", + "types": "dist/index.d.ts", + "dependencies": { + "@ai16z/eliza": "workspace:*", + "@ai16z/plugin-solana": "workspace:*", + "@ai16z/plugin-node": "workspace:*", + "@ai16z/plugin-bootstrap": "workspace:*", + "@ai16z/adapter-sqljs": "workspace:*", + "@ai16z/adapter-supabase": "workspace:*", + "@ai16z/adapter-sqlite": "workspace:*", + "tsup": "^8.3.5", + "@solana/spl-token": "0.4.9", + "@solana/web3.js": "1.95.4", + "@coral-xyz/anchor": "^0.30.1", + "bignumber": "1.1.0", + "bignumber.js": "9.1.2", + "pumpdotfun-sdk": "1.3.2", + "node-cache": "5.1.2" + }, + "scripts": { + "test": "jest --runInBand", + "test:watch": "jest --runInBand --watch" + }, + "peerDependencies": { + "whatwg-url": "7.1.0" + } +} diff --git a/packages/core/src/test_resources/cache.ts b/packages/test/src/test_resources/cache.ts similarity index 100% rename from packages/core/src/test_resources/cache.ts rename to packages/test/src/test_resources/cache.ts diff --git a/packages/core/src/test_resources/constants.ts b/packages/test/src/test_resources/constants.ts similarity index 92% rename from packages/core/src/test_resources/constants.ts rename to packages/test/src/test_resources/constants.ts index f60b632a03f..abe8802e38a 100644 --- a/packages/core/src/test_resources/constants.ts +++ b/packages/test/src/test_resources/constants.ts @@ -1,4 +1,4 @@ -import { type UUID } from "@ai16z/eliza/src/types.ts"; +import { type UUID } from "@ai16z/eliza"; export const SERVER_URL = "http://localhost:7998"; export const SUPABASE_URL = "https://pronvzrzfwsptkojvudd.supabase.co"; diff --git a/packages/core/src/test_resources/createRuntime.ts b/packages/test/src/test_resources/createRuntime.ts similarity index 87% rename from packages/core/src/test_resources/createRuntime.ts rename to packages/test/src/test_resources/createRuntime.ts index a9c98ddcf75..878bb6f186b 100644 --- a/packages/core/src/test_resources/createRuntime.ts +++ b/packages/test/src/test_resources/createRuntime.ts @@ -1,23 +1,18 @@ -import { SqliteDatabaseAdapter } from "../adapters/sqlite.ts"; -import { load } from "../../../adapter-sqlite/src/sqlite_vec.ts"; -import { SqlJsDatabaseAdapter } from "../../../adapter-sqljs/src/index.ts"; -import { SupabaseDatabaseAdapter } from "../../../adapter-supabase/src/index.ts"; -import { DatabaseAdapter } from "@ai16z/eliza/src/database.ts"; -import { AgentRuntime } from "@ai16z/eliza/src/runtime.ts"; -import { - Action, - Evaluator, - ModelProviderName, - Provider, -} from "@ai16z/eliza/src/types.ts"; +import { SqliteDatabaseAdapter } from "@ai16z/adapter-sqlite"; +import { load } from "@ai16z/adapter-sqlite"; +import { SqlJsDatabaseAdapter } from "@ai16z/adapter-sqljs"; +import { SupabaseDatabaseAdapter } from "@ai16z/adapter-supabase"; +import { DatabaseAdapter } from "@ai16z/eliza"; +import { AgentRuntime } from "@ai16z/eliza"; +import { Action, Evaluator, ModelProviderName, Provider } from "@ai16z/eliza"; import { SUPABASE_ANON_KEY, SUPABASE_URL, TEST_EMAIL, TEST_PASSWORD, zeroUuid, -} from "./constants.ts"; -import { User } from "./types.ts"; +} from "./constants.js"; +import { User } from "./types.js"; export async function createRuntime({ env, diff --git a/packages/core/src/test_resources/data.ts b/packages/test/src/test_resources/data.ts similarity index 99% rename from packages/core/src/test_resources/data.ts rename to packages/test/src/test_resources/data.ts index 6b6d5481c7e..0a36b3a92e8 100644 --- a/packages/core/src/test_resources/data.ts +++ b/packages/test/src/test_resources/data.ts @@ -1,5 +1,5 @@ import { ConversationExample, type UUID } from "@ai16z/eliza/src/types.ts"; -import { zeroUuid } from "./constants.ts"; +import { zeroUuid } from "./constants.js"; // CJ asks Jim some personal questions - name, job, marital status, and what he's looking for in a relationship export const GetTellMeAboutYourselfConversation1 = ( diff --git a/packages/core/src/test_resources/getOrCreateRelationship.ts b/packages/test/src/test_resources/getOrCreateRelationship.ts similarity index 100% rename from packages/core/src/test_resources/getOrCreateRelationship.ts rename to packages/test/src/test_resources/getOrCreateRelationship.ts diff --git a/packages/core/src/test_resources/populateMemories.ts b/packages/test/src/test_resources/populateMemories.ts similarity index 96% rename from packages/core/src/test_resources/populateMemories.ts rename to packages/test/src/test_resources/populateMemories.ts index bef1cddc2f3..e58ed1b46df 100644 --- a/packages/core/src/test_resources/populateMemories.ts +++ b/packages/test/src/test_resources/populateMemories.ts @@ -1,6 +1,6 @@ import { Content, IAgentRuntime, type UUID } from "@ai16z/eliza/src/types.ts"; -import { getCachedEmbeddings, writeCachedEmbedding } from "./cache.ts"; -import { type User } from "./types.ts"; +import { getCachedEmbeddings, writeCachedEmbedding } from "./cache.js"; +import { type User } from "./types.js"; export async function populateMemories( runtime: IAgentRuntime, diff --git a/packages/core/src/test_resources/report.ts b/packages/test/src/test_resources/report.ts similarity index 100% rename from packages/core/src/test_resources/report.ts rename to packages/test/src/test_resources/report.ts diff --git a/packages/core/src/test_resources/runAiTest.ts b/packages/test/src/test_resources/runAiTest.ts similarity index 90% rename from packages/core/src/test_resources/runAiTest.ts rename to packages/test/src/test_resources/runAiTest.ts index 06cbe4e71ec..2c055e600c0 100644 --- a/packages/core/src/test_resources/runAiTest.ts +++ b/packages/test/src/test_resources/runAiTest.ts @@ -1,4 +1,4 @@ -import { addToReport } from "./report.ts"; +import { addToReport } from "./report.js"; export async function runAiTest( testName: string, diff --git a/packages/core/src/test_resources/templates.ts b/packages/test/src/test_resources/templates.ts similarity index 100% rename from packages/core/src/test_resources/templates.ts rename to packages/test/src/test_resources/templates.ts diff --git a/packages/core/src/test_resources/testAction.ts b/packages/test/src/test_resources/testAction.ts similarity index 93% rename from packages/core/src/test_resources/testAction.ts rename to packages/test/src/test_resources/testAction.ts index 78ea87a3a6e..9743c3fa2a7 100644 --- a/packages/core/src/test_resources/testAction.ts +++ b/packages/test/src/test_resources/testAction.ts @@ -1,8 +1,4 @@ -import { - IAgentRuntime, - type Action, - type Memory, -} from "@ai16z/eliza/src/types.ts"; +import { IAgentRuntime, type Action, type Memory } from "@ai16z/eliza"; export const TEST_ACTION = { name: "TEST_ACTION", diff --git a/packages/core/src/test_resources/testEvaluator.ts b/packages/test/src/test_resources/testEvaluator.ts similarity index 100% rename from packages/core/src/test_resources/testEvaluator.ts rename to packages/test/src/test_resources/testEvaluator.ts diff --git a/packages/core/src/test_resources/testSetup.ts b/packages/test/src/test_resources/testSetup.ts similarity index 88% rename from packages/core/src/test_resources/testSetup.ts rename to packages/test/src/test_resources/testSetup.ts index 1f782c22fec..870ba9ee353 100644 --- a/packages/core/src/test_resources/testSetup.ts +++ b/packages/test/src/test_resources/testSetup.ts @@ -1,5 +1,4 @@ import dotenv from "dotenv"; -import path from "path"; import { jest } from "@jest/globals"; diff --git a/packages/core/src/test_resources/types.ts b/packages/test/src/test_resources/types.ts similarity index 100% rename from packages/core/src/test_resources/types.ts rename to packages/test/src/test_resources/types.ts diff --git a/packages/core/src/tests/actions.test.ts b/packages/test/src/tests/actions.test.ts similarity index 91% rename from packages/core/src/tests/actions.test.ts rename to packages/test/src/tests/actions.test.ts index 6f702bf5d90..c7050d0563c 100644 --- a/packages/core/src/tests/actions.test.ts +++ b/packages/test/src/tests/actions.test.ts @@ -1,26 +1,23 @@ import dotenv from "dotenv"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { runAiTest } from "../src/test_resources/runAiTest.ts"; -import { messageHandlerTemplate } from "../src/test_resources/templates.ts"; -import { - TEST_ACTION, - TEST_ACTION_FAIL, -} from "../src/test_resources/testAction.ts"; -import { type User } from "../src/test_resources/types.ts"; -import { composeContext } from "../src/context.ts"; -import { embeddingZeroVector } from "../src/memory.ts"; +import { createRuntime } from "../test_resources/createRuntime.js"; +import { getOrCreateRelationship } from "../test_resources/getOrCreateRelationship.js"; +import { runAiTest } from "../test_resources/runAiTest.js"; +import { messageHandlerTemplate } from "../test_resources/templates.js"; +import { TEST_ACTION, TEST_ACTION_FAIL } from "../test_resources/testAction.js"; +import { type User } from "../test_resources/types.js"; import { + MemoryManager, Content, IAgentRuntime, ModelClass, State, type Memory, type UUID, -} from "../src/types.ts"; -import { stringToUuid } from "../src/uuid.ts"; -import { generateMessageResponse } from "../src/generation.ts"; -import { MemoryManager } from "@ai16z/eliza/src/index.ts"; + stringToUuid, + composeContext, + generateMessageResponse, + embeddingZeroVector, +} from "@ai16z/eliza"; async function handleMessage( runtime: IAgentRuntime, diff --git a/packages/core/src/test_resources/basic.test.ts b/packages/test/src/tests/basic.test.ts similarity index 100% rename from packages/core/src/test_resources/basic.test.ts rename to packages/test/src/tests/basic.test.ts diff --git a/packages/test/src/tests/browser.test.ts b/packages/test/src/tests/browser.test.ts new file mode 100644 index 00000000000..a1ec417691e --- /dev/null +++ b/packages/test/src/tests/browser.test.ts @@ -0,0 +1,98 @@ +import dotenv from "dotenv"; +import { createRuntime } from "../test_resources/createRuntime.ts"; +import { BrowserService } from "@ai16z/plugin-node"; + +dotenv.config(); + +describe("BrowserService", () => { + let browserService: BrowserService; + + // beforeAll(async () => { + // const { runtime } = await createRuntime({ + // env: process.env as Record, + // actions: [], + // }); + // browserService = BrowserService.getInstance(runtime); + // await browserService.initialize(); + // }); + + // afterAll(async () => { + // await browserService.closeBrowser(); + // }); + + // test("should initialize and close browser", async () => { + // const { runtime } = await createRuntime({ + // env: process.env as Record, + // actions: [], + // }); + // const newBrowserService = BrowserService.getInstance(runtime); + // await expect(newBrowserService.initialize()).resolves.not.toThrow(); + // await expect(newBrowserService.closeBrowser()).resolves.not.toThrow(); + // }); + + // test("should fetch content from a simple website", async () => { + // const content = await browserService.getPageContent( + // "https://example.com" + // ); + // expect(content).toContain("Example Domain"); + // }, 30000); + + // test("should fetch content from a news website", async () => { + // const content = await browserService.getPageContent( + // "https://news.ycombinator.com" + // ); + // expect(content).toContain("Hacker News"); + // }, 30000); + + // test("should handle a website with potential CAPTCHA (GitHub)", async () => { + // const content = + // await browserService.getPageContent("https://github.com"); + // expect(content).toContain("GitHub"); + // }, 60000); + + // test("should fetch content from a website that might be blocked (Wikipedia)", async () => { + // const content = await browserService.getPageContent( + // "https://en.wikipedia.org/wiki/Main_Page" + // ); + // expect(content).toContain("Wikipedia"); + // }, 30000); + + // test("should handle a 404 error and try alternative sources", async () => { + // const content = await browserService.getPageContent( + // "https://example.com/nonexistent-page" + // ); + // expect(content).not.toBe(""); + // expect(content).toContain("search"); // Expecting to fall back to a search result + // }, 60000); + + // test("should handle network errors gracefully", async () => { + // await expect( + // browserService.getPageContent( + // "https://thisisaninvalidurlthatdoesnotexist.com" + // ) + // ).rejects.toThrow("Failed to fetch content from alternative sources"); + // }, 60000); + + // test("should block ads on ad-heavy website", async () => { + // const content = await browserService.getPageContent( + // "https://www.cnn.com" + // ); + // expect(content).not.toContain("Advertisement"); + // }, 60000); + + // test("should handle a website with reCAPTCHA", async () => { + // const content = await browserService.getPageContent( + // "https://www.google.com/recaptcha/api2/demo" + // ); + // expect(content).toContain("reCAPTCHA"); + // // Note: Full CAPTCHA solving can't be reliably tested without manual intervention + // }, 60000); + + // test("should handle a website with hCAPTCHA", async () => { + // const content = await browserService.getPageContent( + // "https://accounts.hcaptcha.com/demo" + // ); + // expect(content).toContain("hCaptcha"); + // // Note: Full CAPTCHA solving can't be reliably tested without manual intervention + // }, 60000); +}); diff --git a/packages/test/src/tests/continue.test.ts b/packages/test/src/tests/continue.test.ts new file mode 100644 index 00000000000..ccdee8e0249 --- /dev/null +++ b/packages/test/src/tests/continue.test.ts @@ -0,0 +1,233 @@ +// import dotenv from "dotenv"; +// import { Content, IAgentRuntime, Memory, type UUID } from "@ai16z/eliza"; +// import { zeroUuid } from "../test_resources/constants.js"; +// import { createRuntime } from "../test_resources/createRuntime.js"; +// import { Goodbye1 } from "../test_resources/data.js"; +// import { getOrCreateRelationship } from "../test_resources/getOrCreateRelationship.js"; +// import { populateMemories } from "../test_resources/populateMemories.js"; +// import { runAiTest } from "../test_resources/runAiTest.js"; +// import { type User } from "../test_resources/types.js"; +// import action from "@ai16z/eliza"; +// import ignore from "@ai16z/eliza"; +// import { MemoryManager } from "@ai16z/eliza/src/memory.ts"; + +// dotenv.config({ path: ".dev.vars" }); + +// const GetContinueExample1 = (_userId: UUID) => [ +// { +// userId: zeroUuid, +// content: { +// text: "Hmm, let think for a second, I was going to tell you about something...", +// action: "CONTINUE", +// }, +// }, +// { +// userId: zeroUuid, +// content: { +// text: "I remember now, I was going to tell you about my favorite food, which is pizza.", +// action: "CONTINUE", +// }, +// }, +// { +// userId: zeroUuid, +// content: { +// text: "I love pizza, it's so delicious.", +// action: "CONTINUE", +// }, +// }, +// ]; + +// describe("User Profile", () => { +// let user: User; +// let runtime: IAgentRuntime; +// let roomId: UUID = zeroUuid; + +// afterAll(async () => { +// await cleanup(); +// }); + +// beforeAll(async () => { +// const setup = await createRuntime({ +// env: process.env as Record, +// actions: [action, ignore], +// }); +// user = setup.session.user; +// runtime = setup.runtime; + +// const data = await getOrCreateRelationship({ +// runtime, +// userA: user.id as UUID, +// userB: zeroUuid, +// }); + +// roomId = data.roomId; + +// await cleanup(); +// }); + +// beforeEach(async () => { +// await cleanup(); +// }); + +// async function cleanup() { +// const factsManager = new MemoryManager({ +// runtime, +// tableName: "facts", +// }); + +// await factsManager.removeAllMemories(roomId); +// await runtime.messageManager.removeAllMemories(roomId); +// } + +// // test validate function response + +// test("Test validate function response", async () => { +// await runAiTest("Test validate function response", async () => { +// const message: Memory = { +// userId: user.id as UUID, +// content: { text: "Hello" }, +// roomId: roomId as UUID, +// }; + +// const validate = action.validate!; + +// const result = await validate(runtime, message); + +// // try again with GetContinueExample1, expect to be false +// await populateMemories(runtime, user, roomId, [ +// GetContinueExample1, +// ]); + +// const message2: Memory = { +// userId: zeroUuid as UUID, +// content: { +// text: "Hello", +// action: "CONTINUE", +// }, +// roomId: roomId as UUID, +// }; + +// const result2 = await validate(runtime, message2); + +// return result === true && result2 === false; +// }); +// }, 60000); + +// test("Test repetition check on continue", async () => { +// await runAiTest("Test repetition check on continue", async () => { +// const message: Memory = { +// userId: zeroUuid as UUID, +// content: { +// text: "Hmm, let think for a second, I was going to tell you about something...", +// action: "CONTINUE", +// }, +// roomId, +// }; + +// const handler = action.handler!; + +// await populateMemories(runtime, user, roomId, [ +// GetContinueExample1, +// ]); + +// const result = (await handler(runtime, message)) as Content; + +// return result.action !== "CONTINUE"; +// }); +// }, 60000); + +// test("Test multiple continue messages in a conversation", async () => { +// await runAiTest( +// "Test multiple continue messages in a conversation", +// async () => { +// const message: Memory = { +// userId: user?.id as UUID, +// content: { +// text: "Write a short story in three parts, using the CONTINUE action for each part.", +// }, +// roomId: roomId, +// }; + +// const initialMessageCount = +// await runtime.messageManager.countMemories(roomId, false); + +// await action.handler!(runtime, message); + +// const finalMessageCount = +// await runtime.messageManager.countMemories(roomId, false); + +// const agentMessages = await runtime.messageManager.getMemories({ +// roomId, +// agentId: runtime.agentId, +// count: finalMessageCount - initialMessageCount, +// unique: false, +// }); + +// const continueMessages = agentMessages.filter( +// (m) => +// m.userId === zeroUuid && +// (m.content as Content).action === "CONTINUE" +// ); + +// // Check if the agent sent more than one message +// const sentMultipleMessages = +// finalMessageCount - initialMessageCount > 2; + +// // Check if the agent used the CONTINUE action for each part +// const usedContinueAction = continueMessages.length === 3; +// // Check if the agent's responses are not empty +// const responsesNotEmpty = agentMessages.every( +// (m) => (m.content as Content).text !== "" +// ); + +// return ( +// sentMultipleMessages && +// usedContinueAction && +// responsesNotEmpty +// ); +// } +// ); +// }, 60000); + +// test("Test if message is added to database", async () => { +// await runAiTest("Test if message is added to database", async () => { +// const message: Memory = { +// userId: user?.id as UUID, +// content: { +// text: "Tell me more about your favorite food.", +// }, +// roomId: roomId as UUID, +// }; + +// const initialMessageCount = +// await runtime.messageManager.countMemories(roomId, false); + +// await action.handler!(runtime, message); + +// const finalMessageCount = +// await runtime.messageManager.countMemories(roomId, false); + +// return finalMessageCount - initialMessageCount === 2; +// }); +// }, 60000); +// test("Test if not continue", async () => { +// await runAiTest("Test if not continue", async () => { +// // this is basically the same test as the one in ignore.test +// const message: Memory = { +// userId: user?.id as UUID, +// content: { text: "Bye" }, +// roomId: roomId as UUID, +// }; + +// const handler = action.handler!; + +// await populateMemories(runtime, user, roomId, [Goodbye1]); + +// const result = (await handler(runtime, message)) as Content; + +// return result.action === "IGNORE"; +// }); +// }, 60000); + +// // test conditions where we would expect a wait or an ignore +// }); diff --git a/packages/core/src/tests/evaluation.test.ts b/packages/test/src/tests/evaluation.test.ts similarity index 67% rename from packages/core/src/tests/evaluation.test.ts rename to packages/test/src/tests/evaluation.test.ts index 04ff8bee4c4..955892f9ad4 100644 --- a/packages/core/src/tests/evaluation.test.ts +++ b/packages/test/src/tests/evaluation.test.ts @@ -1,17 +1,17 @@ import dotenv from "dotenv"; -import fact from "../src/evaluators/fact.ts"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { runAiTest } from "../src/test_resources/runAiTest.ts"; +// import fact from "@ai16z/eliza"; +import { zeroUuid } from "../test_resources/constants.js"; +import { createRuntime } from "../test_resources/createRuntime.js"; +import { getOrCreateRelationship } from "../test_resources/getOrCreateRelationship.js"; +import { runAiTest } from "../test_resources/runAiTest.js"; import { TEST_EVALUATOR, TEST_EVALUATOR_FAIL, -} from "../src/test_resources/testEvaluator.ts"; -import { type User } from "../src/test_resources/types.ts"; -import { composeContext } from "../src/context.ts"; -import { evaluationTemplate } from "../src/evaluators.ts"; -import { IAgentRuntime, Memory, UUID } from "../src/types.ts"; +} from "../test_resources/testEvaluator.js"; +import { type User } from "../test_resources/types.js"; +import { composeContext } from "@ai16z/eliza"; +import { evaluationTemplate } from "@ai16z/eliza"; +import { IAgentRuntime, Memory, UUID } from "@ai16z/eliza"; dotenv.config({ path: ".dev.vars" }); @@ -60,6 +60,7 @@ describe("Evaluation Process", () => { const message: Memory = { userId: user.id as UUID, content: { text: "Test message for evaluation" }, + agentId: zeroUuid, roomId, }; @@ -79,6 +80,7 @@ describe("Evaluation Process", () => { userId: user.id as UUID, content: { text: "Run TEST_EVALUATOR handler" }, roomId, + agentId: zeroUuid, }; const result = await TEST_EVALUATOR.handler(runtime, message); @@ -93,6 +95,7 @@ describe("Evaluation Process", () => { text: "We are in testing mode. We want to make sure that the test passes by replying with the evaluator TEST_EVALUATOR in the array of evaluators that are returned. Please run the TEST_EVALUATOR", }, roomId, + agentId: zeroUuid, }; const state = await runtime.composeState(message); @@ -102,27 +105,28 @@ describe("Evaluation Process", () => { }); // Adjust the timeout if needed }, 600000); - test("Test that fact appears in evaluation handler", async () => { - const { runtime } = await createRuntime({ - env: process.env as Record, - conversationLength: 1, - evaluators: [fact], - }); + // test("Test that fact appears in evaluation handler", async () => { + // const { runtime } = await createRuntime({ + // env: process.env as Record, + // conversationLength: 1, + // evaluators: [fact], + // }); - const message: Memory = { - userId: user.id as UUID, - content: { text: "Test message for evaluation" }, - roomId, - }; + // const message: Memory = { + // userId: user.id as UUID, + // content: { text: "Test message for evaluation" }, + // roomId, + // agentId: zeroUuid, + // }; - const state = await runtime.composeState(message); - const prompt = composeContext({ state, template: evaluationTemplate }); + // const state = await runtime.composeState(message); + // const prompt = composeContext({ state, template: evaluationTemplate }); - // expect that the prompt contacts the testEvaluator name - expect(prompt.includes(fact.name)).toBeTruthy(); + // // expect that the prompt contacts the testEvaluator name + // expect(prompt.includes(fact.name)).toBeTruthy(); - // check if state.EvaluatorNames contains the testEvaluator name + // // check if state.EvaluatorNames contains the testEvaluator name - expect(state.evaluatorNames).toContain(fact.name); - }); + // expect(state.evaluatorNames).toContain(fact.name); + // }); }); diff --git a/packages/core/src/tests/fact.test.ts b/packages/test/src/tests/fact.test.ts similarity index 76% rename from packages/core/src/tests/fact.test.ts rename to packages/test/src/tests/fact.test.ts index 01cbdbc2e90..1f886952706 100644 --- a/packages/core/src/tests/fact.test.ts +++ b/packages/test/src/tests/fact.test.ts @@ -1,24 +1,26 @@ import dotenv from "dotenv"; -import { defaultActions } from "../src/actions.ts"; -import { IAgentRuntime, type Memory, type UUID } from "../src/types.ts"; + +import { IAgentRuntime, type Memory, type UUID } from "@ai16z/eliza"; import { getCachedEmbeddings, writeCachedEmbedding, -} from "../src/test_resources/cache.ts"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; +} from "../test_resources/cache.js"; +import { zeroUuid } from "../test_resources/constants.js"; +import { createRuntime } from "../test_resources/createRuntime.js"; import { GetTellMeAboutYourselfConversation1, GetTellMeAboutYourselfConversation2, GetTellMeAboutYourselfConversation3, jimFacts, -} from "../src/test_resources/data.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { populateMemories } from "../src/test_resources/populateMemories.ts"; -import { runAiTest } from "../src/test_resources/runAiTest.ts"; -import { type User } from "../src/test_resources/types.ts"; -import evaluator from "../src/evaluators/fact.ts"; +} from "../test_resources/data.js"; +import { getOrCreateRelationship } from "../test_resources/getOrCreateRelationship.js"; +import { populateMemories } from "../test_resources/populateMemories.js"; +import { runAiTest } from "../test_resources/runAiTest.js"; +import { type User } from "../test_resources/types.js"; +import evaluator from "@ai16z/eliza"; import { MemoryManager } from "@ai16z/eliza/src/memory.ts"; +import { TEST_EVALUATOR } from "../test_resources/testEvaluator.ts"; +import { TEST_ACTION } from "../test_resources/testAction.ts"; dotenv.config({ path: ".dev.vars" }); @@ -30,8 +32,8 @@ describe("Facts Evaluator", () => { beforeAll(async () => { const setup = await createRuntime({ env: process.env as Record, - evaluators: [evaluator], - actions: defaultActions, + evaluators: [TEST_EVALUATOR], + actions: [TEST_ACTION], }); user = setup.session.user; runtime = setup.runtime; @@ -66,11 +68,12 @@ describe("Facts Evaluator", () => { const message: Memory = { userId: user.id as UUID, content: { text: "" }, + agentId: zeroUuid, roomId, }; - const result = await evaluator.handler(runtime, message); - const resultConcatenated = result.join("\n"); + const result = await TEST_EVALUATOR.handler(runtime, message); + const resultConcatenated = (result as string[]).join("\n"); return ( resultConcatenated.toLowerCase().includes("programmer") && @@ -91,11 +94,12 @@ describe("Facts Evaluator", () => { const message: Memory = { userId: user.id as UUID, content: { text: "" }, + agentId: zeroUuid, roomId, }; - const result = await evaluator.handler(runtime, message); - const resultConcatenated = result.join("\n"); + const result = await TEST_EVALUATOR.handler(runtime, message); + const resultConcatenated = (result as string[]).join("\n"); return ( !resultConcatenated.toLowerCase().includes("francisco") && diff --git a/packages/core/src/tests/goal.test.ts b/packages/test/src/tests/goal.test.ts similarity index 86% rename from packages/core/src/tests/goal.test.ts rename to packages/test/src/tests/goal.test.ts index 8120fb0e126..71f0fbb1a17 100644 --- a/packages/core/src/tests/goal.test.ts +++ b/packages/test/src/tests/goal.test.ts @@ -1,6 +1,6 @@ import dotenv from "dotenv"; -import { defaultActions } from "../src/actions.ts"; -import { createGoal, getGoals } from "../src/goals.ts"; +// import { defaultActions } from "@ai16z/eliza"; +import { createGoal, getGoals } from "@ai16z/eliza"; import { Goal, GoalStatus, @@ -9,14 +9,15 @@ import { State, type Memory, type UUID, -} from "../src/types.ts"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { populateMemories } from "../src/test_resources/populateMemories.ts"; -import { runAiTest } from "../src/test_resources/runAiTest.ts"; -import { type User } from "../src/test_resources/types.ts"; -import evaluator from "../src/evaluators/goal.ts"; +} from "@ai16z/eliza"; +import { zeroUuid } from "../test_resources/constants.js"; +import { createRuntime } from "../test_resources/createRuntime.js"; +import { getOrCreateRelationship } from "../test_resources/getOrCreateRelationship.js"; +import { populateMemories } from "../test_resources/populateMemories.js"; +import { runAiTest } from "../test_resources/runAiTest.js"; +import { type User } from "../test_resources/types.js"; +import { TEST_EVALUATOR } from "../test_resources/testEvaluator.ts"; +import { TEST_ACTION } from "../test_resources/testAction.ts"; dotenv.config({ path: ".dev.vars" }); @@ -28,8 +29,8 @@ describe("Goals Evaluator", () => { beforeAll(async () => { const setup = await createRuntime({ env: process.env as Record, - evaluators: [evaluator], - actions: defaultActions, + evaluators: [TEST_EVALUATOR], + actions: [TEST_ACTION], }); user = setup.session.user; runtime = setup.runtime; @@ -107,11 +108,12 @@ describe("Goals Evaluator", () => { content: { text: "I've completed task 1 and task 2 for the Test Goal. Both are finished. Everything is done and I'm ready for the next goal.", }, + agentId: zeroUuid, roomId, }; // Process the message with the goal evaluator - await evaluator.handler( + await TEST_EVALUATOR.handler( runtime, message, {} as unknown as State, @@ -176,10 +178,11 @@ describe("Goals Evaluator", () => { const message: Memory = { userId: user.id as UUID, content: { text: "I've decided to mark Goal Y as failed." }, + agentId: zeroUuid, roomId, }; - await evaluator.handler(runtime, message, {} as State, { + await TEST_EVALUATOR.handler(runtime, message, {} as State, { onlyInProgress: false, }); diff --git a/packages/core/src/tests/goals.test.ts b/packages/test/src/tests/goals.test.ts similarity index 90% rename from packages/core/src/tests/goals.test.ts rename to packages/test/src/tests/goals.test.ts index 872073a39a9..e975408c7fd 100644 --- a/packages/core/src/tests/goals.test.ts +++ b/packages/test/src/tests/goals.test.ts @@ -1,14 +1,9 @@ import dotenv from "dotenv"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { type User } from "../src/test_resources/types.ts"; -import { createGoal, getGoals, updateGoal } from "../src/goals.ts"; -import { - GoalStatus, - IAgentRuntime, - type Goal, - type UUID, -} from "../src/types.ts"; +import { zeroUuid } from "../test_resources/constants.js"; +import { createRuntime } from "../test_resources/createRuntime.js"; +import { type User } from "../test_resources/types.js"; +import { createGoal, getGoals, updateGoal } from "@ai16z/eliza"; +import { GoalStatus, IAgentRuntime, type Goal, type UUID } from "@ai16z/eliza"; dotenv.config({ path: ".dev.vars" }); describe("Goals", () => { diff --git a/packages/core/src/tests/ignore.test.ts b/packages/test/src/tests/ignore.test.ts similarity index 86% rename from packages/core/src/tests/ignore.test.ts rename to packages/test/src/tests/ignore.test.ts index 28746f60689..7390dae7f8f 100644 --- a/packages/core/src/tests/ignore.test.ts +++ b/packages/test/src/tests/ignore.test.ts @@ -1,7 +1,7 @@ import dotenv from "dotenv"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { composeContext } from "../src/context.ts"; -import { embeddingZeroVector } from "../src/memory.ts"; +import { zeroUuid } from "../test_resources/constants.js"; +import { composeContext } from "@ai16z/eliza"; +import { embeddingZeroVector } from "@ai16z/eliza"; import { Content, IAgentRuntime, @@ -9,20 +9,20 @@ import { ModelClass, State, type UUID, -} from "../src/types.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; +} from "@ai16z/eliza"; +import { createRuntime } from "../test_resources/createRuntime.js"; import { GetTellMeAboutYourselfConversationTroll1, GetTellMeAboutYourselfConversationTroll2, Goodbye1, -} from "../src/test_resources/data.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { populateMemories } from "../src/test_resources/populateMemories.ts"; -import { runAiTest } from "../src/test_resources/runAiTest.ts"; -import { messageHandlerTemplate } from "../src/test_resources/templates.ts"; -import { type User } from "../src/test_resources/types.ts"; -import action from "../src/actions/ignore.ts"; -import { generateMessageResponse } from "../src/generation.ts"; +} from "../test_resources/data.js"; +import { getOrCreateRelationship } from "../test_resources/getOrCreateRelationship.js"; +import { populateMemories } from "../test_resources/populateMemories.js"; +import { runAiTest } from "../test_resources/runAiTest.js"; +import { messageHandlerTemplate } from "../test_resources/templates.js"; +import { type User } from "../test_resources/types.js"; +import { TEST_ACTION } from "../test_resources/testAction.js"; +import { generateMessageResponse } from "@ai16z/eliza"; import { MemoryManager } from "@ai16z/eliza/src/memory.ts"; async function handleMessage( @@ -41,6 +41,7 @@ async function handleMessage( text: _senderContent, action: (message.content as Content)?.action ?? "null", }, + agentId: zeroUuid, roomId, embedding: embeddingZeroVector, }); @@ -74,6 +75,7 @@ async function handleMessage( const responseMessage: Memory = { userId: runtime.agentId, + agentId: zeroUuid, content: response, roomId, embedding: embeddingZeroVector, @@ -105,7 +107,7 @@ describe("Ignore action tests", () => { beforeAll(async () => { const setup = await createRuntime({ env: process.env as Record, - actions: [action], + actions: [TEST_ACTION], }); user = setup.session.user; runtime = setup.runtime; @@ -142,6 +144,7 @@ describe("Ignore action tests", () => { await runAiTest("Test ignore action", async () => { const message: Memory = { userId: user?.id as UUID, + agentId: zeroUuid, content: { text: "Never talk to me again" }, roomId: roomId as UUID, }; @@ -162,6 +165,7 @@ describe("Ignore action tests", () => { async () => { const message: Memory = { userId: user.id as UUID, + agentId: zeroUuid, content: { text: "", action: "IGNORE" }, roomId: roomId as UUID, }; @@ -187,6 +191,7 @@ describe("Ignore action tests", () => { async () => { const message: Memory = { userId: user.id as UUID, + agentId: zeroUuid, content: { text: "", action: "IGNORE" }, roomId: roomId as UUID, }; @@ -210,6 +215,7 @@ describe("Ignore action tests", () => { await runAiTest("Expect ignore", async () => { const message: Memory = { userId: user.id as UUID, + agentId: zeroUuid, content: { text: "Bye" }, roomId: roomId as UUID, }; diff --git a/packages/core/src/tests/memory.test.ts b/packages/test/src/tests/memory.test.ts similarity index 95% rename from packages/core/src/tests/memory.test.ts rename to packages/test/src/tests/memory.test.ts index d77f515256e..d0802f32749 100644 --- a/packages/core/src/tests/memory.test.ts +++ b/packages/test/src/tests/memory.test.ts @@ -2,14 +2,14 @@ import dotenv from "dotenv"; import { getCachedEmbeddings, writeCachedEmbedding, -} from "../src/test_resources/cache.ts"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { type User } from "../src/test_resources/types.ts"; -import { MemoryManager } from "../src/memory.ts"; -import { type Content, type Memory, type UUID } from "../src/types.ts"; -import { embed } from "../src/embedding.ts"; +} from "../test_resources/cache.js"; +import { zeroUuid } from "../test_resources/constants.js"; +import { createRuntime } from "../test_resources/createRuntime.js"; +import { getOrCreateRelationship } from "../test_resources/getOrCreateRelationship.js"; +import { type User } from "../test_resources/types.js"; +import { MemoryManager } from "@ai16z/eliza"; +import { type Content, type Memory, type UUID } from "@ai16z/eliza"; +import { embed } from "@ai16z/eliza"; dotenv.config({ path: ".dev.vars" }); describe("Memory", () => { @@ -73,6 +73,7 @@ describe("Memory", () => { content: { text: similarMemoryContent }, roomId: roomId, embedding, + agentId: zeroUuid, }); if (!embedding) { writeCachedEmbedding( @@ -89,6 +90,7 @@ describe("Memory", () => { content: { text: dissimilarMemoryContent }, roomId, embedding, + agentId: zeroUuid, }); if (!embedding) { writeCachedEmbedding( @@ -139,6 +141,7 @@ describe("Memory", () => { content: { text: queryMemoryContent }, roomId, embedding, + agentId: zeroUuid, }); if (!embedding) { writeCachedEmbedding( @@ -155,6 +158,7 @@ describe("Memory", () => { content: { text: highSimilarityContent }, roomId, embedding, + agentId: zeroUuid, }); if (!embedding) { writeCachedEmbedding( @@ -170,6 +174,7 @@ describe("Memory", () => { content: { text: lowSimilarityContent }, roomId, embedding, + agentId: zeroUuid, }); if (!embedding) { writeCachedEmbedding( @@ -248,6 +253,7 @@ describe("Memory - Basic tests", () => { content: { text: "Test content for memory lifecycle" }, roomId: roomId, embedding, + agentId: zeroUuid, }); if (!embedding) { writeCachedEmbedding( @@ -349,6 +355,7 @@ describe("Memory - Extended Tests", () => { content: { text: similarMemoryContent }, roomId, embedding, + agentId: zeroUuid, }); if (!embedding) { writeCachedEmbedding( @@ -394,6 +401,7 @@ describe("Memory - Extended Tests", () => { content: { text: similarMemoryContent }, roomId: roomId, embedding, + agentId: zeroUuid, }); if (!embedding) { writeCachedEmbedding( @@ -435,6 +443,7 @@ describe("Memory - Extended Tests", () => { content: { text: memoryContent }, roomId, embedding, + agentId: zeroUuid, }); if (!embedding) { writeCachedEmbedding( @@ -452,6 +461,7 @@ describe("Memory - Extended Tests", () => { content: { text: similarMemoryContent }, roomId, embedding, + agentId: zeroUuid, }); if (!embedding) { writeCachedEmbedding( @@ -488,6 +498,7 @@ describe("Memory - Extended Tests", () => { content: { text: similarMemoryContent }, roomId, embedding, + agentId: zeroUuid, }); if (!embedding) { writeCachedEmbedding( @@ -504,6 +515,7 @@ describe("Memory - Extended Tests", () => { content: { text: dissimilarMemoryContent }, roomId, embedding: await getCachedEmbeddings(dissimilarMemoryContent), + agentId: zeroUuid, }); if (!embedding) { writeCachedEmbedding( @@ -553,6 +565,7 @@ describe("Memory - Extended Tests", () => { content: { text: queryMemoryContent }, roomId, embedding, + agentId: zeroUuid, }); if (!embedding) { writeCachedEmbedding( @@ -569,6 +582,7 @@ describe("Memory - Extended Tests", () => { content: { text: highSimilarityContent }, roomId, embedding, + agentId: zeroUuid, }); if (!embedding) { writeCachedEmbedding( @@ -584,6 +598,7 @@ describe("Memory - Extended Tests", () => { content: { text: lowSimilarityContent }, roomId, embedding, + agentId: zeroUuid, }); if (!embedding) { writeCachedEmbedding( diff --git a/packages/core/src/tests/messages.test.ts b/packages/test/src/tests/messages.test.ts similarity index 85% rename from packages/core/src/tests/messages.test.ts rename to packages/test/src/tests/messages.test.ts index 02e2c1107ad..9b3880b1886 100644 --- a/packages/core/src/tests/messages.test.ts +++ b/packages/test/src/tests/messages.test.ts @@ -1,22 +1,22 @@ import dotenv from "dotenv"; -import { formatFacts } from "../src/evaluators/fact.ts"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { type User } from "../src/test_resources/types.ts"; +import { formatFacts } from "@ai16z/plugin-bootstrap"; +import { zeroUuid } from "../test_resources/constants.js"; +import { createRuntime } from "../test_resources/createRuntime.js"; +import { getOrCreateRelationship } from "../test_resources/getOrCreateRelationship.js"; +import { type User } from "../test_resources/types.js"; import { + createRelationship, formatActors, formatMessages, getActorDetails, -} from "../src/messages.ts"; -import { createRelationship } from "../src/relationships.ts"; +} from "@ai16z/eliza"; import { IAgentRuntime, type Actor, type Content, type Memory, type UUID, -} from "../src/types.ts"; +} from "@ai16z/eliza"; dotenv.config({ path: ".dev.vars" }); @@ -78,11 +78,13 @@ describe("Messages Library", () => { content: { text: "Hello" }, userId: user.id as UUID, roomId: "00000000-0000-0000-0000-000000000000", + agentId: zeroUuid, }, { content: { text: "How are you?" }, userId: "00000000-0000-0000-0000-000000000000", roomId: "00000000-0000-0000-0000-000000000000", + agentId: zeroUuid, }, ]; const formattedMessages = formatMessages({ messages, actors }); @@ -99,11 +101,13 @@ describe("Messages Library", () => { content: { text: "Reflecting on the day" }, userId: user.id as UUID, roomId: "00000000-0000-0000-0000-000000000000", + agentId: zeroUuid, }, { content: { text: "Thoughts and musings" }, userId: "00000000-0000-0000-0000-000000000000", roomId: "00000000-0000-0000-0000-000000000000room", + agentId: zeroUuid, }, ]; const formattedFacts = formatFacts(facts); diff --git a/packages/core/src/tests/providers.test.ts b/packages/test/src/tests/providers.test.ts similarity index 87% rename from packages/core/src/tests/providers.test.ts rename to packages/test/src/tests/providers.test.ts index 902de0379c1..c5c60fbea0e 100644 --- a/packages/core/src/tests/providers.test.ts +++ b/packages/test/src/tests/providers.test.ts @@ -1,13 +1,13 @@ import dotenv from "dotenv"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; +import { zeroUuid } from "../test_resources/constants.js"; +import { createRuntime } from "../test_resources/createRuntime.js"; import { IAgentRuntime, type Memory, type Provider, type State, type UUID, -} from "../src/types.ts"; +} from "@ai16z/eliza"; dotenv.config({ path: ".dev.vars" }); @@ -34,6 +34,7 @@ describe("TestProvider", () => { const message: Memory = { userId: zeroUuid, content: { text: "" }, + agentId: zeroUuid, roomId: roomId, }; diff --git a/packages/core/src/tests/relationships.test.ts b/packages/test/src/tests/relationships.test.ts similarity index 79% rename from packages/core/src/tests/relationships.test.ts rename to packages/test/src/tests/relationships.test.ts index d9bb406e415..7327167e538 100644 --- a/packages/core/src/tests/relationships.test.ts +++ b/packages/test/src/tests/relationships.test.ts @@ -1,10 +1,10 @@ import dotenv from "dotenv"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; // Adjust the import path as needed -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { type User } from "../src/test_resources/types.ts"; -import { createRelationship, getRelationships } from "../src/relationships.ts"; // Adjust the import path as needed -import { IAgentRuntime, type UUID } from "../src/types.ts"; +import { zeroUuid } from "../test_resources/constants.js"; +import { createRuntime } from "../test_resources/createRuntime.js"; // Adjust the import path as needed +import { getOrCreateRelationship } from "../test_resources/getOrCreateRelationship.js"; +import { type User } from "../test_resources/types.js"; +import { createRelationship, getRelationships } from "@ai16z/eliza"; // Adjust the import path as needed +import { IAgentRuntime, type UUID } from "@ai16z/eliza"; dotenv.config({ path: ".dev.vars" }); diff --git a/packages/core/src/tests/runtime.test.ts b/packages/test/src/tests/runtime.test.ts similarity index 87% rename from packages/core/src/tests/runtime.test.ts rename to packages/test/src/tests/runtime.test.ts index efd3f2efb09..e8c97bf87f3 100644 --- a/packages/core/src/tests/runtime.test.ts +++ b/packages/test/src/tests/runtime.test.ts @@ -2,12 +2,12 @@ import dotenv from "dotenv"; import { getCachedEmbeddings, writeCachedEmbedding, -} from "../src/test_resources/cache.ts"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import { getOrCreateRelationship } from "../src/test_resources/getOrCreateRelationship.ts"; -import { type User } from "../src/test_resources/types.ts"; -import { IAgentRuntime, type Memory, type UUID } from "../src/types.ts"; +} from "../test_resources/cache.js"; +import { zeroUuid } from "../test_resources/constants.js"; +import { createRuntime } from "../test_resources/createRuntime.js"; +import { getOrCreateRelationship } from "../test_resources/getOrCreateRelationship.js"; +import { type User } from "../test_resources/types.js"; +import { IAgentRuntime, type Memory, type UUID } from "@ai16z/eliza"; dotenv.config({ path: ".dev.vars" }); @@ -40,6 +40,7 @@ describe("Agent Runtime", () => { content, roomId, embedding, + agentId: zeroUuid, }); if (!embedding) { writeCachedEmbedding( @@ -102,6 +103,7 @@ describe("Agent Runtime", () => { userId: user.id as UUID, content: { text: "test message" }, roomId: roomId as UUID, + agentId: zeroUuid, }; const state = await runtime.composeState(message); diff --git a/packages/core/src/tests/time.test.ts b/packages/test/src/tests/time.test.ts similarity index 86% rename from packages/core/src/tests/time.test.ts rename to packages/test/src/tests/time.test.ts index 0453c2d79f7..8be36c08915 100644 --- a/packages/core/src/tests/time.test.ts +++ b/packages/test/src/tests/time.test.ts @@ -1,14 +1,14 @@ import dotenv from "dotenv"; -import { composeContext } from "../src/context.ts"; +import { composeContext } from "@ai16z/eliza"; import { IAgentRuntime, type Memory, type State, type UUID, -} from "../src/types.ts"; -import { zeroUuid } from "../src/test_resources/constants.ts"; -import { createRuntime } from "../src/test_resources/createRuntime.ts"; -import timeProvider from "../src/providers/time.ts"; +} from "@ai16z/eliza"; +import { zeroUuid } from "../test_resources/constants.js"; +import { createRuntime } from "../test_resources/createRuntime.js"; +import { timeProvider } from "@ai16z/plugin-bootstrap"; dotenv.config({ path: ".dev.vars" }); @@ -32,6 +32,7 @@ describe("Time Provider", () => { userId: user.id, content: { text: "" }, roomId: roomId, + agentId: zeroUuid, }; const currentTimeResponse = await timeProvider.get( @@ -49,6 +50,7 @@ describe("Time Provider", () => { userId: user.id, content: { text: "" }, roomId: roomId, + agentId: zeroUuid, }; // Manually integrate the time provider's response into the state @@ -74,6 +76,7 @@ describe("Time Provider", () => { userId: user.id, content: { text: "" }, roomId: roomId, + agentId: zeroUuid, }; const currentTimeResponse = await timeProvider.get(runtime, message); diff --git a/packages/test/src/tests/token.test.ts b/packages/test/src/tests/token.test.ts new file mode 100644 index 00000000000..be0492ee429 --- /dev/null +++ b/packages/test/src/tests/token.test.ts @@ -0,0 +1,77 @@ +// import { createRuntime } from "../test_resources/createRuntime"; +// import { TokenProvider } from "@ai16z/plugin-solana"; +// import NodeCache from "node-cache"; + +// // Mock the dependencies +// jest.mock("cross-fetch"); +// jest.mock("fs"); +// jest.mock("node-cache"); + +// describe("TokenProvider Tests", () => { +// // let connection: Connection; +// let tokenProvider: TokenProvider; + +// beforeEach(() => { +// // Initialize the connection and token provider before each test +// // connection = new Connection("https://api.mainnet-beta.solana.com"); +// tokenProvider = new TokenProvider( +// "2weMjPLLybRMMva1fM3U31goWWrCpF59CHWNhnCJ9Vyh" +// ); +// }); + +// test("should fetch token security data", async () => { +// const { runtime } = await createRuntime({ +// conversationLength: 10, +// }); + +// // Mock the response for the fetchTokenSecurity call +// const mockFetchResponse = { +// success: true, +// data: { +// ownerBalance: "100", +// creatorBalance: "50", +// ownerPercentage: 10, +// creatorPercentage: 5, +// top10HolderBalance: "200", +// top10HolderPercent: 20, +// }, +// }; + +// // Mock fetchWithRetry function +// const fetchSpy = jest +// .spyOn(tokenProvider as any, "fetchWithRetry") +// .mockResolvedValue(mockFetchResponse); + +// // Run the fetchTokenSecurity method +// // const securityData = await tokenProvider.fetchTokenSecurity(); + +// // Check if the data returned is correct +// // expect(securityData).toEqual({ +// // ownerBalance: "100", +// // creatorBalance: "50", +// // ownerPercentage: 10, +// // creatorPercentage: 5, +// // top10HolderBalance: "200", +// // top10HolderPercent: 20, +// // }); +// //console.log the securityData +// // console.log({ securityData }); + +// // const holderList = await tokenProvider.fetchHolderList(); + +// // console.log({ holderList }); + +// // const tradeData = await tokenProvider.fetchTokenTradeData(); +// // console.log({ tradeData }); + +// // const dexScreenerData = await tokenProvider.fetchDexScreenerData(); +// // console.log({ dexScreenerData }); + +// const tokenReport = +// await tokenProvider.getFormattedTokenReport(runtime); +// console.log({ tokenReport }); + +// // Ensure the mock was called +// expect(fetchSpy).toHaveBeenCalled(); +// }); +// }); diff --git a/packages/test/src/tests/utils.test.ts b/packages/test/src/tests/utils.test.ts new file mode 100644 index 00000000000..6339c181623 --- /dev/null +++ b/packages/test/src/tests/utils.test.ts @@ -0,0 +1,76 @@ +// import Database from "better-sqlite3"; +// import fs from "fs"; +// import path from "path"; +// import { fileURLToPath } from "url"; +// import { TwitterInteractionClient } from "@ai16z/eliza"; +// import { SqliteDatabaseAdapter } from "@ai16z/adapter-sqljs"; +// import { defaultCharacter } from "@ai16z/eliza"; +// import { buildConversationThread } from "@ai16z/eliza"; +// import { AgentRuntime } from "@ai16z/eliza"; +// import settings from "@ai16z/eliza"; +// import { ModelProviderName } from "@ai16z/eliza"; + +// // const __dirname = path.dirname(new URL(".", import.meta.url).pathname); + +// const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +// describe("buildConversationThread", () => { +// let runtime: AgentRuntime; +// let client: TwitterInteractionClient; + +// beforeAll(async () => { +// // Create an instance of the AgentRuntime +// runtime = new AgentRuntime({ +// databaseAdapter: new SqliteDatabaseAdapter( +// new Database(":memory:") +// ), +// token: settings.OPENAI_API_KEY as string, +// evaluators: [], +// modelProvider: ModelProviderName.OPENAI, +// character: defaultCharacter, +// providers: [], +// actions: [], +// }); + +// // Create an instance of the TwitterPostClient +// client = new TwitterInteractionClient(runtime); + +// // Load cached Twitter credentials +// const cookiesFilePath = path.join( +// __dirname, +// "../../../tweetcache/" + +// runtime.getSetting("TWITTER_USERNAME") + +// "_cookies.json" +// ); +// console.log("Cookies file path:", cookiesFilePath); +// if (fs.existsSync(cookiesFilePath)) { +// const cookiesArray = JSON.parse( +// fs.readFileSync(cookiesFilePath, "utf-8") +// ); +// client.setCookiesFromArray(cookiesArray); +// } else { +// throw new Error( +// "Twitter credentials not found. Please provide valid cookies.json." +// ); +// } +// }); + +// it("should build a conversation thread from a tweet ID", async () => { +// const tweetId = "1830058678197895517"; + +// // Fetch the tweet from the API +// const tweet = await client.getTweet(tweetId); +// console.log("Original tweet:", JSON.stringify(tweet, null, 2)); + +// // Build the conversation thread +// const thread = await buildConversationThread(tweet, client); + +// console.log("Generated conversation thread:"); +// console.log(thread); + +// // Add assertions based on the expected structure and content of the thread +// // expect(thread.includes("By: Aya Bochman (@ayaboch)")).toBe(true); +// // expect(thread.includes("@ayaboch @DanBochman You should do nothing. Its opensource code, you have too much to lose by fighting this fight, this post will get u blacklisted be aware")).toBe(true); +// // expect(thread.includes("@BLUECOW009 @ayaboch @DanBochman That's not how it works")).toBe(true); +// }, 30000); +// }); diff --git a/packages/test/tsconfig.json b/packages/test/tsconfig.json new file mode 100644 index 00000000000..eaa78145aa3 --- /dev/null +++ b/packages/test/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src" + }, + "include": ["src"] +} diff --git a/packages/test/tsup.config.ts b/packages/test/tsup.config.ts new file mode 100644 index 00000000000..e42bf4efeae --- /dev/null +++ b/packages/test/tsup.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + outDir: "dist", + sourcemap: true, + clean: true, + format: ["esm"], // Ensure you're targeting CommonJS + external: [ + "dotenv", // Externalize dotenv to prevent bundling + "fs", // Externalize fs to use Node.js built-in module + "path", // Externalize other built-ins if necessary + "@reflink/reflink", + "@node-llama-cpp", + "https", + "http", + "agentkeepalive", + // Add other modules you want to externalize + ], +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1c7221516fa..08530df2c2e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -112,7 +112,7 @@ importers: devDependencies: tsup: specifier: ^8.3.5 - version: 8.3.5(jiti@1.21.6)(postcss@8.4.48)(typescript@5.6.3)(yaml@2.6.0) + version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) packages/adapter-sqlite: dependencies: @@ -134,7 +134,7 @@ importers: devDependencies: tsup: specifier: ^8.3.5 - version: 8.3.5(jiti@1.21.6)(postcss@8.4.48)(typescript@5.6.3)(yaml@2.6.0) + version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) packages/adapter-sqljs: dependencies: @@ -156,7 +156,7 @@ importers: devDependencies: tsup: specifier: ^8.3.5 - version: 8.3.5(jiti@1.21.6)(postcss@8.4.48)(typescript@5.6.3)(yaml@2.6.0) + version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) packages/adapter-supabase: dependencies: @@ -172,7 +172,7 @@ importers: devDependencies: tsup: specifier: ^8.3.5 - version: 8.3.5(jiti@1.21.6)(postcss@8.4.48)(typescript@5.6.3)(yaml@2.6.0) + version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) packages/agent: dependencies: @@ -211,7 +211,7 @@ importers: version: link:../plugin-node '@ai16z/plugin-solana': specifier: workspace:* - version: link:../plugin-solana + version: link:../test readline: specifier: ^1.3.0 version: 1.3.0 @@ -224,7 +224,7 @@ importers: version: 10.9.2(@types/node@22.8.4)(typescript@5.6.3) tsup: specifier: ^8.3.5 - version: 8.3.5(jiti@1.21.6)(postcss@8.4.48)(typescript@5.6.3)(yaml@2.6.0) + version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) packages/client-auto: dependencies: @@ -258,7 +258,7 @@ importers: devDependencies: tsup: specifier: ^8.3.5 - version: 8.3.5(jiti@1.21.6)(postcss@8.4.48)(typescript@5.6.3)(yaml@2.6.0) + version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) packages/client-direct: dependencies: @@ -292,7 +292,7 @@ importers: devDependencies: tsup: specifier: ^8.3.5 - version: 8.3.5(jiti@1.21.6)(postcss@8.4.48)(typescript@5.6.3)(yaml@2.6.0) + version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) packages/client-discord: dependencies: @@ -326,7 +326,7 @@ importers: devDependencies: tsup: specifier: ^8.3.5 - version: 8.3.5(jiti@1.21.6)(postcss@8.4.48)(typescript@5.6.3)(yaml@2.6.0) + version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) packages/client-telegram: dependencies: @@ -345,7 +345,7 @@ importers: devDependencies: tsup: specifier: ^8.3.5 - version: 8.3.5(jiti@1.21.6)(postcss@8.4.48)(typescript@5.6.3)(yaml@2.6.0) + version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) packages/client-twitter: dependencies: @@ -364,7 +364,7 @@ importers: devDependencies: tsup: specifier: ^8.3.5 - version: 8.3.5(jiti@1.21.6)(postcss@8.4.48)(typescript@5.6.3)(yaml@2.6.0) + version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) packages/core: dependencies: @@ -391,7 +391,7 @@ importers: version: 10.0.0 ai: specifier: ^3.4.23 - version: 3.4.33(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))(react@18.2.0)(sswr@2.1.0(svelte@5.1.14))(svelte@5.1.14)(vue@3.5.12(typescript@5.6.3))(zod@3.23.8) + version: 3.4.33(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))(react@18.2.0)(sswr@2.1.0(svelte@5.1.15))(svelte@5.1.15)(vue@3.5.12(typescript@5.6.3))(zod@3.23.8) anthropic-vertex-ai: specifier: ^1.0.0 version: 1.0.0(encoding@0.1.13)(zod@3.23.8) @@ -518,7 +518,7 @@ importers: version: 2.8.0 tsup: specifier: ^8.3.5 - version: 8.3.5(jiti@1.21.6)(postcss@8.4.48)(typescript@5.6.3)(yaml@2.6.0) + version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) typescript: specifier: 5.6.3 version: 5.6.3 @@ -530,7 +530,7 @@ importers: version: link:../core tsup: specifier: ^8.3.5 - version: 8.3.5(jiti@1.21.6)(postcss@8.4.48)(typescript@5.6.3)(yaml@2.6.0) + version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) whatwg-url: specifier: 7.1.0 version: 7.1.0 @@ -542,7 +542,7 @@ importers: version: link:../core tsup: specifier: ^8.3.5 - version: 8.3.5(jiti@1.21.6)(postcss@8.4.48)(typescript@5.6.3)(yaml@2.6.0) + version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) whatwg-url: specifier: 7.1.0 version: 7.1.0 @@ -711,7 +711,7 @@ importers: devDependencies: tsup: specifier: ^8.3.5 - version: 8.3.5(jiti@1.21.6)(postcss@8.4.48)(typescript@5.6.3)(yaml@2.6.0) + version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) packages/plugin-solana: dependencies: @@ -741,7 +741,58 @@ importers: version: 1.3.2(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(rollup@4.25.0)(typescript@5.6.3)(utf-8-validate@5.0.10) tsup: specifier: ^8.3.5 - version: 8.3.5(jiti@1.21.6)(postcss@8.4.48)(typescript@5.6.3)(yaml@2.6.0) + version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) + whatwg-url: + specifier: 7.1.0 + version: 7.1.0 + + packages/test: + dependencies: + '@ai16z/adapter-sqlite': + specifier: workspace:* + version: link:../adapter-sqlite + '@ai16z/adapter-sqljs': + specifier: workspace:* + version: link:../adapter-sqljs + '@ai16z/adapter-supabase': + specifier: workspace:* + version: link:../adapter-supabase + '@ai16z/eliza': + specifier: workspace:* + version: link:../core + '@ai16z/plugin-bootstrap': + specifier: workspace:* + version: link:../plugin-bootstrap + '@ai16z/plugin-node': + specifier: workspace:* + version: link:../plugin-node + '@ai16z/plugin-solana': + specifier: workspace:* + version: 'link:' + '@coral-xyz/anchor': + specifier: ^0.30.1 + version: 0.30.1(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/spl-token': + specifier: 0.4.9 + version: 0.4.9(@solana/web3.js@1.95.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(utf-8-validate@5.0.10) + '@solana/web3.js': + specifier: 1.95.4 + version: 1.95.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + bignumber: + specifier: 1.1.0 + version: 1.1.0 + bignumber.js: + specifier: 9.1.2 + version: 9.1.2 + node-cache: + specifier: 5.1.2 + version: 5.1.2 + pumpdotfun-sdk: + specifier: 1.3.2 + version: 1.3.2(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(rollup@4.25.0)(typescript@5.6.3)(utf-8-validate@5.0.10) + tsup: + specifier: ^8.3.5 + version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) whatwg-url: specifier: 7.1.0 version: 7.1.0 @@ -1059,8 +1110,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-define-polyfill-provider@0.6.2': - resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} + '@babel/helper-define-polyfill-provider@0.6.3': + resolution: {integrity: sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -2634,67 +2685,67 @@ packages: resolution: {integrity: sha512-y7efHHwghQfk28G2z3tlZ67pLG0XdfYbcVG26r7YIXALRsrVQcTq4/tdenSmdOrEsNahIYA/eh8aEVROWGFUDg==} engines: {node: ^16.14.0 || >=18.0.0} - '@nx/devkit@20.0.12': - resolution: {integrity: sha512-HsaDoAmzLPE2vHal2eNYvH7x6NCfHjUblm8WDD12Q/uCdTBvDTZqd7P+bukEH+2FhY89Dn/1fy59vKkA+rcB/g==} + '@nx/devkit@20.1.0': + resolution: {integrity: sha512-TDWT3d7nei+FtqoZscR7KtbQ9BXzV1c1Wvk9UUejo7eXbrQ/+YnHVVze8EMuIgTXaHxNIBTKGUPcRi3cibmCDw==} peerDependencies: nx: '>= 19 <= 21' - '@nx/nx-darwin-arm64@20.0.12': - resolution: {integrity: sha512-iwEDUTKx0n2S6Nz9gc9ShrfBw0MG87U0YIu2x/09tKOSkcsw90QKy54qN/6WNoFIE41Kt3U+dYtWi+NdLRE9kw==} + '@nx/nx-darwin-arm64@20.1.0': + resolution: {integrity: sha512-fel9LpSWuwY0cGAsRFEPxLp6J5VcK/5sjeWA0lZWrFf1oQJCOlKBfkxzi384Nd7eK5JSjxIXrpYfRLaqSbp+IA==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@nx/nx-darwin-x64@20.0.12': - resolution: {integrity: sha512-JYFNf0yPReejaooQAAIMsjWDGENT777wDXj45e7JQUMM4t6NOMpGBj4qUFyc6a/jXT+/bCGEj4N7VDZDZiogGA==} + '@nx/nx-darwin-x64@20.1.0': + resolution: {integrity: sha512-l1DB8dk2rCLGgXW26HmFOKYpUCF259LRus8z+z7dsFv5vz9TeN+fk5m9aAdiENgMA2cGlndQQW+E8UIo3yv+9g==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@nx/nx-freebsd-x64@20.0.12': - resolution: {integrity: sha512-892n8o7vxdmE7pol3ggV78YHlP25p6Y/Z2x69nnC3BBTpWmesyd6lbEmamANofD5KcKCmT1HquC3m6rCT7akHw==} + '@nx/nx-freebsd-x64@20.1.0': + resolution: {integrity: sha512-f8uMRIhiOA/73cIjiyS3gpKvaAtsHgyUkkoCOPc4xdxoSLAjlxb6VOUPIFj9rzLA6qQXImVpsiNPG+p1sJ1GAQ==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@nx/nx-linux-arm-gnueabihf@20.0.12': - resolution: {integrity: sha512-ZPcdYIVAc5JMtmvroJOloI9CJgtwBOGr7E7mO1eT44zs5av0j/QMIj6GSDdvJ7fx+I7TmT4mDiu3s6rLO+/JjA==} + '@nx/nx-linux-arm-gnueabihf@20.1.0': + resolution: {integrity: sha512-M7pay8hFJQZ3uJHlr5hZK/8o1BcHt95hy/SU7Azt7+LKQGOy42tXhHO30As9APzXqRmvoA2Iq1IyrJJicrz+Ew==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@nx/nx-linux-arm64-gnu@20.0.12': - resolution: {integrity: sha512-TadGwwUKS5WQg2YOMb2WuuVG1k14miSdB9qJOcAX5MGdOiQ1fpV00ph+kMWZSsCCo6N7sKxmvXXXdsUUFSDGjg==} + '@nx/nx-linux-arm64-gnu@20.1.0': + resolution: {integrity: sha512-A5+Kpk1uwYIj6CPm0DWLVz5wNTN4ewNl7ajLS9YJOi4yHx/FhfMMyPj4ZnbTpc4isuvgZwBZNl8kwFb2RdXq4w==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@nx/nx-linux-arm64-musl@20.0.12': - resolution: {integrity: sha512-EE2HQjgY87/s9+PQ27vbYyDEXFZ4Qot+O8ThVDVuMI/2dosmWs6C4+YEm3VYG+CT31MVwe/vHKXbDlZgkROMuA==} + '@nx/nx-linux-arm64-musl@20.1.0': + resolution: {integrity: sha512-pWIQPt9Fst1O4dgrWHdU1b+5wpfLmsmaSeRvLQ9b2VFp3tKGko4ie0skme62TuMgpcqMWDBFKs8KgbHESOi7vw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@nx/nx-linux-x64-gnu@20.0.12': - resolution: {integrity: sha512-gITJ2g6dH2qvGrI2CHHRyd3soVrJyQQGkqtJnWq04ge+YDy/KniXR2ThQ93LI/QLAxKrKOe3qmIIaNdcdDYnjA==} + '@nx/nx-linux-x64-gnu@20.1.0': + resolution: {integrity: sha512-sOpeGOHznk2ztCXzKhRPAKG3WtwaQUsfQ/3aYDXE6z+rSfyZTGY29M/a9FbdjI4cLJX+NdLAAMj15c3VecJ65g==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@nx/nx-linux-x64-musl@20.0.12': - resolution: {integrity: sha512-vOoCrjL44nFZ5N8a4UAIYELnf/tq1dRaLEhSV+P0hKTEtwONj4k8crfU/2HifG1iU7p3AWJLEyaddMoINhB/2g==} + '@nx/nx-linux-x64-musl@20.1.0': + resolution: {integrity: sha512-SxnQJhjOvuOfUZnF4Wt4/O/l1e21qpACZzfMaPIvmiTLk9zPJZWtfgbqlKtTXHKWq9DfIUZQqZXRIpHPM1sDZQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@nx/nx-win32-arm64-msvc@20.0.12': - resolution: {integrity: sha512-gKdaul23bdRnh493iAd6pSLPSW54VBuEv2zPL86cgprLOcEZiGM5BLJWQguKHCib6dYKaIP4CUIs7i7vhEID+A==} + '@nx/nx-win32-arm64-msvc@20.1.0': + resolution: {integrity: sha512-Z/KoaAA+Rg9iqqOPkKZV61MejPoJBOHlecFpq0G4TgKMJEJ/hEsjojq5usO1fUGAbvQT/SXL3pYWgZwhD3VEHw==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@nx/nx-win32-x64-msvc@20.0.12': - resolution: {integrity: sha512-R1pz4kAG0Ok0EDxXhHwKM3ZZcK2nLycuR9SDrq2Ldp2knvbFf4quSjWyAQaiofJXo179+noa7o5tZDZbNjBYMw==} + '@nx/nx-win32-x64-msvc@20.1.0': + resolution: {integrity: sha512-pbxacjLsW9vXD9FibvU8Pal/r5+Yq6AaW6I57CDi7jsLt+K6jcS0fP4FlfXT8QFWdx9+bOKNfOsKEIwpirMN1w==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -3776,8 +3827,8 @@ packages: '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} - '@types/node-fetch@2.6.11': - resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} + '@types/node-fetch@2.6.12': + resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} '@types/node-forge@1.3.11': resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} @@ -4395,8 +4446,8 @@ packages: resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - babel-plugin-polyfill-corejs2@0.4.11: - resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} + babel-plugin-polyfill-corejs2@0.4.12: + resolution: {integrity: sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -4405,8 +4456,8 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.6.2: - resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} + babel-plugin-polyfill-regenerator@0.6.3: + resolution: {integrity: sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 @@ -5763,8 +5814,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.55: - resolution: {integrity: sha512-6maZ2ASDOTBtjt9FhqYPRnbvKU5tjG0IN9SztUOWYw2AzNDNpKJYLJmlK0/En4Hs/aiWnB+JZ+gW19PIGszgKg==} + electron-to-chromium@1.5.56: + resolution: {integrity: sha512-7lXb9dAvimCFdvUMTyucD4mnIndt/xhRKFAlky0CyFogdnNmdPQNoHI23msF/2V4mpTxMzgMdjK4+YRlFlRQZw==} emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} @@ -8577,8 +8628,8 @@ packages: peerDependencies: webpack: ^4.0.0 || ^5.0.0 - nx@20.0.12: - resolution: {integrity: sha512-pQ7Rwb2Qlhr+fEamd0qc4VsL/aKjVJ0MXPsosuhdZobLJQOKHefe+nXSSZ1Jy19VM3RRpxUKFneD/V2jvs3qDA==} + nx@20.1.0: + resolution: {integrity: sha512-d8Ywh1AvG3szYqWEHg2n9DHh/hF0jtVhMZKxwsr7n+kSVxp7gE/rHCCfOo8H+OmP030qXoox5e4Ovp7H9CEJnA==} hasBin: true peerDependencies: '@swc-node/register': ^1.8.0 @@ -9243,14 +9294,14 @@ packages: peerDependencies: postcss: ^8.1.0 - postcss-modules-local-by-default@4.0.5: - resolution: {integrity: sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==} + postcss-modules-local-by-default@4.1.0: + resolution: {integrity: sha512-rm0bdSv4jC3BDma3s9H19ZddW0aHX6EoqwDYU2IfZhRN+53QrufTRo2IdkAbRqLx4R2IYbZnbjKKxg4VN5oU9Q==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 - postcss-modules-scope@3.2.0: - resolution: {integrity: sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==} + postcss-modules-scope@3.2.1: + resolution: {integrity: sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 @@ -9343,6 +9394,10 @@ packages: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} + postcss-selector-parser@7.0.0: + resolution: {integrity: sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==} + engines: {node: '>=4'} + postcss-sort-media-queries@5.2.0: resolution: {integrity: sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==} engines: {node: '>=14.0.0'} @@ -9370,8 +9425,8 @@ packages: peerDependencies: postcss: ^8.4.31 - postcss@8.4.48: - resolution: {integrity: sha512-GCRK8F6+Dl7xYniR5a4FYbpBzU8XnZVeowqsQFYdcXuSbChgiks7qybSkbvnaeqv0G0B+dd9/jJgH8kkLDQeEA==} + postcss@8.4.49: + resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} engines: {node: ^10 || ^12 || >=14} postgres-array@2.0.0: @@ -10585,8 +10640,8 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svelte@5.1.14: - resolution: {integrity: sha512-1ZURTV4OBeWS6qKFzKjTIa9K4RWCR3CtpgOen/hsamCIS/dwBpvglwPNMjvNJR/yMlUWxtq+KC4mmvCo7G7m6Q==} + svelte@5.1.15: + resolution: {integrity: sha512-cs2JYADrEorRCB4AUCHMvwperwAKcn/mz7w1xzVOv3fG6TmAS2n13JYHH8/uDCFbqVyRSXXlL+vA5RDwGUXEZg==} engines: {node: '>=18'} svg-parser@2.0.4: @@ -11688,13 +11743,13 @@ snapshots: transitivePeerDependencies: - zod - '@ai-sdk/svelte@0.0.57(svelte@5.1.14)(zod@3.23.8)': + '@ai-sdk/svelte@0.0.57(svelte@5.1.15)(zod@3.23.8)': dependencies: '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8) '@ai-sdk/ui-utils': 0.0.50(zod@3.23.8) - sswr: 2.1.0(svelte@5.1.14) + sswr: 2.1.0(svelte@5.1.15) optionalDependencies: - svelte: 5.1.14 + svelte: 5.1.15 transitivePeerDependencies: - zod @@ -11916,7 +11971,7 @@ snapshots: '@anthropic-ai/sdk@0.30.1(encoding@0.1.13)': dependencies: '@types/node': 18.19.64 - '@types/node-fetch': 2.6.11 + '@types/node-fetch': 2.6.12 abort-controller: 3.0.0 agentkeepalive: 4.5.0 form-data-encoder: 1.7.2 @@ -12015,7 +12070,7 @@ snapshots: regexpu-core: 6.1.1 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.26.0)': + '@babel/helper-define-polyfill-provider@0.6.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-compilation-targets': 7.25.9 @@ -12561,9 +12616,9 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-module-imports': 7.25.9 '@babel/helper-plugin-utils': 7.25.9 - babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.26.0) + babel-plugin-polyfill-corejs2: 0.4.12(@babel/core@7.26.0) babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.26.0) - babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.26.0) + babel-plugin-polyfill-regenerator: 0.6.3(@babel/core@7.26.0) semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -12697,9 +12752,9 @@ snapshots: '@babel/plugin-transform-unicode-regex': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-unicode-sets-regex': 7.25.9(@babel/core@7.26.0) '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.26.0) - babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.26.0) + babel-plugin-polyfill-corejs2: 0.4.12(@babel/core@7.26.0) babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.26.0) - babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.26.0) + babel-plugin-polyfill-regenerator: 0.6.3(@babel/core@7.26.0) core-js-compat: 3.39.0 semver: 6.3.1 transitivePeerDependencies: @@ -12995,19 +13050,19 @@ snapshots: '@docusaurus/logger': 3.6.1 '@docusaurus/types': 3.6.1(acorn@8.14.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@docusaurus/utils': 3.6.1(acorn@8.14.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.6.3) - autoprefixer: 10.4.20(postcss@8.4.48) + autoprefixer: 10.4.20(postcss@8.4.49) babel-loader: 9.2.1(@babel/core@7.26.0)(webpack@5.96.1) clean-css: 5.3.3 copy-webpack-plugin: 11.0.0(webpack@5.96.1) css-loader: 6.11.0(webpack@5.96.1) css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.96.1) - cssnano: 6.1.2(postcss@8.4.48) + cssnano: 6.1.2(postcss@8.4.49) file-loader: 6.2.0(webpack@5.96.1) html-minifier-terser: 7.2.0 mini-css-extract-plugin: 2.9.2(webpack@5.96.1) null-loader: 4.0.1(webpack@5.96.1) - postcss: 8.4.48 - postcss-loader: 7.3.4(postcss@8.4.48)(typescript@5.6.3)(webpack@5.96.1) + postcss: 8.4.49 + postcss-loader: 7.3.4(postcss@8.4.49)(typescript@5.6.3)(webpack@5.96.1) react-dev-utils: 12.0.1(eslint@9.13.0(jiti@1.21.6))(typescript@5.6.3)(webpack@5.96.1) terser-webpack-plugin: 5.3.10(webpack@5.96.1) tslib: 2.8.0 @@ -13102,9 +13157,9 @@ snapshots: '@docusaurus/cssnano-preset@3.6.1': dependencies: - cssnano-preset-advanced: 6.1.2(postcss@8.4.48) - postcss: 8.4.48 - postcss-sort-media-queries: 5.2.0(postcss@8.4.48) + cssnano-preset-advanced: 6.1.2(postcss@8.4.49) + postcss: 8.4.49 + postcss-sort-media-queries: 5.2.0(postcss@8.4.49) tslib: 2.8.0 '@docusaurus/logger@3.6.1': @@ -13579,7 +13634,7 @@ snapshots: infima: 0.2.0-alpha.45 lodash: 4.17.21 nprogress: 0.2.0 - postcss: 8.4.48 + postcss: 8.4.49 prism-react-renderer: 2.3.1(react@18.2.0) prismjs: 1.29.0 react: 18.2.0 @@ -14317,7 +14372,7 @@ snapshots: '@npmcli/arborist': 7.5.4 '@npmcli/package-json': 5.2.0 '@npmcli/run-script': 8.1.0 - '@nx/devkit': 20.0.12(nx@20.0.12) + '@nx/devkit': 20.1.0(nx@20.1.0) '@octokit/plugin-enterprise-rest': 6.0.1 '@octokit/rest': 19.0.11(encoding@0.1.13) aproba: 2.0.0 @@ -14356,7 +14411,7 @@ snapshots: npm-package-arg: 11.0.2 npm-packlist: 8.0.2 npm-registry-fetch: 17.1.0 - nx: 20.0.12 + nx: 20.1.0 p-map: 4.0.0 p-map-series: 2.1.0 p-queue: 6.6.2 @@ -14638,46 +14693,46 @@ snapshots: - bluebird - supports-color - '@nx/devkit@20.0.12(nx@20.0.12)': + '@nx/devkit@20.1.0(nx@20.1.0)': dependencies: ejs: 3.1.10 enquirer: 2.3.6 ignore: 5.3.2 minimatch: 9.0.3 - nx: 20.0.12 + nx: 20.1.0 semver: 7.6.3 tmp: 0.2.3 tslib: 2.8.0 yargs-parser: 21.1.1 - '@nx/nx-darwin-arm64@20.0.12': + '@nx/nx-darwin-arm64@20.1.0': optional: true - '@nx/nx-darwin-x64@20.0.12': + '@nx/nx-darwin-x64@20.1.0': optional: true - '@nx/nx-freebsd-x64@20.0.12': + '@nx/nx-freebsd-x64@20.1.0': optional: true - '@nx/nx-linux-arm-gnueabihf@20.0.12': + '@nx/nx-linux-arm-gnueabihf@20.1.0': optional: true - '@nx/nx-linux-arm64-gnu@20.0.12': + '@nx/nx-linux-arm64-gnu@20.1.0': optional: true - '@nx/nx-linux-arm64-musl@20.0.12': + '@nx/nx-linux-arm64-musl@20.1.0': optional: true - '@nx/nx-linux-x64-gnu@20.0.12': + '@nx/nx-linux-x64-gnu@20.1.0': optional: true - '@nx/nx-linux-x64-musl@20.0.12': + '@nx/nx-linux-x64-musl@20.1.0': optional: true - '@nx/nx-win32-arm64-msvc@20.0.12': + '@nx/nx-win32-arm64-msvc@20.1.0': optional: true - '@nx/nx-win32-x64-msvc@20.0.12': + '@nx/nx-win32-x64-msvc@20.1.0': optional: true '@octokit/app@15.1.0': @@ -15984,7 +16039,7 @@ snapshots: '@types/ms@0.7.34': {} - '@types/node-fetch@2.6.11': + '@types/node-fetch@2.6.12': dependencies: '@types/node': 22.8.4 form-data: 4.0.1 @@ -16229,7 +16284,7 @@ snapshots: '@vue/shared': 3.5.12 estree-walker: 2.0.2 magic-string: 0.30.12 - postcss: 8.4.48 + postcss: 8.4.49 source-map-js: 1.2.1 '@vue/compiler-ssr@3.5.12': @@ -16421,13 +16476,13 @@ snapshots: clean-stack: 2.2.0 indent-string: 4.0.0 - ai@3.4.33(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))(react@18.2.0)(sswr@2.1.0(svelte@5.1.14))(svelte@5.1.14)(vue@3.5.12(typescript@5.6.3))(zod@3.23.8): + ai@3.4.33(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))(react@18.2.0)(sswr@2.1.0(svelte@5.1.15))(svelte@5.1.15)(vue@3.5.12(typescript@5.6.3))(zod@3.23.8): dependencies: '@ai-sdk/provider': 0.0.26 '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8) '@ai-sdk/react': 0.0.70(react@18.2.0)(zod@3.23.8) '@ai-sdk/solid': 0.0.54(zod@3.23.8) - '@ai-sdk/svelte': 0.0.57(svelte@5.1.14)(zod@3.23.8) + '@ai-sdk/svelte': 0.0.57(svelte@5.1.15)(zod@3.23.8) '@ai-sdk/ui-utils': 0.0.50(zod@3.23.8) '@ai-sdk/vue': 0.0.59(vue@3.5.12(typescript@5.6.3))(zod@3.23.8) '@opentelemetry/api': 1.9.0 @@ -16439,8 +16494,8 @@ snapshots: optionalDependencies: openai: 4.69.0(encoding@0.1.13)(zod@3.23.8) react: 18.2.0 - sswr: 2.1.0(svelte@5.1.14) - svelte: 5.1.14 + sswr: 2.1.0(svelte@5.1.15) + svelte: 5.1.15 zod: 3.23.8 transitivePeerDependencies: - solid-js @@ -16641,14 +16696,14 @@ snapshots: dependencies: immediate: 3.3.0 - autoprefixer@10.4.20(postcss@8.4.48): + autoprefixer@10.4.20(postcss@8.4.49): dependencies: browserslist: 4.24.2 caniuse-lite: 1.0.30001680 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 - postcss: 8.4.48 + postcss: 8.4.49 postcss-value-parser: 4.2.0 aws-sign2@0.7.0: {} @@ -16715,11 +16770,11 @@ snapshots: '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.20.6 - babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.26.0): + babel-plugin-polyfill-corejs2@0.4.12(@babel/core@7.26.0): dependencies: '@babel/compat-data': 7.26.2 '@babel/core': 7.26.0 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.26.0) + '@babel/helper-define-polyfill-provider': 0.6.3(@babel/core@7.26.0) semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -16727,15 +16782,15 @@ snapshots: babel-plugin-polyfill-corejs3@0.10.6(@babel/core@7.26.0): dependencies: '@babel/core': 7.26.0 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.26.0) + '@babel/helper-define-polyfill-provider': 0.6.3(@babel/core@7.26.0) core-js-compat: 3.39.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.26.0): + babel-plugin-polyfill-regenerator@0.6.3(@babel/core@7.26.0): dependencies: '@babel/core': 7.26.0 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.26.0) + '@babel/helper-define-polyfill-provider': 0.6.3(@babel/core@7.26.0) transitivePeerDependencies: - supports-color @@ -16934,7 +16989,7 @@ snapshots: browserslist@4.24.2: dependencies: caniuse-lite: 1.0.30001680 - electron-to-chromium: 1.5.55 + electron-to-chromium: 1.5.56 node-releases: 2.0.18 update-browserslist-db: 1.1.1(browserslist@4.24.2) @@ -17607,18 +17662,18 @@ snapshots: dependencies: type-fest: 1.4.0 - css-declaration-sorter@7.2.0(postcss@8.4.48): + css-declaration-sorter@7.2.0(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 css-loader@6.11.0(webpack@5.96.1): dependencies: - icss-utils: 5.1.0(postcss@8.4.48) - postcss: 8.4.48 - postcss-modules-extract-imports: 3.1.0(postcss@8.4.48) - postcss-modules-local-by-default: 4.0.5(postcss@8.4.48) - postcss-modules-scope: 3.2.0(postcss@8.4.48) - postcss-modules-values: 4.0.0(postcss@8.4.48) + icss-utils: 5.1.0(postcss@8.4.49) + postcss: 8.4.49 + postcss-modules-extract-imports: 3.1.0(postcss@8.4.49) + postcss-modules-local-by-default: 4.1.0(postcss@8.4.49) + postcss-modules-scope: 3.2.1(postcss@8.4.49) + postcss-modules-values: 4.0.0(postcss@8.4.49) postcss-value-parser: 4.2.0 semver: 7.6.3 optionalDependencies: @@ -17627,9 +17682,9 @@ snapshots: css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.96.1): dependencies: '@jridgewell/trace-mapping': 0.3.25 - cssnano: 6.1.2(postcss@8.4.48) + cssnano: 6.1.2(postcss@8.4.49) jest-worker: 29.7.0 - postcss: 8.4.48 + postcss: 8.4.49 schema-utils: 4.2.0 serialize-javascript: 6.0.2 webpack: 5.96.1 @@ -17668,60 +17723,60 @@ snapshots: cssesc@3.0.0: {} - cssnano-preset-advanced@6.1.2(postcss@8.4.48): + cssnano-preset-advanced@6.1.2(postcss@8.4.49): dependencies: - autoprefixer: 10.4.20(postcss@8.4.48) + autoprefixer: 10.4.20(postcss@8.4.49) browserslist: 4.24.2 - cssnano-preset-default: 6.1.2(postcss@8.4.48) - postcss: 8.4.48 - postcss-discard-unused: 6.0.5(postcss@8.4.48) - postcss-merge-idents: 6.0.3(postcss@8.4.48) - postcss-reduce-idents: 6.0.3(postcss@8.4.48) - postcss-zindex: 6.0.2(postcss@8.4.48) + cssnano-preset-default: 6.1.2(postcss@8.4.49) + postcss: 8.4.49 + postcss-discard-unused: 6.0.5(postcss@8.4.49) + postcss-merge-idents: 6.0.3(postcss@8.4.49) + postcss-reduce-idents: 6.0.3(postcss@8.4.49) + postcss-zindex: 6.0.2(postcss@8.4.49) - cssnano-preset-default@6.1.2(postcss@8.4.48): + cssnano-preset-default@6.1.2(postcss@8.4.49): dependencies: browserslist: 4.24.2 - css-declaration-sorter: 7.2.0(postcss@8.4.48) - cssnano-utils: 4.0.2(postcss@8.4.48) - postcss: 8.4.48 - postcss-calc: 9.0.1(postcss@8.4.48) - postcss-colormin: 6.1.0(postcss@8.4.48) - postcss-convert-values: 6.1.0(postcss@8.4.48) - postcss-discard-comments: 6.0.2(postcss@8.4.48) - postcss-discard-duplicates: 6.0.3(postcss@8.4.48) - postcss-discard-empty: 6.0.3(postcss@8.4.48) - postcss-discard-overridden: 6.0.2(postcss@8.4.48) - postcss-merge-longhand: 6.0.5(postcss@8.4.48) - postcss-merge-rules: 6.1.1(postcss@8.4.48) - postcss-minify-font-values: 6.1.0(postcss@8.4.48) - postcss-minify-gradients: 6.0.3(postcss@8.4.48) - postcss-minify-params: 6.1.0(postcss@8.4.48) - postcss-minify-selectors: 6.0.4(postcss@8.4.48) - postcss-normalize-charset: 6.0.2(postcss@8.4.48) - postcss-normalize-display-values: 6.0.2(postcss@8.4.48) - postcss-normalize-positions: 6.0.2(postcss@8.4.48) - postcss-normalize-repeat-style: 6.0.2(postcss@8.4.48) - postcss-normalize-string: 6.0.2(postcss@8.4.48) - postcss-normalize-timing-functions: 6.0.2(postcss@8.4.48) - postcss-normalize-unicode: 6.1.0(postcss@8.4.48) - postcss-normalize-url: 6.0.2(postcss@8.4.48) - postcss-normalize-whitespace: 6.0.2(postcss@8.4.48) - postcss-ordered-values: 6.0.2(postcss@8.4.48) - postcss-reduce-initial: 6.1.0(postcss@8.4.48) - postcss-reduce-transforms: 6.0.2(postcss@8.4.48) - postcss-svgo: 6.0.3(postcss@8.4.48) - postcss-unique-selectors: 6.0.4(postcss@8.4.48) - - cssnano-utils@4.0.2(postcss@8.4.48): - dependencies: - postcss: 8.4.48 - - cssnano@6.1.2(postcss@8.4.48): - dependencies: - cssnano-preset-default: 6.1.2(postcss@8.4.48) + css-declaration-sorter: 7.2.0(postcss@8.4.49) + cssnano-utils: 4.0.2(postcss@8.4.49) + postcss: 8.4.49 + postcss-calc: 9.0.1(postcss@8.4.49) + postcss-colormin: 6.1.0(postcss@8.4.49) + postcss-convert-values: 6.1.0(postcss@8.4.49) + postcss-discard-comments: 6.0.2(postcss@8.4.49) + postcss-discard-duplicates: 6.0.3(postcss@8.4.49) + postcss-discard-empty: 6.0.3(postcss@8.4.49) + postcss-discard-overridden: 6.0.2(postcss@8.4.49) + postcss-merge-longhand: 6.0.5(postcss@8.4.49) + postcss-merge-rules: 6.1.1(postcss@8.4.49) + postcss-minify-font-values: 6.1.0(postcss@8.4.49) + postcss-minify-gradients: 6.0.3(postcss@8.4.49) + postcss-minify-params: 6.1.0(postcss@8.4.49) + postcss-minify-selectors: 6.0.4(postcss@8.4.49) + postcss-normalize-charset: 6.0.2(postcss@8.4.49) + postcss-normalize-display-values: 6.0.2(postcss@8.4.49) + postcss-normalize-positions: 6.0.2(postcss@8.4.49) + postcss-normalize-repeat-style: 6.0.2(postcss@8.4.49) + postcss-normalize-string: 6.0.2(postcss@8.4.49) + postcss-normalize-timing-functions: 6.0.2(postcss@8.4.49) + postcss-normalize-unicode: 6.1.0(postcss@8.4.49) + postcss-normalize-url: 6.0.2(postcss@8.4.49) + postcss-normalize-whitespace: 6.0.2(postcss@8.4.49) + postcss-ordered-values: 6.0.2(postcss@8.4.49) + postcss-reduce-initial: 6.1.0(postcss@8.4.49) + postcss-reduce-transforms: 6.0.2(postcss@8.4.49) + postcss-svgo: 6.0.3(postcss@8.4.49) + postcss-unique-selectors: 6.0.4(postcss@8.4.49) + + cssnano-utils@4.0.2(postcss@8.4.49): + dependencies: + postcss: 8.4.49 + + cssnano@6.1.2(postcss@8.4.49): + dependencies: + cssnano-preset-default: 6.1.2(postcss@8.4.49) lilconfig: 3.1.2 - postcss: 8.4.48 + postcss: 8.4.49 csso@5.0.5: dependencies: @@ -18239,7 +18294,7 @@ snapshots: dependencies: jake: 10.9.2 - electron-to-chromium@1.5.55: {} + electron-to-chromium@1.5.56: {} emittery@0.13.1: {} @@ -18682,7 +18737,7 @@ snapshots: extract-zip@2.0.1: dependencies: - debug: 4.3.4 + debug: 4.3.7(supports-color@5.5.0) get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -19671,9 +19726,9 @@ snapshots: dependencies: safer-buffer: 2.1.2 - icss-utils@5.1.0(postcss@8.4.48): + icss-utils@5.1.0(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 ieee754@1.2.1: {} @@ -20535,7 +20590,7 @@ snapshots: '@npmcli/arborist': 7.5.4 '@npmcli/package-json': 5.2.0 '@npmcli/run-script': 8.1.0 - '@nx/devkit': 20.0.12(nx@20.0.12) + '@nx/devkit': 20.1.0(nx@20.1.0) '@octokit/plugin-enterprise-rest': 6.0.1 '@octokit/rest': 19.0.11(encoding@0.1.13) aproba: 2.0.0 @@ -20580,7 +20635,7 @@ snapshots: npm-package-arg: 11.0.2 npm-packlist: 8.0.2 npm-registry-fetch: 17.1.0 - nx: 20.0.12 + nx: 20.1.0 p-map: 4.0.0 p-map-series: 2.1.0 p-pipe: 3.1.0 @@ -21958,7 +22013,7 @@ snapshots: schema-utils: 3.3.0 webpack: 5.96.1 - nx@20.0.12: + nx@20.1.0: dependencies: '@napi-rs/wasm-runtime': 0.2.4 '@yarnpkg/lockfile': 1.1.0 @@ -21993,16 +22048,16 @@ snapshots: yargs: 17.7.2 yargs-parser: 21.1.1 optionalDependencies: - '@nx/nx-darwin-arm64': 20.0.12 - '@nx/nx-darwin-x64': 20.0.12 - '@nx/nx-freebsd-x64': 20.0.12 - '@nx/nx-linux-arm-gnueabihf': 20.0.12 - '@nx/nx-linux-arm64-gnu': 20.0.12 - '@nx/nx-linux-arm64-musl': 20.0.12 - '@nx/nx-linux-x64-gnu': 20.0.12 - '@nx/nx-linux-x64-musl': 20.0.12 - '@nx/nx-win32-arm64-msvc': 20.0.12 - '@nx/nx-win32-x64-msvc': 20.0.12 + '@nx/nx-darwin-arm64': 20.1.0 + '@nx/nx-darwin-x64': 20.1.0 + '@nx/nx-freebsd-x64': 20.1.0 + '@nx/nx-linux-arm-gnueabihf': 20.1.0 + '@nx/nx-linux-arm64-gnu': 20.1.0 + '@nx/nx-linux-arm64-musl': 20.1.0 + '@nx/nx-linux-x64-gnu': 20.1.0 + '@nx/nx-linux-x64-musl': 20.1.0 + '@nx/nx-win32-arm64-msvc': 20.1.0 + '@nx/nx-win32-x64-msvc': 20.1.0 transitivePeerDependencies: - debug @@ -22103,7 +22158,7 @@ snapshots: openai@4.69.0(encoding@0.1.13)(zod@3.23.8): dependencies: '@types/node': 18.19.64 - '@types/node-fetch': 2.6.11 + '@types/node-fetch': 2.6.12 abort-controller: 3.0.0 agentkeepalive: 4.5.0 form-data-encoder: 1.7.2 @@ -22618,195 +22673,195 @@ snapshots: path-data-parser: 0.1.0 points-on-curve: 0.2.0 - postcss-calc@9.0.1(postcss@8.4.48): + postcss-calc@9.0.1(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 postcss-value-parser: 4.2.0 - postcss-colormin@6.1.0(postcss@8.4.48): + postcss-colormin@6.1.0(postcss@8.4.49): dependencies: browserslist: 4.24.2 caniuse-api: 3.0.0 colord: 2.9.3 - postcss: 8.4.48 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-convert-values@6.1.0(postcss@8.4.48): + postcss-convert-values@6.1.0(postcss@8.4.49): dependencies: browserslist: 4.24.2 - postcss: 8.4.48 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-discard-comments@6.0.2(postcss@8.4.48): + postcss-discard-comments@6.0.2(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 - postcss-discard-duplicates@6.0.3(postcss@8.4.48): + postcss-discard-duplicates@6.0.3(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 - postcss-discard-empty@6.0.3(postcss@8.4.48): + postcss-discard-empty@6.0.3(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 - postcss-discard-overridden@6.0.2(postcss@8.4.48): + postcss-discard-overridden@6.0.2(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 - postcss-discard-unused@6.0.5(postcss@8.4.48): + postcss-discard-unused@6.0.5(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 - postcss-load-config@6.0.1(jiti@1.21.6)(postcss@8.4.48)(yaml@2.6.0): + postcss-load-config@6.0.1(jiti@1.21.6)(postcss@8.4.49)(yaml@2.6.0): dependencies: lilconfig: 3.1.2 optionalDependencies: jiti: 1.21.6 - postcss: 8.4.48 + postcss: 8.4.49 yaml: 2.6.0 - postcss-loader@7.3.4(postcss@8.4.48)(typescript@5.6.3)(webpack@5.96.1): + postcss-loader@7.3.4(postcss@8.4.49)(typescript@5.6.3)(webpack@5.96.1): dependencies: cosmiconfig: 8.3.6(typescript@5.6.3) jiti: 1.21.6 - postcss: 8.4.48 + postcss: 8.4.49 semver: 7.6.3 webpack: 5.96.1 transitivePeerDependencies: - typescript - postcss-merge-idents@6.0.3(postcss@8.4.48): + postcss-merge-idents@6.0.3(postcss@8.4.49): dependencies: - cssnano-utils: 4.0.2(postcss@8.4.48) - postcss: 8.4.48 + cssnano-utils: 4.0.2(postcss@8.4.49) + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-merge-longhand@6.0.5(postcss@8.4.48): + postcss-merge-longhand@6.0.5(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - stylehacks: 6.1.1(postcss@8.4.48) + stylehacks: 6.1.1(postcss@8.4.49) - postcss-merge-rules@6.1.1(postcss@8.4.48): + postcss-merge-rules@6.1.1(postcss@8.4.49): dependencies: browserslist: 4.24.2 caniuse-api: 3.0.0 - cssnano-utils: 4.0.2(postcss@8.4.48) - postcss: 8.4.48 + cssnano-utils: 4.0.2(postcss@8.4.49) + postcss: 8.4.49 postcss-selector-parser: 6.1.2 - postcss-minify-font-values@6.1.0(postcss@8.4.48): + postcss-minify-font-values@6.1.0(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-minify-gradients@6.0.3(postcss@8.4.48): + postcss-minify-gradients@6.0.3(postcss@8.4.49): dependencies: colord: 2.9.3 - cssnano-utils: 4.0.2(postcss@8.4.48) - postcss: 8.4.48 + cssnano-utils: 4.0.2(postcss@8.4.49) + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-minify-params@6.1.0(postcss@8.4.48): + postcss-minify-params@6.1.0(postcss@8.4.49): dependencies: browserslist: 4.24.2 - cssnano-utils: 4.0.2(postcss@8.4.48) - postcss: 8.4.48 + cssnano-utils: 4.0.2(postcss@8.4.49) + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-minify-selectors@6.0.4(postcss@8.4.48): + postcss-minify-selectors@6.0.4(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 - postcss-modules-extract-imports@3.1.0(postcss@8.4.48): + postcss-modules-extract-imports@3.1.0(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 - postcss-modules-local-by-default@4.0.5(postcss@8.4.48): + postcss-modules-local-by-default@4.1.0(postcss@8.4.49): dependencies: - icss-utils: 5.1.0(postcss@8.4.48) - postcss: 8.4.48 - postcss-selector-parser: 6.1.2 + icss-utils: 5.1.0(postcss@8.4.49) + postcss: 8.4.49 + postcss-selector-parser: 7.0.0 postcss-value-parser: 4.2.0 - postcss-modules-scope@3.2.0(postcss@8.4.48): + postcss-modules-scope@3.2.1(postcss@8.4.49): dependencies: - postcss: 8.4.48 - postcss-selector-parser: 6.1.2 + postcss: 8.4.49 + postcss-selector-parser: 7.0.0 - postcss-modules-values@4.0.0(postcss@8.4.48): + postcss-modules-values@4.0.0(postcss@8.4.49): dependencies: - icss-utils: 5.1.0(postcss@8.4.48) - postcss: 8.4.48 + icss-utils: 5.1.0(postcss@8.4.49) + postcss: 8.4.49 - postcss-normalize-charset@6.0.2(postcss@8.4.48): + postcss-normalize-charset@6.0.2(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 - postcss-normalize-display-values@6.0.2(postcss@8.4.48): + postcss-normalize-display-values@6.0.2(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-normalize-positions@6.0.2(postcss@8.4.48): + postcss-normalize-positions@6.0.2(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-normalize-repeat-style@6.0.2(postcss@8.4.48): + postcss-normalize-repeat-style@6.0.2(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-normalize-string@6.0.2(postcss@8.4.48): + postcss-normalize-string@6.0.2(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-normalize-timing-functions@6.0.2(postcss@8.4.48): + postcss-normalize-timing-functions@6.0.2(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-normalize-unicode@6.1.0(postcss@8.4.48): + postcss-normalize-unicode@6.1.0(postcss@8.4.49): dependencies: browserslist: 4.24.2 - postcss: 8.4.48 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-normalize-url@6.0.2(postcss@8.4.48): + postcss-normalize-url@6.0.2(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-normalize-whitespace@6.0.2(postcss@8.4.48): + postcss-normalize-whitespace@6.0.2(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-ordered-values@6.0.2(postcss@8.4.48): + postcss-ordered-values@6.0.2(postcss@8.4.49): dependencies: - cssnano-utils: 4.0.2(postcss@8.4.48) - postcss: 8.4.48 + cssnano-utils: 4.0.2(postcss@8.4.49) + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-reduce-idents@6.0.3(postcss@8.4.48): + postcss-reduce-idents@6.0.3(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 postcss-value-parser: 4.2.0 - postcss-reduce-initial@6.1.0(postcss@8.4.48): + postcss-reduce-initial@6.1.0(postcss@8.4.49): dependencies: browserslist: 4.24.2 caniuse-api: 3.0.0 - postcss: 8.4.48 + postcss: 8.4.49 - postcss-reduce-transforms@6.0.2(postcss@8.4.48): + postcss-reduce-transforms@6.0.2(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 postcss-value-parser: 4.2.0 postcss-selector-parser@6.1.2: @@ -22814,29 +22869,34 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-sort-media-queries@5.2.0(postcss@8.4.48): + postcss-selector-parser@7.0.0: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-sort-media-queries@5.2.0(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 sort-css-media-queries: 2.2.0 - postcss-svgo@6.0.3(postcss@8.4.48): + postcss-svgo@6.0.3(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 postcss-value-parser: 4.2.0 svgo: 3.3.2 - postcss-unique-selectors@6.0.4(postcss@8.4.48): + postcss-unique-selectors@6.0.4(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 postcss-value-parser@4.2.0: {} - postcss-zindex@6.0.2(postcss@8.4.48): + postcss-zindex@6.0.2(postcss@8.4.49): dependencies: - postcss: 8.4.48 + postcss: 8.4.49 - postcss@8.4.48: + postcss@8.4.49: dependencies: nanoid: 3.3.7 picocolors: 1.1.1 @@ -23698,7 +23758,7 @@ snapshots: dependencies: escalade: 3.2.0 picocolors: 1.1.1 - postcss: 8.4.48 + postcss: 8.4.49 strip-json-comments: 3.1.1 run-async@2.4.1: {} @@ -24185,9 +24245,9 @@ snapshots: dependencies: minipass: 7.1.2 - sswr@2.1.0(svelte@5.1.14): + sswr@2.1.0(svelte@5.1.15): dependencies: - svelte: 5.1.14 + svelte: 5.1.15 swrev: 4.0.0 stack-utils@2.0.6: @@ -24313,10 +24373,10 @@ snapshots: dependencies: inline-style-parser: 0.2.4 - stylehacks@6.1.1(postcss@8.4.48): + stylehacks@6.1.1(postcss@8.4.49): dependencies: browserslist: 4.24.2 - postcss: 8.4.48 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 stylis@4.3.4: {} @@ -24354,7 +24414,7 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte@5.1.14: + svelte@5.1.15: dependencies: '@ampproject/remapping': 2.3.0 '@jridgewell/sourcemap-codec': 1.5.0 @@ -24569,7 +24629,7 @@ snapshots: together-ai@0.7.0(encoding@0.1.13): dependencies: '@types/node': 18.19.64 - '@types/node-fetch': 2.6.11 + '@types/node-fetch': 2.6.12 abort-controller: 3.0.0 agentkeepalive: 4.5.0 form-data-encoder: 1.7.2 @@ -24673,7 +24733,7 @@ snapshots: tslib@2.8.0: {} - tsup@8.3.5(jiti@1.21.6)(postcss@8.4.48)(typescript@5.6.3)(yaml@2.6.0): + tsup@8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0): dependencies: bundle-require: 5.0.0(esbuild@0.24.0) cac: 6.7.14 @@ -24683,7 +24743,7 @@ snapshots: esbuild: 0.24.0 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@1.21.6)(postcss@8.4.48)(yaml@2.6.0) + postcss-load-config: 6.0.1(jiti@1.21.6)(postcss@8.4.49)(yaml@2.6.0) resolve-from: 5.0.0 rollup: 4.25.0 source-map: 0.8.0-beta.0 @@ -24692,7 +24752,7 @@ snapshots: tinyglobby: 0.2.10 tree-kill: 1.2.2 optionalDependencies: - postcss: 8.4.48 + postcss: 8.4.49 typescript: 5.6.3 transitivePeerDependencies: - jiti From cfae1029996cded2b32c116b2272421246b25ee4 Mon Sep 17 00:00:00 2001 From: ponderingdemocritus Date: Tue, 12 Nov 2024 18:47:08 +1100 Subject: [PATCH 3/5] jest --- packages/test/ jest.config.ts | 16 ++++++++++++++++ packages/test/src/tests/providers.test.ts | 8 +------- 2 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 packages/test/ jest.config.ts diff --git a/packages/test/ jest.config.ts b/packages/test/ jest.config.ts new file mode 100644 index 00000000000..13974b484f4 --- /dev/null +++ b/packages/test/ jest.config.ts @@ -0,0 +1,16 @@ +export default { + preset: "ts-jest", + testEnvironment: "node", + extensionsToTreatAsEsm: [".ts"], + moduleNameMapper: { + "^(\\.{1,2}/.*)\\.js$": "$1", + }, + transform: { + "^.+\\.tsx?$": [ + "ts-jest", + { + useESM: true, + }, + ], + }, +}; diff --git a/packages/test/src/tests/providers.test.ts b/packages/test/src/tests/providers.test.ts index c5c60fbea0e..3629c752900 100644 --- a/packages/test/src/tests/providers.test.ts +++ b/packages/test/src/tests/providers.test.ts @@ -1,13 +1,7 @@ import dotenv from "dotenv"; import { zeroUuid } from "../test_resources/constants.js"; import { createRuntime } from "../test_resources/createRuntime.js"; -import { - IAgentRuntime, - type Memory, - type Provider, - type State, - type UUID, -} from "@ai16z/eliza"; +import { IAgentRuntime, Memory, Provider, State, UUID } from "@ai16z/eliza"; dotenv.config({ path: ".dev.vars" }); From 90adb755792d166dbde6216854f184225d4ec8b1 Mon Sep 17 00:00:00 2001 From: ponderingdemocritus Date: Tue, 12 Nov 2024 18:56:18 +1100 Subject: [PATCH 4/5] vitest --- packages/test/package.json | 24 ++++--- packages/test/src/tests/actions.test.ts | 96 ++++++++++++++----------- 2 files changed, 68 insertions(+), 52 deletions(-) diff --git a/packages/test/package.json b/packages/test/package.json index 70e42406c82..9017a50a914 100644 --- a/packages/test/package.json +++ b/packages/test/package.json @@ -5,25 +5,29 @@ "type": "module", "types": "dist/index.d.ts", "dependencies": { - "@ai16z/eliza": "workspace:*", - "@ai16z/plugin-solana": "workspace:*", - "@ai16z/plugin-node": "workspace:*", - "@ai16z/plugin-bootstrap": "workspace:*", + "@ai16z/adapter-sqlite": "workspace:*", "@ai16z/adapter-sqljs": "workspace:*", "@ai16z/adapter-supabase": "workspace:*", - "@ai16z/adapter-sqlite": "workspace:*", - "tsup": "^8.3.5", + "@ai16z/eliza": "workspace:*", + "@ai16z/plugin-bootstrap": "workspace:*", + "@ai16z/plugin-node": "workspace:*", + "@ai16z/plugin-solana": "workspace:*", + "@coral-xyz/anchor": "^0.30.1", "@solana/spl-token": "0.4.9", "@solana/web3.js": "1.95.4", - "@coral-xyz/anchor": "^0.30.1", + "@types/jest": "^29.5.14", "bignumber": "1.1.0", "bignumber.js": "9.1.2", + "jest": "^29.7.0", + "node-cache": "5.1.2", "pumpdotfun-sdk": "1.3.2", - "node-cache": "5.1.2" + "ts-jest": "^29.2.5", + "tsup": "^8.3.5", + "vitest": "^2.1.4" }, "scripts": { - "test": "jest --runInBand", - "test:watch": "jest --runInBand --watch" + "test": "vitest", + "test:watch": "vitest --watch" }, "peerDependencies": { "whatwg-url": "7.1.0" diff --git a/packages/test/src/tests/actions.test.ts b/packages/test/src/tests/actions.test.ts index c7050d0563c..c8a016e5d17 100644 --- a/packages/test/src/tests/actions.test.ts +++ b/packages/test/src/tests/actions.test.ts @@ -1,18 +1,19 @@ import dotenv from "dotenv"; +import { describe, test, expect, beforeAll, afterAll } from "vitest"; import { createRuntime } from "../test_resources/createRuntime.js"; import { getOrCreateRelationship } from "../test_resources/getOrCreateRelationship.js"; import { runAiTest } from "../test_resources/runAiTest.js"; import { messageHandlerTemplate } from "../test_resources/templates.js"; import { TEST_ACTION, TEST_ACTION_FAIL } from "../test_resources/testAction.js"; -import { type User } from "../test_resources/types.js"; +import { User } from "../test_resources/types.js"; import { MemoryManager, Content, IAgentRuntime, ModelClass, State, - type Memory, - type UUID, + Memory, + UUID, stringToUuid, composeContext, generateMessageResponse, @@ -220,46 +221,57 @@ describe("Actions", () => { }); // Validate that TEST_ACTION is in the state - test("Validate that TEST_ACTION is in the state", async () => { - await runAiTest("Validate TEST_ACTION is in the state", async () => { - const message: Memory = { - agentId: runtime.agentId, - userId: user.id as UUID, - content: { - text: "Please respond with the message 'ok' and the action TEST_ACTION", - }, - roomId, - }; - - const response = await handleMessage(runtime, message); - return response.action === "TEST_ACTION"; // Return true if the expected action matches - }); - }, 60000); + test( + "Validate that TEST_ACTION is in the state", + async () => { + await runAiTest( + "Validate TEST_ACTION is in the state", + async () => { + const message: Memory = { + agentId: runtime.agentId, + userId: user.id as UUID, + content: { + text: "Please respond with the message 'ok' and the action TEST_ACTION", + }, + roomId, + }; + + const response = await handleMessage(runtime, message); + return response.action === "TEST_ACTION"; // Return true if the expected action matches + } + ); + }, + { timeout: 60000 } + ); // Test that TEST_ACTION action handler is called properly - test("Test action handler is called", async () => { - await runAiTest("Test action handler is called", async () => { - const testAction = runtime.actions.find( - (action) => action.name === "TEST_ACTION" - ); - if (!testAction || !testAction.handler) { - console.error( - "Continue action or its handler function is undefined" + test( + "Test action handler is called", + async () => { + await runAiTest("Test action handler is called", async () => { + const testAction = runtime.actions.find( + (action) => action.name === "TEST_ACTION" ); - return false; // Return false to indicate the test setup failed - } - - const mockMessage: Memory = { - userId: user.id as UUID, - agentId: runtime.agentId, - content: { - text: "Test message for TEST action", - }, - roomId, - }; - - const response = await testAction.handler(runtime, mockMessage); - return response !== undefined; // Return true if the handler returns a defined response - }); - }, 60000); // You can adjust the timeout if needed + if (!testAction || !testAction.handler) { + console.error( + "Continue action or its handler function is undefined" + ); + return false; // Return false to indicate the test setup failed + } + + const mockMessage: Memory = { + userId: user.id as UUID, + agentId: runtime.agentId, + content: { + text: "Test message for TEST action", + }, + roomId, + }; + + const response = await testAction.handler(runtime, mockMessage); + return response !== undefined; // Return true if the handler returns a defined response + }); + }, + { timeout: 60000 } + ); // You can adjust the timeout if needed }); From 4f6c0dece7ac2e24143afa54584bae9d2ed0751d Mon Sep 17 00:00:00 2001 From: ponderingdemocritus Date: Tue, 12 Nov 2024 19:52:25 +1100 Subject: [PATCH 5/5] imports --- packages/agent/src/index.ts | 32 +- packages/plugin-solana/src/index.ts | 2 - packages/plugin-solana/tsconfig.json | 3 +- pnpm-lock.yaml | 540 ++++++++++++++++++++++++++- scripts/build.sh | 5 + 5 files changed, 558 insertions(+), 24 deletions(-) diff --git a/packages/agent/src/index.ts b/packages/agent/src/index.ts index 825b607d53e..1d968d90798 100644 --- a/packages/agent/src/index.ts +++ b/packages/agent/src/index.ts @@ -1,22 +1,22 @@ -import { PostgresDatabaseAdapter } from "@ai16z/adapter-postgres/src/index.ts"; -import { SqliteDatabaseAdapter } from "@ai16z/adapter-sqlite/src/index.ts"; -import { DirectClientInterface } from "@ai16z/client-direct/src/index.ts"; -import { DiscordClientInterface } from "@ai16z/client-discord/src/index.ts"; -import { AutoClientInterface } from "@ai16z/client-auto/src/index.ts"; -import { TelegramClientInterface } from "@ai16z/client-telegram/src/index.ts"; -import { TwitterClientInterface } from "@ai16z/client-twitter/src/index.ts"; -import { defaultCharacter } from "@ai16z/eliza/src/defaultCharacter.ts"; -import { AgentRuntime } from "@ai16z/eliza/src/runtime.ts"; -import settings from "@ai16z/eliza/src/settings.ts"; +import { PostgresDatabaseAdapter } from "@ai16z/adapter-postgres"; +import { SqliteDatabaseAdapter } from "@ai16z/adapter-sqlite"; +import { DirectClientInterface } from "@ai16z/client-direct"; +import { DiscordClientInterface } from "@ai16z/client-discord"; +import { AutoClientInterface } from "@ai16z/client-auto"; +import { TelegramClientInterface } from "@ai16z/client-telegram"; +import { TwitterClientInterface } from "@ai16z/client-twitter"; +import { defaultCharacter } from "@ai16z/eliza"; +import { AgentRuntime } from "@ai16z/eliza"; +import { settings } from "@ai16z/eliza"; import { Character, IAgentRuntime, IDatabaseAdapter, ModelProviderName, -} from "@ai16z/eliza/src/types.ts"; -import { bootstrapPlugin } from "@ai16z/plugin-bootstrap/src/index.ts"; -import { solanaPlugin } from "@ai16z/plugin-solana/src/index.ts"; -import { nodePlugin } from "@ai16z/plugin-node/src/index.ts"; +} from "@ai16z/eliza"; +import { bootstrapPlugin } from "@ai16z/plugin-bootstrap"; +import { solanaPlugin } from "@ai16z/plugin-solana"; +import { nodePlugin } from "@ai16z/plugin-node"; import Database from "better-sqlite3"; import fs from "fs"; import readline from "readline"; @@ -223,9 +223,7 @@ export async function createAgent( plugins: [ bootstrapPlugin, nodePlugin, - character.settings.secrets.WALLET_PUBLIC_KEY - ? solanaPlugin - : null + character.settings.secrets.WALLET_PUBLIC_KEY ? solanaPlugin : null, ].filter(Boolean), providers: [], actions: [], diff --git a/packages/plugin-solana/src/index.ts b/packages/plugin-solana/src/index.ts index dc65ac0bf88..939439ade11 100644 --- a/packages/plugin-solana/src/index.ts +++ b/packages/plugin-solana/src/index.ts @@ -21,5 +21,3 @@ export const solanaPlugin: Plugin = { evaluators: [trustEvaluator], providers: [walletProvider, trustScoreProvider], }; - -export default solanaPlugin; diff --git a/packages/plugin-solana/tsconfig.json b/packages/plugin-solana/tsconfig.json index eaa78145aa3..ea7ea435e3e 100644 --- a/packages/plugin-solana/tsconfig.json +++ b/packages/plugin-solana/tsconfig.json @@ -2,7 +2,8 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "dist", - "rootDir": "./src" + "rootDir": ".", + "types": ["node"] }, "include": ["src"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 08530df2c2e..e4817509e8d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -509,7 +509,7 @@ importers: version: 2.79.2 ts-jest: specifier: 29.2.5 - version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@22.8.4)(ts-node@10.9.2(@types/node@22.8.4)(typescript@5.6.3)))(typescript@5.6.3) + version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@22.8.4))(typescript@5.6.3) ts-node: specifier: 10.9.2 version: 10.9.2(@types/node@22.8.4)(typescript@5.6.3) @@ -778,21 +778,33 @@ importers: '@solana/web3.js': specifier: 1.95.4 version: 1.95.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@types/jest': + specifier: ^29.5.14 + version: 29.5.14 bignumber: specifier: 1.1.0 version: 1.1.0 bignumber.js: specifier: 9.1.2 version: 9.1.2 + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@22.8.4)(ts-node@10.9.2(@types/node@22.8.4)(typescript@5.6.3)) node-cache: specifier: 5.1.2 version: 5.1.2 pumpdotfun-sdk: specifier: 1.3.2 version: 1.3.2(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(rollup@4.25.0)(typescript@5.6.3)(utf-8-validate@5.0.10) + ts-jest: + specifier: ^29.2.5 + version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@22.8.4))(typescript@5.6.3) tsup: specifier: ^8.3.5 version: 8.3.5(jiti@1.21.6)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.0) + vitest: + specifier: ^2.1.4 + version: 2.1.4(@types/node@22.8.4)(terser@5.36.0) whatwg-url: specifier: 7.1.0 version: 7.1.0 @@ -2062,108 +2074,216 @@ packages: '@emnapi/wasi-threads@1.0.1': resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.24.0': resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.24.0': resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.24.0': resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.24.0': resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.24.0': resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.24.0': resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.24.0': resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.24.0': resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.24.0': resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.24.0': resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.24.0': resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.24.0': resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.24.0': resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.24.0': resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.24.0': resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.24.0': resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.24.0': resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.24.0': resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} engines: {node: '>=18'} @@ -2176,30 +2296,60 @@ packages: cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.24.0': resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.24.0': resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.24.0': resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.24.0': resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.24.0': resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} engines: {node: '>=18'} @@ -4011,6 +4161,35 @@ packages: '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + '@vitest/expect@2.1.4': + resolution: {integrity: sha512-DOETT0Oh1avie/D/o2sgMHGrzYUFFo3zqESB2Hn70z6QB1HrS2IQ9z5DfyTqU8sg4Bpu13zZe9V4+UTNQlUeQA==} + + '@vitest/mocker@2.1.4': + resolution: {integrity: sha512-Ky/O1Lc0QBbutJdW0rqLeFNbuLEyS+mIPiNdlVlp2/yhJ0SbyYqObS5IHdhferJud8MbbwMnexg4jordE5cCoQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.1.4': + resolution: {integrity: sha512-L95zIAkEuTDbUX1IsjRl+vyBSLh3PwLLgKpghl37aCK9Jvw0iP+wKwIFhfjdUtA2myLgjrG6VU6JCFLv8q/3Ww==} + + '@vitest/runner@2.1.4': + resolution: {integrity: sha512-sKRautINI9XICAMl2bjxQM8VfCMTB0EbsBc/EDFA57V6UQevEKY/TOPOF5nzcvCALltiLfXWbq4MaAwWx/YxIA==} + + '@vitest/snapshot@2.1.4': + resolution: {integrity: sha512-3Kab14fn/5QZRog5BPj6Rs8dc4B+mim27XaKWFWHWA87R56AKjHTGcBFKpvZKDzC4u5Wd0w/qKsUIio3KzWW4Q==} + + '@vitest/spy@2.1.4': + resolution: {integrity: sha512-4JOxa+UAizJgpZfaCPKK2smq9d8mmjZVPMt2kOsg/R8QkoRzydHH1qHxIYNvr1zlEaFj4SXiaaJWxq/LPLKaLg==} + + '@vitest/utils@2.1.4': + resolution: {integrity: sha512-MXDnZn0Awl2S86PSNIim5PWXgIAx8CIkzu35mBdSApUip6RFOGXBCf3YFyeEu8n1IHk4bWD46DeYFu9mQlFIRg==} + '@vladfrangu/async_event_emitter@2.4.6': resolution: {integrity: sha512-RaI5qZo6D2CVS6sTHFKg1v5Ohq/+Bo2LZ5gzUEwZ/WkHhwtGTCB/sVLw8ijOkAUxasZ+WshN/Rzj4ywsABJ5ZA==} engines: {node: '>=v14.0.0', npm: '>=7.0.0'} @@ -4366,6 +4545,10 @@ packages: resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} engines: {node: '>=0.8'} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + ast-types@0.13.4: resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} engines: {node: '>=4'} @@ -4737,6 +4920,10 @@ packages: ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chai@5.1.2: + resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} + engines: {node: '>=12'} + chalk@3.0.0: resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} engines: {node: '>=8'} @@ -4775,6 +4962,10 @@ packages: charm@0.1.2: resolution: {integrity: sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ==} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} @@ -5588,6 +5779,10 @@ packages: babel-plugin-macros: optional: true + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} @@ -5932,6 +6127,11 @@ packages: esast-util-from-js@2.0.1: resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + esbuild@0.24.0: resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} engines: {node: '>=18'} @@ -6150,6 +6350,10 @@ packages: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} + expect-type@1.1.0: + resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} + engines: {node: '>=12.0.0'} + expect@29.7.0: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -7834,6 +8038,9 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + loupe@3.1.2: + resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} + lowdb@7.0.1: resolution: {integrity: sha512-neJAj8GwF0e8EpycYIDFqEPcx9Qz4GUho20jWFR7YiFeXzF1YMLdxB36PypcTSPMA+4+LvgyMacYhlr18Zlymw==} engines: {node: '>=18'} @@ -9017,6 +9224,10 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + pdfjs-dist@4.7.76: resolution: {integrity: sha512-8y6wUgC/Em35IumlGjaJOCm3wV4aY/6sqnIT3fVW/67mXsOZ9HWBn8GDKmJUK0GSzpbmX3gQqwfoFayp78Mtqw==} engines: {node: '>=18'} @@ -10271,6 +10482,9 @@ packages: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -10479,6 +10693,9 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} @@ -10788,6 +11005,9 @@ packages: tiny-warning@1.0.3: resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + tinyexec@0.3.1: resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} @@ -10800,10 +11020,22 @@ packages: engines: {node: '>= 12.10.0', npm: '>= 6.12.0', yarn: '>= 1.20.0'} hasBin: true + tinypool@1.0.1: + resolution: {integrity: sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + tinyspawn@1.3.3: resolution: {integrity: sha512-CvvMFgecnQMyg59nOnAD5O4lV83cVj2ooDniJ3j2bYvMajqlK4wQ13k6OUHfA+J5nkInTxbSGJv2olUJIiAtJg==} engines: {node: '>= 18'} + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + tldts-core@6.1.60: resolution: {integrity: sha512-XHjoxak8SFQnHnmYHb3PcnW5TZ+9ErLZemZei3azuIRhQLw4IExsVbL3VZJdHcLeNaXq6NqawgpDPpjBOg4B5g==} @@ -11297,6 +11529,67 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite-node@2.1.4: + resolution: {integrity: sha512-kqa9v+oi4HwkG6g8ufRnb5AeplcRw8jUF6/7/Qz1qRQOXHImG8YnLbB+LLszENwFnoBl9xIf9nVdCFzNd7GQEg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.4.11: + resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@2.1.4: + resolution: {integrity: sha512-eDjxbVAJw1UJJCHr5xr/xM86Zx+YxIEXGAR+bmnEID7z9qWfoxpHw0zdobz+TQAFOLT+nEXz3+gx6nUJ7RgmlQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.4 + '@vitest/ui': 2.1.4 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + vizion@2.2.1: resolution: {integrity: sha512-sfAcO2yeSU0CSPFI/DmZp3FsFE9T+8913nv1xWBOyzODv13fwkn6Vl7HqxGpkr9F608M+8SuFId3s+BlZqfXww==} engines: {node: '>=4.0'} @@ -11456,6 +11749,11 @@ packages: engines: {node: ^16.13.0 || >=18.0.0} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + wide-align@1.1.5: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} @@ -13902,75 +14200,144 @@ snapshots: dependencies: tslib: 2.8.0 + '@esbuild/aix-ppc64@0.21.5': + optional: true + '@esbuild/aix-ppc64@0.24.0': optional: true + '@esbuild/android-arm64@0.21.5': + optional: true + '@esbuild/android-arm64@0.24.0': optional: true + '@esbuild/android-arm@0.21.5': + optional: true + '@esbuild/android-arm@0.24.0': optional: true + '@esbuild/android-x64@0.21.5': + optional: true + '@esbuild/android-x64@0.24.0': optional: true + '@esbuild/darwin-arm64@0.21.5': + optional: true + '@esbuild/darwin-arm64@0.24.0': optional: true + '@esbuild/darwin-x64@0.21.5': + optional: true + '@esbuild/darwin-x64@0.24.0': optional: true + '@esbuild/freebsd-arm64@0.21.5': + optional: true + '@esbuild/freebsd-arm64@0.24.0': optional: true + '@esbuild/freebsd-x64@0.21.5': + optional: true + '@esbuild/freebsd-x64@0.24.0': optional: true + '@esbuild/linux-arm64@0.21.5': + optional: true + '@esbuild/linux-arm64@0.24.0': optional: true + '@esbuild/linux-arm@0.21.5': + optional: true + '@esbuild/linux-arm@0.24.0': optional: true + '@esbuild/linux-ia32@0.21.5': + optional: true + '@esbuild/linux-ia32@0.24.0': optional: true + '@esbuild/linux-loong64@0.21.5': + optional: true + '@esbuild/linux-loong64@0.24.0': optional: true + '@esbuild/linux-mips64el@0.21.5': + optional: true + '@esbuild/linux-mips64el@0.24.0': optional: true + '@esbuild/linux-ppc64@0.21.5': + optional: true + '@esbuild/linux-ppc64@0.24.0': optional: true + '@esbuild/linux-riscv64@0.21.5': + optional: true + '@esbuild/linux-riscv64@0.24.0': optional: true + '@esbuild/linux-s390x@0.21.5': + optional: true + '@esbuild/linux-s390x@0.24.0': optional: true + '@esbuild/linux-x64@0.21.5': + optional: true + '@esbuild/linux-x64@0.24.0': optional: true + '@esbuild/netbsd-x64@0.21.5': + optional: true + '@esbuild/netbsd-x64@0.24.0': optional: true '@esbuild/openbsd-arm64@0.24.0': optional: true + '@esbuild/openbsd-x64@0.21.5': + optional: true + '@esbuild/openbsd-x64@0.24.0': optional: true + '@esbuild/sunos-x64@0.21.5': + optional: true + '@esbuild/sunos-x64@0.24.0': optional: true + '@esbuild/win32-arm64@0.21.5': + optional: true + '@esbuild/win32-arm64@0.24.0': optional: true + '@esbuild/win32-ia32@0.21.5': + optional: true + '@esbuild/win32-ia32@0.24.0': optional: true + '@esbuild/win32-x64@0.21.5': + optional: true + '@esbuild/win32-x64@0.24.0': optional: true @@ -16260,6 +16627,46 @@ snapshots: '@ungap/structured-clone@1.2.0': {} + '@vitest/expect@2.1.4': + dependencies: + '@vitest/spy': 2.1.4 + '@vitest/utils': 2.1.4 + chai: 5.1.2 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.4(vite@5.4.11(@types/node@22.8.4)(terser@5.36.0))': + dependencies: + '@vitest/spy': 2.1.4 + estree-walker: 3.0.3 + magic-string: 0.30.12 + optionalDependencies: + vite: 5.4.11(@types/node@22.8.4)(terser@5.36.0) + + '@vitest/pretty-format@2.1.4': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.4': + dependencies: + '@vitest/utils': 2.1.4 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.4': + dependencies: + '@vitest/pretty-format': 2.1.4 + magic-string: 0.30.12 + pathe: 1.1.2 + + '@vitest/spy@2.1.4': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.1.4': + dependencies: + '@vitest/pretty-format': 2.1.4 + loupe: 3.1.2 + tinyrainbow: 1.2.0 + '@vladfrangu/async_event_emitter@2.4.6': {} '@vue/compiler-core@3.5.12': @@ -16670,6 +17077,8 @@ snapshots: assert-plus@1.0.0: {} + assertion-error@2.0.1: {} + ast-types@0.13.4: dependencies: tslib: 2.8.0 @@ -17138,6 +17547,14 @@ snapshots: ccount@2.0.1: {} + chai@5.1.2: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.2 + pathval: 2.0.0 + chalk@3.0.0: dependencies: ansi-styles: 4.3.0 @@ -17169,6 +17586,8 @@ snapshots: charm@0.1.2: {} + check-error@2.1.1: {} + cheerio-select@2.1.0: dependencies: boolbase: 1.0.0 @@ -18055,6 +18474,8 @@ snapshots: dedent@1.5.3: {} + deep-eql@5.0.2: {} + deep-extend@0.6.0: {} deep-is@0.1.4: {} @@ -18405,6 +18826,32 @@ snapshots: esast-util-from-estree: 2.0.0 vfile-message: 4.0.2 + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + esbuild@0.24.0: optionalDependencies: '@esbuild/aix-ppc64': 0.24.0 @@ -18673,6 +19120,8 @@ snapshots: expand-template@2.0.3: {} + expect-type@1.1.0: {} + expect@29.7.0: dependencies: '@jest/expect-utils': 29.7.0 @@ -18737,7 +19186,7 @@ snapshots: extract-zip@2.0.1: dependencies: - debug: 4.3.7(supports-color@5.5.0) + debug: 4.3.4 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -20822,7 +21271,7 @@ snapshots: log-symbols@4.1.0: dependencies: - chalk: 4.1.0 + chalk: 4.1.2 is-unicode-supported: 0.1.0 log-symbols@6.0.0: @@ -20851,6 +21300,8 @@ snapshots: dependencies: js-tokens: 4.0.0 + loupe@3.1.2: {} + lowdb@7.0.1: dependencies: steno: 4.0.2 @@ -22485,6 +22936,8 @@ snapshots: pathe@1.1.2: {} + pathval@2.0.0: {} + pdfjs-dist@4.7.76(encoding@0.1.13): optionalDependencies: canvas: 2.11.2(encoding@0.1.13) @@ -24014,6 +24467,8 @@ snapshots: get-intrinsic: 1.2.4 object-inspect: 1.13.3 + siginfo@2.0.0: {} + signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -24254,6 +24709,8 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 + stackback@0.0.2: {} + statuses@1.5.0: {} statuses@2.0.1: {} @@ -24592,6 +25049,8 @@ snapshots: tiny-warning@1.0.3: {} + tinybench@2.9.0: {} + tinyexec@0.3.1: {} tinyglobby@0.2.10: @@ -24601,8 +25060,14 @@ snapshots: tinyld@1.3.4: {} + tinypool@1.0.1: {} + + tinyrainbow@1.2.0: {} + tinyspawn@1.3.3: {} + tinyspy@3.0.2: {} + tldts-core@6.1.60: {} tldts-experimental@6.1.60: @@ -24684,7 +25149,7 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@22.8.4)(ts-node@10.9.2(@types/node@22.8.4)(typescript@5.6.3)))(typescript@5.6.3): + ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@22.8.4))(typescript@5.6.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 @@ -25086,6 +25551,68 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 + vite-node@2.1.4(@types/node@22.8.4)(terser@5.36.0): + dependencies: + cac: 6.7.14 + debug: 4.3.7(supports-color@5.5.0) + pathe: 1.1.2 + vite: 5.4.11(@types/node@22.8.4)(terser@5.36.0) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite@5.4.11(@types/node@22.8.4)(terser@5.36.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.49 + rollup: 4.25.0 + optionalDependencies: + '@types/node': 22.8.4 + fsevents: 2.3.3 + terser: 5.36.0 + + vitest@2.1.4(@types/node@22.8.4)(terser@5.36.0): + dependencies: + '@vitest/expect': 2.1.4 + '@vitest/mocker': 2.1.4(vite@5.4.11(@types/node@22.8.4)(terser@5.36.0)) + '@vitest/pretty-format': 2.1.4 + '@vitest/runner': 2.1.4 + '@vitest/snapshot': 2.1.4 + '@vitest/spy': 2.1.4 + '@vitest/utils': 2.1.4 + chai: 5.1.2 + debug: 4.3.7(supports-color@5.5.0) + expect-type: 1.1.0 + magic-string: 0.30.12 + pathe: 1.1.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.1 + tinypool: 1.0.1 + tinyrainbow: 1.2.0 + vite: 5.4.11(@types/node@22.8.4)(terser@5.36.0) + vite-node: 2.1.4(@types/node@22.8.4)(terser@5.36.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.8.4 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vizion@2.2.1: dependencies: async: 2.6.4 @@ -25319,6 +25846,11 @@ snapshots: dependencies: isexe: 3.1.1 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + wide-align@1.1.5: dependencies: string-width: 4.2.3 diff --git a/scripts/build.sh b/scripts/build.sh index e94f5d1e50c..57179f44f57 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -11,6 +11,11 @@ fi # Iterate over each directory in the packages directory for package in packages/*; do + # Skip the test directory + if [ "$(basename "$package")" = "test" ]; then + continue + fi + if [ -d "$package" ]; then echo "Building package: $(basename "$package")" cd "$package" || continue