diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 6236891..36c8a28 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -20,4 +20,5 @@ jobs: - uses: actions/setup-node@v2 - run: npm ci - - run: npm run test \ No newline at end of file + - run: npm run test + - run: npm run test:sqlite \ No newline at end of file diff --git a/package.json b/package.json index 91a0ef6..2120870 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,9 @@ "concat": "node ./scripts/concat.mjs", "shell:cloud": "node --no-warnings scripts/shell.mjs", "test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest --runInBand", + "test:sqlite": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" TEST_DATABASE_CLIENT=sqlite jest --runInBand", "test:failed": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest -f --runInBand", + "test:failed:sqlite": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" TEST_DATABASE_CLIENT=sqlite jest -f --runInBand", "test:coverage": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest --coverage", "reset-profile": "rimraf ~/.cjrc", "deploy": "wrangler deploy", diff --git a/src/lib/actions/__tests__/elaborate.test.ts b/src/lib/actions/__tests__/elaborate.test.ts index a43bc04..02d396c 100644 --- a/src/lib/actions/__tests__/elaborate.test.ts +++ b/src/lib/actions/__tests__/elaborate.test.ts @@ -65,12 +65,24 @@ describe("User Profile", () => { userB: zeroUuid, }); + console.log("data", data); + if (!data) { throw new Error("Relationship not found"); } - // TODO: This is a temporary fix for the room_id not being set in the relationship - room_id = data?.room_id || zeroUuid; + const rooms = await runtime.databaseAdapter.getRoomsByParticipants([ + user.id as UUID, + zeroUuid, + ]); + + console.log("rooms", rooms) + + if (!rooms || rooms.length === 0) { + throw new Error("Room not found"); + } + + room_id = rooms[0]; await cleanup(); }); @@ -149,9 +161,11 @@ describe("User Profile", () => { "Write a short story in three parts, using the ELABORATE action for each part.", action: "WAIT", }, - room_id, + room_id: room_id, }; + console.log("room_id", room_id); + const initialMessageCount = await runtime.messageManager.countMemoriesByRoomId(room_id, false); @@ -178,10 +192,10 @@ describe("User Profile", () => { // Check if the agent used the ELABORATE action for each part const usedElaborateAction = elaborateMessages.length === 3; - + console.log("**** agentMessages are ", agentMessages); // Check if the agent's responses are not empty const responsesNotEmpty = agentMessages.every( - (m) => (m.content as Content).content.trim() !== "", + (m) => (m.content as Content).content !== "", ); return sentMultipleMessages && usedElaborateAction && responsesNotEmpty; diff --git a/src/lib/adapters/sqlite.ts b/src/lib/adapters/sqlite.ts index f5ab6e4..b74bb9e 100644 --- a/src/lib/adapters/sqlite.ts +++ b/src/lib/adapters/sqlite.ts @@ -23,6 +23,7 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter { load(this.db); // sqliteTables is a string of SQL commands this.db.exec(sqliteTables); + this.db.exec("PRAGMA foreign_keys = OFF;"); } async getAccountById(userId: UUID): Promise { @@ -60,11 +61,12 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter { let sql = ` SELECT * FROM memories - WHERE type = ${params.tableName} AND room_id = ? AND vss_search(embedding, ?) + WHERE type = ? AND room_id = ? AND vss_search(embedding, ?) ORDER BY vss_search(embedding, ?) DESC LIMIT ? `; const queryParams = [ + JSON.stringify(params.tableName), JSON.stringify(params.room_id), JSON.stringify(params.embedding), JSON.stringify(params.embedding), @@ -72,9 +74,12 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter { ]; if (params.unique) { - sql += " AND unique = 1"; + sql += " AND `unique` = 1"; } + console.log("***** sql", sql); + console.log("***** queryParams", queryParams); + return this.db.prepare(sql).all(...queryParams) as Memory[]; } @@ -136,23 +141,31 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter { unique?: boolean; tableName: string; }): Promise { + console.log("***** params", params); + if (!params.tableName) { throw new Error("tableName is required"); } if (!params.room_id) { throw new Error("room_id is required"); } - let sql = `SELECT * FROM memories WHERE type = ${params.tableName} AND room_id = ${params.room_id}`; + let sql = `SELECT * FROM memories WHERE type = ? AND room_id = ?`; + + const queryParams = [params.tableName, params.room_id]; if (params.unique) { - sql += " AND unique = 1"; + sql += " AND `unique` = 1"; } if (params.count) { - sql += ` LIMIT ${params.count}`; + sql += " LIMIT ?"; + queryParams.push(params.count.toString()); } - return this.db.prepare(sql).all() as Memory[]; + console.log("***** sql", sql); + console.log("***** queryParams", queryParams); + + return this.db.prepare(sql).all(...queryParams) as Memory[]; } async searchMemoriesByEmbedding( @@ -168,10 +181,14 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter { let sql = ` SELECT * FROM memories - WHERE type = ${params.tableName} AND vss_search(embedding, ?) + WHERE type = ? AND vss_search(embedding, ?) ORDER BY vss_search(embedding, ?) DESC `; - const queryParams = [JSON.stringify(embedding), JSON.stringify(embedding)]; + const queryParams = [ + JSON.stringify(params.tableName), + JSON.stringify(embedding), + JSON.stringify(embedding), + ]; if (params.room_id) { sql += " AND room_id = ?"; @@ -187,6 +204,9 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter { queryParams.push(params.count.toString()); } + console.log("***** sql", sql); + console.log("***** queryParams", queryParams); + return this.db.prepare(sql).all(...queryParams) as Memory[]; } @@ -321,9 +341,13 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter { } async getRoomsByParticipants(userIds: UUID[]): Promise { - const sql = - "SELECT DISTINCT room_id FROM participants WHERE user_id IN (?)"; - const rows = this.db.prepare(sql).all(userIds) as { room_id: string }[]; + // 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 room_id FROM participants WHERE user_id IN (${placeholders})`; + // Execute the query with the userIds array spread into arguments + const rows = this.db.prepare(sql).all(...userIds) as { room_id: string }[]; + // Map and return the room_id values as UUIDs return rows.map((row) => row.room_id as UUID); } @@ -341,6 +365,9 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter { userA: UUID; userB: UUID; }): Promise { + if (!params.userA || !params.userB) { + throw new Error("userA and userB are required"); + } const sql = "INSERT INTO relationships (user_a, user_b, user_id) VALUES (?, ?, ?)"; this.db.prepare(sql).run(params.userA, params.userB, params.userA); diff --git a/src/lib/adapters/sqlite/sqliteTables.ts b/src/lib/adapters/sqlite/sqliteTables.ts index edafdbb..02f3874 100644 --- a/src/lib/adapters/sqlite/sqliteTables.ts +++ b/src/lib/adapters/sqlite/sqliteTables.ts @@ -34,6 +34,7 @@ CREATE TABLE IF NOT EXISTS "goals" ( "name" TEXT, "status" TEXT, "description" TEXT, + "room_id" TEXT, "objectives" TEXT DEFAULT '[]' NOT NULL ); @@ -61,15 +62,13 @@ CREATE TABLE IF NOT EXISTS "participants" ( -- Table: relationships CREATE TABLE IF NOT EXISTS "relationships" ( "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - "user_a" TEXT, - "user_b" TEXT, - "status" TEXT, + "user_a" TEXT NOT NULL, + "user_b" TEXT NOT NULL, + "status" "text", "id" TEXT PRIMARY KEY, - "room_id" TEXT, "user_id" TEXT NOT NULL, FOREIGN KEY ("user_a") REFERENCES "accounts"("id"), FOREIGN KEY ("user_b") REFERENCES "accounts"("id"), - FOREIGN KEY ("room_id") REFERENCES "rooms"("id") ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY ("user_id") REFERENCES "accounts"("id") ); diff --git a/src/lib/adapters/supabase.ts b/src/lib/adapters/supabase.ts index 879d606..ec91287 100644 --- a/src/lib/adapters/supabase.ts +++ b/src/lib/adapters/supabase.ts @@ -454,7 +454,6 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { user_a: params.userA, user_b: params.userB, user_id: params.userA, - room_id, status: "FRIENDS", }) .eq("user_a", params.userA) diff --git a/src/test/getOrCreateRelationship.ts b/src/test/getOrCreateRelationship.ts index 91e2a18..dbd0553 100644 --- a/src/test/getOrCreateRelationship.ts +++ b/src/test/getOrCreateRelationship.ts @@ -11,46 +11,58 @@ export async function getOrCreateRelationship({ userB: UUID; }): Promise { // Check if a relationship already exists between userA and userB - let relationship = await getRelationship({ runtime, userA, userB }); + try { + let relationship = await getRelationship({ runtime, userA, userB }); - if (!relationship) { - try { + console.log("relationship", relationship); + + if (!relationship) { + console.log("!relationship"); // Check if a room already exists for the participants const rooms = await runtime.databaseAdapter.getRoomsByParticipants([ userA, userB, ]); + console.log("rooms", rooms); + let roomId: UUID; if (!rooms || rooms.length === 0) { + console.log("!rooms || rooms.length === 0"); // If no room exists, create a new room for the relationship roomId = await runtime.databaseAdapter.createRoom("Direct Message"); + console.log("roomId", roomId); + // Add participants to the newly created room + console.log("adding parcitipants to room..."); await runtime.databaseAdapter.addParticipantToRoom(userA, roomId); await runtime.databaseAdapter.addParticipantToRoom(userB, roomId); + console.log("userA, userB", userA, userB); } else { // If a room already exists, use the existing room roomId = rooms[0]; } + console.log("createRelationship"); // Create the relationship await runtime.databaseAdapter.createRelationship({ userA, userB, }); + console.log("getRelationship"); // Fetch the newly created relationship relationship = await getRelationship({ runtime, userA, userB }); + console.log("relationship", relationship); if (!relationship) { throw new Error("Failed to fetch the created relationship"); } - } catch (error) { - throw new Error(`Error creating relationship: ${JSON.stringify(error)}`); } + return relationship; + } catch (error) { + throw new Error(`Error creating relationship: ${JSON.stringify(error)}`); } - - return relationship; } diff --git a/supabase/migrations/20240318103238_remote_schema.sql b/supabase/migrations/20240318103238_remote_schema.sql index 52bc1ce..40f604e 100644 --- a/supabase/migrations/20240318103238_remote_schema.sql +++ b/supabase/migrations/20240318103238_remote_schema.sql @@ -370,7 +370,6 @@ CREATE TABLE IF NOT EXISTS "public"."relationships" ( "user_b" "uuid", "status" "text", "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, - "room_id" "uuid", "user_id" "uuid" NOT NULL );