diff --git a/src/lib/__tests__/goals.test.ts b/src/lib/__tests__/goals.test.ts index 7b235ab..c6c1e78 100644 --- a/src/lib/__tests__/goals.test.ts +++ b/src/lib/__tests__/goals.test.ts @@ -1,52 +1,38 @@ -import { type User } from "../../test/types"; import { type UUID } from "crypto"; import dotenv from "dotenv"; import { createRuntime } from "../../test/createRuntime"; +import { type User } from "../../test/types"; +import { zeroUuid } from "../constants"; import { createGoal, getGoals, updateGoal } from "../goals"; import { BgentRuntime } from "../runtime"; import { GoalStatus, type Goal } from "../types"; -import { getRelationship } from "../relationships"; -import { zeroUuid } from "../constants"; dotenv.config({ path: ".dev.vars" }); describe("Goals", () => { let runtime: BgentRuntime; let user: User; - let room_id = beforeAll(async () => { + beforeAll(async () => { const result = await createRuntime({ env: process.env as Record, }); runtime = result.runtime; user = result.session.user; - const data = await getRelationship({ - runtime, - userA: user?.id as UUID, - userB: zeroUuid, - }); - - if (!data) { - throw new Error("Relationship not found"); - } - - room_id = data.room_id; - - await runtime.databaseAdapter.removeAllMemoriesByRoomId(room_id, "goals"); + await runtime.databaseAdapter.removeAllMemoriesByRoomId(zeroUuid, "goals"); }); beforeEach(async () => { - await runtime.databaseAdapter.removeAllMemoriesByRoomId(room_id, "goals"); + await runtime.databaseAdapter.removeAllMemoriesByRoomId(zeroUuid, "goals"); }); afterAll(async () => { - await runtime.databaseAdapter.removeAllMemoriesByRoomId(room_id, "goals"); + await runtime.databaseAdapter.removeAllMemoriesByRoomId(zeroUuid, "goals"); }); - // TODO: Write goal tests here test("createGoal - successfully creates a new goal", async () => { const newGoal: Goal = { name: "Test Create Goal", status: GoalStatus.IN_PROGRESS, - room_id, + room_id: zeroUuid, user_id: user?.id as UUID, objectives: [ { @@ -56,6 +42,8 @@ describe("Goals", () => { ], }; + console.log("newGoal", newGoal); + await createGoal({ runtime, goal: newGoal, @@ -64,9 +52,11 @@ describe("Goals", () => { // Verify the goal is created in the database const goals = await getGoals({ runtime, - room_id, + userId: user?.id as UUID, + room_id: zeroUuid, onlyInProgress: false, }); + const createdGoal = goals.find((goal: Goal) => goal.name === newGoal.name); expect(createdGoal).toBeDefined(); @@ -79,7 +69,7 @@ describe("Goals", () => { const newGoal: Goal = { name: "Test Create Goal", status: GoalStatus.IN_PROGRESS, - room_id, + room_id: zeroUuid, user_id: user?.id as UUID, objectives: [ { @@ -97,9 +87,10 @@ describe("Goals", () => { // retrieve the goal from the database let goals = await getGoals({ runtime, - room_id, + room_id: zeroUuid, onlyInProgress: false, }); + console.log("goals", goals); const existingGoal = goals.find( (goal: Goal) => goal.name === newGoal.name, ) as Goal; @@ -112,7 +103,7 @@ describe("Goals", () => { // Verify the goal's status is updated in the database goals = await getGoals({ runtime, - room_id, + room_id: zeroUuid, onlyInProgress: false, }); diff --git a/src/lib/__tests__/messages.test.ts b/src/lib/__tests__/messages.test.ts index 977e00b..566df7a 100644 --- a/src/lib/__tests__/messages.test.ts +++ b/src/lib/__tests__/messages.test.ts @@ -5,6 +5,8 @@ import { formatActors, formatMessages, getActorDetails } from "../messages"; import { type BgentRuntime } from "../runtime"; import { type Actor, type Content, type Memory } from "../types"; import { formatFacts } from "../evaluators/fact"; +import { createRelationship, getRelationship } from "../relationships"; +import { zeroUuid } from "../constants"; describe("Messages Library", () => { let runtime: BgentRuntime, user: User, actors: Actor[]; @@ -22,9 +24,29 @@ describe("Messages Library", () => { }); test("getActorDetails should return actors based on given room_id", async () => { + // create a room and add a user to it + const userA = user?.id as UUID; + const userB = zeroUuid; + + await createRelationship({ + runtime, + userA, + userB, + }); + + const relationship = await getRelationship({ + runtime, + userA, + userB, + }); + + if (!relationship?.room_id) { + throw new Error("Room not found"); + } + const result = await getActorDetails({ runtime, - room_id: "00000000-0000-0000-0000-000000000000", + room_id: relationship?.room_id as UUID, }); expect(result.length).toBeGreaterThan(0); result.forEach((actor: Actor) => { diff --git a/src/lib/__tests__/providers.test.ts b/src/lib/__tests__/providers.test.ts index 16fa312..487e16f 100644 --- a/src/lib/__tests__/providers.test.ts +++ b/src/lib/__tests__/providers.test.ts @@ -24,7 +24,7 @@ describe("TestProvider", () => { providers: [TestProvider], }); runtime = setup.runtime; - room_id = "some-room-id" as UUID; + room_id = zeroUuid; }); test("TestProvider should return 'Hello Test'", async () => { diff --git a/src/lib/__tests__/runtime.test.ts b/src/lib/__tests__/runtime.test.ts index e855fb8..86dd1bb 100644 --- a/src/lib/__tests__/runtime.test.ts +++ b/src/lib/__tests__/runtime.test.ts @@ -1,7 +1,7 @@ import dotenv from "dotenv"; import { createRuntime } from "../../test/createRuntime"; import { type UUID } from "crypto"; -import { getRelationship } from "../relationships"; +import { createRelationship, getRelationship } from "../relationships"; import { getCachedEmbedding, writeCachedEmbedding } from "../../test/cache"; import { BgentRuntime } from "../runtime"; import { type User } from "../../test/types"; @@ -13,7 +13,7 @@ dotenv.config({ path: ".dev.vars" }); describe("Agent Runtime", () => { let user: User; let runtime: BgentRuntime; - let room_id: UUID; + let room_id: UUID = zeroUuid; // Helper function to clear memories async function clearMemories() { @@ -31,17 +31,21 @@ describe("Agent Runtime", () => { ]; for (const { userId, content } of memories) { - const embedding = getCachedEmbedding(content.content); - const memory = await runtime.messageManager.addEmbeddingToMemory({ - user_id: userId, - content, - room_id, - embedding, - }); - if (!embedding) { - writeCachedEmbedding(content.content, memory.embedding as number[]); + try { + const embedding = getCachedEmbedding(content.content); + const memory = await runtime.messageManager.addEmbeddingToMemory({ + user_id: userId, + content, + room_id, + embedding, + }); + if (!embedding) { + writeCachedEmbedding(content.content, memory.embedding as number[]); + } + await runtime.messageManager.createMemory(memory); + } catch (error) { + console.error("Error creating memory", error); } - await runtime.messageManager.createMemory(memory); } } @@ -54,17 +58,28 @@ describe("Agent Runtime", () => { runtime = result.runtime; user = result.session.user; - const data = await getRelationship({ + let data = await getRelationship({ runtime, userA: user?.id as UUID, userB: zeroUuid, }); if (!data) { - throw new Error("Relationship not found"); + await createRelationship({ + runtime, + userA: user?.id as UUID, + userB: zeroUuid, + }); + data = await getRelationship({ + runtime, + userA: user?.id as UUID, + userB: zeroUuid, + }); } - room_id = data?.room_id; + console.log("data", data); + + room_id = data?.room_id as UUID; await clearMemories(); // Clear memories before each test }); @@ -84,7 +99,13 @@ describe("Agent Runtime", () => { }); test("Memory lifecycle: create, retrieve, and destroy", async () => { - await createMemories(); // Create new memories + try { + await createMemories(); // Create new memories + } catch (error) { + console.error("Error creating memories", error); + } + + console.log("room_id", room_id); const message: Message = { userId: user.id as UUID, diff --git a/src/lib/adapters/sqlite.ts b/src/lib/adapters/sqlite.ts index faecdde..c8dc009 100644 --- a/src/lib/adapters/sqlite.ts +++ b/src/lib/adapters/sqlite.ts @@ -59,8 +59,8 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter { }): Promise { let sql = ` SELECT * - FROM ${params.tableName} - WHERE room_id = ? AND vss_search(embedding, ?) + FROM memories + WHERE type = ${params.tableName} AND room_id = ? AND vss_search(embedding, ?) ORDER BY vss_search(embedding, ?) DESC LIMIT ? `; @@ -88,14 +88,16 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter { }): Promise<[]> { const sql = ` SELECT * - FROM ${opts.query_table_name} - WHERE vss_search(${opts.query_field_name}, ?) + FROM memories + WHERE type = ? + AND vss_search(${opts.query_field_name}, ?) ORDER BY vss_search(${opts.query_field_name}, ?) DESC LIMIT ? `; return this.db .prepare(sql) .all( + JSON.stringify(opts.query_table_name), JSON.stringify(opts.query_input), JSON.stringify(opts.query_input), opts.query_match_count, @@ -134,19 +136,26 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter { unique?: boolean; tableName: string; }): Promise { - let sql = `SELECT * FROM ${params.tableName} WHERE room_id = ?`; - const queryParams = [JSON.stringify(params.room_id)]; + 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}`; if (params.unique) { sql += " AND unique = 1"; } if (params.count) { - sql += " LIMIT ?"; - queryParams.push(params.count.toString()); + sql += ` LIMIT ${params.count}`; } - return this.db.prepare(sql).all(...queryParams) as Memory[]; + console.log("sql"); + console.log(sql); + + return this.db.prepare(sql).all() as Memory[]; } async searchMemoriesByEmbedding( @@ -161,8 +170,8 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter { ): Promise { let sql = ` SELECT * - FROM ${params.tableName} - WHERE vss_search(embedding, ?) + FROM memories + WHERE type = ${params.tableName} AND vss_search(embedding, ?) ORDER BY vss_search(embedding, ?) DESC `; const queryParams = [JSON.stringify(embedding), JSON.stringify(embedding)]; @@ -189,7 +198,7 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter { tableName: string, unique = false, ): Promise { - const sql = `INSERT INTO memories (id, type, created_at, content, embedding, user_id, room_id, unique) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`; + const sql = `INSERT INTO memories (id, type, created_at, content, embedding, user_id, room_id, \`unique\`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`; this.db .prepare(sql) .run( @@ -213,7 +222,7 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter { room_id: UUID, tableName: string, ): Promise { - const sql = `DELETE FROM memories WHERE tableName = ? AND room_id = ?`; + const sql = `DELETE FROM memories WHERE type = ? AND room_id = ?`; this.db.prepare(sql).run(tableName, JSON.stringify(room_id)); } @@ -226,7 +235,7 @@ export class SqliteDatabaseAdapter extends DatabaseAdapter { throw new Error("tableName is required"); } - let sql = `SELECT COUNT(*) as count FROM memories WHERE tableName = ? AND room_id = ?`; + let sql = `SELECT COUNT(*) as count FROM memories WHERE type = ? AND room_id = ?`; const queryParams = [tableName, JSON.stringify(room_id)] as string[]; if (unique) { diff --git a/src/lib/adapters/supabase.ts b/src/lib/adapters/supabase.ts index 2780c74..0a9dbc0 100644 --- a/src/lib/adapters/supabase.ts +++ b/src/lib/adapters/supabase.ts @@ -42,7 +42,11 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { const response = await this.supabase .from("rooms") .select( - "participants:participants!inner(*), participants!inner(user_id:accounts(*))", + ` + participants:participants!inner( + user_id:accounts(id, name, details) + ) + `, ) .eq("id", params.room_id); @@ -55,11 +59,14 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { return data .map((room) => - room.participants.map((participant) => ({ - name: participant.user_id.name, - details: participant.user_id.details, - id: participant.user_id.id, - })), + room.participants.map((participant) => { + const user = participant.user_id[0]; // Assuming user_id is an array with a single object + return { + name: user?.name, + details: user?.details, + id: user?.id, + }; + }), ) .flat(); } @@ -209,7 +216,9 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { throw new Error(JSON.stringify(result.error)); } } else { - const result = await this.supabase.from(tableName).insert(memory); + const result = await this.supabase + .from("memories") + .insert({ ...memory, type: tableName }); const { error } = result; if (error) { throw new Error(JSON.stringify(error)); @@ -217,9 +226,9 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { } } - async removeMemory(memoryId: UUID, tableName: string): Promise { + async removeMemory(memoryId: UUID): Promise { const result = await this.supabase - .from(tableName) + .from("memories") .delete() .eq("id", memoryId); const { error } = result; @@ -276,6 +285,7 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { only_in_progress: params.onlyInProgress, row_count: params.count, }; + console.log("opts", opts) const { data: goals, error } = await this.supabase.rpc("get_goals", opts); if (error) { @@ -297,10 +307,30 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { userA: UUID; userB: UUID; }): Promise { + const { data, error: roomsError } = (await this.supabase + .from("rooms") + .insert({ name: "test relationship" }) + .single()) as { data: { id: UUID } | null; error: Error | null }; + if (roomsError) { + throw new Error(roomsError.message); + } + const room_id = data?.id; + const { error: participantsError } = await this.supabase + .from("participants") + .insert([ + { user_id: params.userA, room_id }, + { user_id: params.userB, room_id }, + ]); + if (participantsError) { + throw new Error(participantsError.message); + } + // then create a relationship between the two users with the room_id as the relationship's room_id + const { error } = await this.supabase.from("relationships").upsert({ user_a: params.userA, user_b: params.userB, user_id: params.userA, + room_id, }); if (error) { diff --git a/src/lib/providers/__tests__/time.test.ts b/src/lib/providers/__tests__/time.test.ts index 88fecdb..4a49ff8 100644 --- a/src/lib/providers/__tests__/time.test.ts +++ b/src/lib/providers/__tests__/time.test.ts @@ -5,6 +5,7 @@ import { composeContext } from "../../context"; import { BgentRuntime } from "../../runtime"; import { type Message, type State } from "../../types"; import timeProvider from "../time"; +import { zeroUuid } from "../../constants"; dotenv.config({ path: ".dev.vars" }); @@ -20,7 +21,7 @@ describe("Time Provider", () => { }); runtime = setup.runtime; user = { id: setup.session.user?.id as UUID }; - room_id = "some-room-id" as UUID; // Assume room_id is fetched or set up in your environment + room_id = zeroUuid; }); test("Time provider should return the current time in the correct format", async () => { diff --git a/src/lib/runtime.ts b/src/lib/runtime.ts index 10b588e..059b9d9 100644 --- a/src/lib/runtime.ts +++ b/src/lib/runtime.ts @@ -449,6 +449,8 @@ export class BgentRuntime { async composeState(message: Message) { const { userId, room_id } = message; + console.log("message", message); + const recentMessageCount = this.getRecentMessageCount(); const recentFactsCount = Math.ceil(this.getRecentMessageCount() / 2); const relevantFactsCount = Math.ceil(this.getRecentMessageCount() / 2); diff --git a/src/test/createRuntime.ts b/src/test/createRuntime.ts index e33aa80..5f0f2d1 100644 --- a/src/test/createRuntime.ts +++ b/src/test/createRuntime.ts @@ -32,7 +32,25 @@ export async function createRuntime({ let session: Session; switch (env?.TEST_DATABASE_CLIENT as string) { + case "sqlite": + { + // SQLite adapter + adapter = new SqliteDatabaseAdapter(new Database(":memory:")); + + // Create a test user and session + user = { + id: "test-user-id" as UUID, + email: "test@example.com", + } as User; + session = { + access_token: "test-access-token", + refresh_token: "test-refresh-token", + user: user, + } as Session; + } + break; case "supabase": + default: { const supabase = createClient( env?.SUPABASE_URL ?? SUPABASE_URL, @@ -73,25 +91,7 @@ export async function createRuntime({ ); } break; - - default: - { - // SQLite adapter - adapter = new SqliteDatabaseAdapter(new Database(":memory:")); - - // Create a test user and session - user = { - id: "test-user-id" as UUID, - email: "test@example.com", - } as User; - session = { - access_token: "test-access-token", - refresh_token: "test-refresh-token", - user: user, - } as Session; - } - break; - } + } const runtime = new BgentRuntime({ debugMode: false, diff --git a/supabase/migrations/20240318103238_remote_schema.sql b/supabase/migrations/20240318103238_remote_schema.sql index 7878e19..24b471b 100644 --- a/supabase/migrations/20240318103238_remote_schema.sql +++ b/supabase/migrations/20240318103238_remote_schema.sql @@ -33,6 +33,17 @@ CREATE TABLE IF NOT EXISTS "public"."secrets" ( ALTER TABLE "public"."secrets" OWNER TO "postgres"; +CREATE TABLE "public"."user_data" ( + owner_id INT, + target_id INT, + data JSONB, + PRIMARY KEY (owner_id, target_id), + FOREIGN KEY (owner_id) REFERENCES accounts(id), + FOREIGN KEY (target_id) REFERENCES accounts(id) +); + +ALTER TABLE "public"."user_data" OWNER TO "postgres"; + CREATE OR REPLACE FUNCTION "public"."after_account_created"() RETURNS "trigger" LANGUAGE "plpgsql" SECURITY DEFINER SET "search_path" TO 'extensions', 'public', 'pg_temp' @@ -61,9 +72,10 @@ $$; ALTER FUNCTION "public"."after_account_created"() OWNER TO "postgres"; -CREATE OR REPLACE FUNCTION "public"."check_similarity_and_insert"("query_table_name" "text", "query_user_id" "uuid", "query_content" "jsonb", "query_room_id" "uuid", "query_embedding" "extensions"."vector", "similarity_threshold" double precision) RETURNS "void" - LANGUAGE "plpgsql" - AS $$ +CREATE OR REPLACE FUNCTION "public"."check_similarity_and_insert"("query_table_name" "text", "query_user_id" "uuid", "query_content" "jsonb", "query_room_id" "uuid", "query_embedding" "extensions"."vector", "similarity_threshold" double precision) +RETURNS "void" +LANGUAGE "plpgsql" +AS $$ DECLARE similar_found BOOLEAN := FALSE; select_query TEXT; @@ -73,20 +85,21 @@ BEGIN IF query_embedding IS NOT NULL THEN -- Build a dynamic query to check for existing similar embeddings using cosine distance select_query := format( - 'SELECT EXISTS (' || - 'SELECT 1 ' || - 'FROM %I ' || - 'WHERE user_id = %L ' || - 'AND room_id = %L ' || -- Assuming this is correct - 'AND embedding <=> %L < %L ' || - 'LIMIT 1' || - ')', - query_table_name, - query_user_id, - query_room_id, -- First usage - query_embedding, - similarity_threshold - ); + 'SELECT EXISTS (' || + 'SELECT 1 ' || + 'FROM memories ' || + 'WHERE user_id = %L ' || + 'AND room_id = %L ' || + 'AND type = %L ' || -- Filter by the 'type' field using query_table_name + 'AND embedding <=> %L < %L ' || + 'LIMIT 1' || + ')', + query_user_id, + query_room_id, + query_table_name, -- Use query_table_name to filter by 'type' + query_embedding, + similarity_threshold + ); -- Execute the query to check for similarity EXECUTE select_query INTO similar_found; @@ -94,12 +107,12 @@ BEGIN -- Prepare the insert query with 'unique' field set based on the presence of similar records or NULL query_embedding insert_query := format( - 'INSERT INTO %I (user_id, content, room_id, embedding, "unique") ' || - 'VALUES (%L, %L, %L, %L, %L)', - query_table_name, + 'INSERT INTO memories (user_id, content, room_id, type, embedding, "unique") ' || -- Insert into the 'memories' table + 'VALUES (%L, %L, %L, %L, %L, %L)', query_user_id, query_content, query_room_id, + query_table_name, -- Use query_table_name as the 'type' value query_embedding, NOT similar_found OR query_embedding IS NULL -- Set 'unique' to true if no similar record is found or query_embedding is NULL ); @@ -111,7 +124,7 @@ $$; ALTER FUNCTION "public"."check_similarity_and_insert"("query_table_name" "text", "query_user_id" "uuid", "query_content" "jsonb", "query_room_id" "uuid", "query_embedding" "extensions"."vector", "similarity_threshold" double precision) OWNER TO "postgres"; -CREATE OR REPLACE FUNCTION "public"."count_memories"("query_type" "text", "query_room_id" "uuid", "query_unique" boolean DEFAULT false) RETURNS bigint +CREATE OR REPLACE FUNCTION "public"."count_memories"("query_table_name" "text", "query_room_id" "uuid", "query_unique" boolean DEFAULT false) RETURNS bigint LANGUAGE "plpgsql" AS $$ DECLARE @@ -119,7 +132,7 @@ DECLARE total BIGINT; BEGIN -- Initialize the base query - query := format('SELECT COUNT(*) FROM memories WHERE type = %L', query_type); + query := format('SELECT COUNT(*) FROM memories WHERE type = %L', query_table_name); -- Add condition for room_id if not null, ensuring proper spacing IF query_room_id IS NOT NULL THEN @@ -221,15 +234,13 @@ $$; ALTER FUNCTION "public"."fn_notify_agents"() OWNER TO "postgres"; -CREATE OR REPLACE FUNCTION "public"."get_embedding_list"("query_table_name" "text", "query_threshold" integer, "query_input" "text", "query_field_name" "text", "query_field_sub_name" "text", "query_match_count" integer) RETURNS TABLE("embedding" "extensions"."vector", "levenshtein_score" integer) - LANGUAGE "plpgsql" - AS $_$DECLARE +CREATE OR REPLACE FUNCTION "public"."get_embedding_list"("query_table_name" "text", "query_threshold" integer, "query_input" "text", "query_field_name" "text", "query_field_sub_name" "text", "query_match_count" integer) +RETURNS TABLE("embedding" "extensions"."vector", "levenshtein_score" integer) +LANGUAGE "plpgsql" +AS $$ +DECLARE QUERY TEXT; BEGIN - IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = query_table_name) THEN - RAISE EXCEPTION 'Table % does not exist', query_table_name; - END IF; - -- Check the length of query_input IF LENGTH(query_input) > 255 THEN -- For inputs longer than 255 characters, use exact match only @@ -237,34 +248,36 @@ BEGIN SELECT embedding FROM - %I + memories WHERE - (content->>''%s'')::TEXT = $1 + type = $1 AND + (content->>''%s'')::TEXT = $2 LIMIT - $2 - ', query_table_name, query_field_name); + $3 + ', query_field_name); -- Execute the query with adjusted parameters for exact match - RETURN QUERY EXECUTE QUERY USING query_input, query_match_count; + RETURN QUERY EXECUTE QUERY USING query_table_name, query_input, query_match_count; ELSE -- For inputs of 255 characters or less, use Levenshtein distance QUERY := format(' SELECT embedding, - levenshtein($1, (content->>''%s'')::TEXT) AS levenshtein_score + levenshtein($2, (content->>''%s'')::TEXT) AS levenshtein_score FROM - %I + memories WHERE - levenshtein($1, (content->>''%s'')::TEXT) <= $2 + type = $1 AND + levenshtein($2, (content->>''%s'')::TEXT) <= $3 ORDER BY levenshtein_score LIMIT - $3 - ', query_field_name, query_table_name, query_field_name); + $4 + ', query_field_name, query_field_name); -- Execute the query with original parameters for Levenshtein distance - RETURN QUERY EXECUTE QUERY USING query_input, query_threshold, query_match_count; + RETURN QUERY EXECUTE QUERY USING query_table_name, query_input, query_threshold, query_match_count; END IF; END; -$_$; +$$; ALTER FUNCTION "public"."get_embedding_list"("query_table_name" "text", "query_threshold" integer, "query_input" "text", "query_field_name" "text", "query_field_sub_name" "text", "query_match_count" integer) OWNER TO "postgres"; @@ -276,6 +289,7 @@ CREATE TABLE IF NOT EXISTS "public"."goals" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "created_at" timestamp with time zone DEFAULT "now"() NOT NULL, "user_id" "uuid", + "room_id": "uuid", "status" "text", "objectives" "jsonb"[] DEFAULT '{}'::"jsonb"[] NOT NULL ); @@ -298,9 +312,10 @@ $$; ALTER FUNCTION "public"."get_goals"("query_room_id" "uuid", "query_user_id" "uuid", "only_in_progress" boolean, "row_count" integer) OWNER TO "postgres"; -CREATE OR REPLACE FUNCTION "public"."get_memories"("query_type" "text", "query_room_id" "uuid", "query_count" integer, "query_unique" boolean DEFAULT false) RETURNS TABLE("id" "uuid", "user_id" "uuid", "content" "jsonb", "created_at" timestamp with time zone, "room_id" "uuid", "embedding" "extensions"."vector") - LANGUAGE "plpgsql" - AS $_$ +CREATE OR REPLACE FUNCTION "public"."get_memories"("query_table_name" "text", "query_room_id" "uuid", "query_count" integer, "query_unique" boolean DEFAULT false) +RETURNS TABLE("id" "uuid", "user_id" "uuid", "content" "jsonb", "created_at" timestamp with time zone, "room_id" "uuid", "embedding" "extensions"."vector") +LANGUAGE "plpgsql" +AS $_$ DECLARE query TEXT; BEGIN @@ -316,12 +331,13 @@ BEGIN WHERE TRUE AND type = %L %s -- Additional condition for 'unique' column based on query_unique + %s -- Additional condition for room_id based on query_room_id ORDER BY created_at DESC LIMIT %L $fmt$, - query_type, + query_table_name, + CASE WHEN query_unique THEN ' AND "unique" IS TRUE' ELSE '' END, CASE WHEN query_room_id IS NOT NULL THEN format(' AND room_id = %L', query_room_id) ELSE '' END, - CASE WHEN query_unique THEN ' AND "unique" = TRUE' ELSE '' END, -- Enclose 'unique' in double quotes query_count ); @@ -329,7 +345,6 @@ BEGIN END; $_$; - ALTER FUNCTION "public"."get_memories"("query_table_name" "text", "query_room_id" "uuid", "query_count" integer, "query_unique" boolean) OWNER TO "postgres"; CREATE OR REPLACE FUNCTION "public"."get_message_count"("p_user_id" "uuid") RETURNS TABLE("room_id" "uuid", "unread_messages_count" integer) @@ -338,7 +353,7 @@ CREATE OR REPLACE FUNCTION "public"."get_message_count"("p_user_id" "uuid") RETU RETURN QUERY SELECT p.room_id, COALESCE(COUNT(m.id)::integer, 0) AS unread_messages_count FROM participants p - LEFT JOIN messages m ON p.room_id = m.room_id + LEFT JOIN memories m ON p.room_id = m.room_id AND m.type = "messages" WHERE p.user_id = p_user_id GROUP BY p.room_id; END; @@ -372,22 +387,23 @@ $$; ALTER FUNCTION "public"."get_relationship"("usera" "uuid", "userb" "uuid") OWNER TO "postgres"; -CREATE OR REPLACE FUNCTION "public"."remove_memories"("query_type" "text", "query_room_id" "uuid") RETURNS "void" +CREATE OR REPLACE FUNCTION "public"."remove_memories"("query_table_name" "text", "query_room_id" "uuid") RETURNS "void" LANGUAGE "plpgsql" AS $_$DECLARE dynamic_query TEXT; BEGIN dynamic_query := format('DELETE FROM memories WHERE room_id = $1 AND type = $2'); - EXECUTE dynamic_query USING query_room_id, query_type; + EXECUTE dynamic_query USING query_room_id, query_table_name; END; $_$; ALTER FUNCTION "public"."remove_memories"("query_table_name" "text", "query_room_id" "uuid") OWNER TO "postgres"; -CREATE OR REPLACE FUNCTION "public"."search_memories"("query_type" "text", "query_room_id" "uuid", "query_embedding" "extensions"."vector", "query_match_threshold" double precision, "query_match_count" integer, "query_unique" boolean) RETURNS TABLE("id" "uuid", "user_id" "uuid", "content" "jsonb", "created_at" timestamp with time zone, "similarity" double precision, "room_id" "uuid", "embedding" "extensions"."vector") - LANGUAGE "plpgsql" - AS $_$ +CREATE OR REPLACE FUNCTION "public"."search_memories"("query_table_name" "text", "query_room_id" "uuid", "query_embedding" "extensions"."vector", "query_match_threshold" double precision, "query_match_count" integer, "query_unique" boolean) +RETURNS TABLE("id" "uuid", "user_id" "uuid", "content" "jsonb", "created_at" timestamp with time zone, "similarity" double precision, "room_id" "uuid", "embedding" "extensions"."vector") +LANGUAGE "plpgsql" +AS $$ DECLARE query TEXT; BEGIN @@ -404,21 +420,23 @@ BEGIN WHERE (1 - (embedding <=> %L) > %L) AND type = %L %s -- Additional condition for 'unique' column + %s -- Additional condition for 'room_id' ORDER BY similarity DESC LIMIT %L $fmt$, query_embedding, query_embedding, query_match_threshold, - query_type, + query_table_name, + CASE WHEN query_unique THEN ' AND "unique" IS TRUE' ELSE '' END, CASE WHEN query_room_id IS NOT NULL THEN format(' AND room_id = %L', query_room_id) ELSE '' END, - CASE WHEN query_unique THEN ' AND "unique"' ELSE '' END, -- Use "unique" instead of unique = TRUE query_match_count ); RETURN QUERY EXECUTE query; END; -$_$; +$$; + ALTER FUNCTION "public"."search_memories"("query_table_name" "text", "query_room_id" "uuid", "query_embedding" "extensions"."vector", "query_match_threshold" double precision, "query_match_count" integer, "query_unique" boolean) OWNER TO "postgres"; @@ -595,106 +613,118 @@ ALTER TABLE "public"."rooms" ENABLE ROW LEVEL SECURITY; CREATE POLICY "select_own_account" ON "public"."accounts" FOR SELECT USING (("auth"."uid"() = "id")); GRANT USAGE ON SCHEMA "public" TO "postgres"; -GRANT USAGE ON SCHEMA "public" TO "anon"; GRANT USAGE ON SCHEMA "public" TO "authenticated"; GRANT USAGE ON SCHEMA "public" TO "service_role"; +GRANT USAGE ON SCHEMA "public" TO "supabase_admin"; +GRANT USAGE ON SCHEMA "public" TO "supabase_auth_admin"; -GRANT ALL ON FUNCTION "public"."after_account_created"() TO "anon"; GRANT ALL ON FUNCTION "public"."after_account_created"() TO "authenticated"; GRANT ALL ON FUNCTION "public"."after_account_created"() TO "service_role"; +GRANT ALL ON FUNCTION "public"."after_account_created"() TO "supabase_admin"; +GRANT ALL ON FUNCTION "public"."after_account_created"() TO "supabase_auth_admin"; -GRANT ALL ON FUNCTION "public"."count_memories"("query_table_name" "text", "query_room_id" "uuid", "query_unique" boolean) TO "anon"; GRANT ALL ON FUNCTION "public"."count_memories"("query_table_name" "text", "query_room_id" "uuid", "query_unique" boolean) TO "authenticated"; GRANT ALL ON FUNCTION "public"."count_memories"("query_table_name" "text", "query_room_id" "uuid", "query_unique" boolean) TO "service_role"; +GRANT ALL ON FUNCTION "public"."count_memories"("query_table_name" "text", "query_room_id" "uuid", "query_unique" boolean) TO "supabase_admin"; +GRANT ALL ON FUNCTION "public"."count_memories"("query_table_name" "text", "query_room_id" "uuid", "query_unique" boolean) TO "supabase_auth_admin"; -GRANT ALL ON FUNCTION "public"."create_friendship_with_host_agent"() TO "anon"; GRANT ALL ON FUNCTION "public"."create_friendship_with_host_agent"() TO "authenticated"; GRANT ALL ON FUNCTION "public"."create_friendship_with_host_agent"() TO "service_role"; +GRANT ALL ON FUNCTION "public"."create_friendship_with_host_agent"() TO "supabase_admin"; +GRANT ALL ON FUNCTION "public"."create_friendship_with_host_agent"() TO "supabase_auth_admin"; -GRANT ALL ON FUNCTION "public"."fn_notify_agents"() TO "anon"; GRANT ALL ON FUNCTION "public"."fn_notify_agents"() TO "authenticated"; GRANT ALL ON FUNCTION "public"."fn_notify_agents"() TO "service_role"; +GRANT ALL ON FUNCTION "public"."fn_notify_agents"() TO "supabase_admin"; +GRANT ALL ON FUNCTION "public"."fn_notify_agents"() TO "supabase_auth_admin"; -GRANT ALL ON FUNCTION "public"."get_embedding_list"("query_table_name" "text", "query_threshold" integer, "query_input" "text", "query_field_name" "text", "query_field_sub_name" "text", "query_match_count" integer) TO "anon"; GRANT ALL ON FUNCTION "public"."get_embedding_list"("query_table_name" "text", "query_threshold" integer, "query_input" "text", "query_field_name" "text", "query_field_sub_name" "text", "query_match_count" integer) TO "authenticated"; GRANT ALL ON FUNCTION "public"."get_embedding_list"("query_table_name" "text", "query_threshold" integer, "query_input" "text", "query_field_name" "text", "query_field_sub_name" "text", "query_match_count" integer) TO "service_role"; +GRANT ALL ON FUNCTION "public"."get_embedding_list"("query_table_name" "text", "query_threshold" integer, "query_input" "text", "query_field_name" "text", "query_field_sub_name" "text", "query_match_count" integer) TO "supabase_admin"; +GRANT ALL ON FUNCTION "public"."get_embedding_list"("query_table_name" "text", "query_threshold" integer, "query_input" "text", "query_field_name" "text", "query_field_sub_name" "text", "query_match_count" integer) TO "supabase_auth_admin"; -GRANT ALL ON TABLE "public"."goals" TO "anon"; GRANT ALL ON TABLE "public"."goals" TO "authenticated"; GRANT ALL ON TABLE "public"."goals" TO "service_role"; GRANT ALL ON TABLE "public"."goals" TO "supabase_admin"; GRANT ALL ON TABLE "public"."goals" TO "supabase_auth_admin"; -GRANT ALL ON FUNCTION "public"."get_goals"("query_room_id" "uuid", "query_user_id" "uuid", "only_in_progress" boolean, "row_count" integer) TO "anon"; GRANT ALL ON FUNCTION "public"."get_goals"("query_room_id" "uuid", "query_user_id" "uuid", "only_in_progress" boolean, "row_count" integer) TO "authenticated"; GRANT ALL ON FUNCTION "public"."get_goals"("query_room_id" "uuid", "query_user_id" "uuid", "only_in_progress" boolean, "row_count" integer) TO "service_role"; +GRANT ALL ON FUNCTION "public"."get_goals"("query_room_id" "uuid", "query_user_id" "uuid", "only_in_progress" boolean, "row_count" integer) TO "supabase_admin"; +GRANT ALL ON FUNCTION "public"."get_goals"("query_room_id" "uuid", "query_user_id" "uuid", "only_in_progress" boolean, "row_count" integer) TO "supabase_auth_admin"; -GRANT ALL ON FUNCTION "public"."get_memories"("query_table_name" "text", "query_room_id" "uuid", "query_count" integer, "query_unique" boolean) TO "anon"; GRANT ALL ON FUNCTION "public"."get_memories"("query_table_name" "text", "query_room_id" "uuid", "query_count" integer, "query_unique" boolean) TO "authenticated"; GRANT ALL ON FUNCTION "public"."get_memories"("query_table_name" "text", "query_room_id" "uuid", "query_count" integer, "query_unique" boolean) TO "service_role"; +GRANT ALL ON FUNCTION "public"."get_memories"("query_table_name" "text", "query_room_id" "uuid", "query_count" integer, "query_unique" boolean) TO "supabase_admin"; +GRANT ALL ON FUNCTION "public"."get_memories"("query_table_name" "text", "query_room_id" "uuid", "query_count" integer, "query_unique" boolean) TO "supabase_auth_admin"; -GRANT ALL ON FUNCTION "public"."get_message_count"("p_user_id" "uuid") TO "anon"; GRANT ALL ON FUNCTION "public"."get_message_count"("p_user_id" "uuid") TO "authenticated"; GRANT ALL ON FUNCTION "public"."get_message_count"("p_user_id" "uuid") TO "service_role"; +GRANT ALL ON FUNCTION "public"."get_message_count"("p_user_id" "uuid") TO "supabase_admin"; +GRANT ALL ON FUNCTION "public"."get_message_count"("p_user_id" "uuid") TO "supabase_auth_admin"; -GRANT ALL ON TABLE "public"."relationships" TO "anon"; GRANT ALL ON TABLE "public"."relationships" TO "authenticated"; GRANT ALL ON TABLE "public"."relationships" TO "service_role"; GRANT ALL ON TABLE "public"."relationships" TO "supabase_admin"; GRANT ALL ON TABLE "public"."relationships" TO "supabase_auth_admin"; -GRANT ALL ON FUNCTION "public"."get_relationship"("usera" "uuid", "userb" "uuid") TO "anon"; GRANT ALL ON FUNCTION "public"."get_relationship"("usera" "uuid", "userb" "uuid") TO "authenticated"; GRANT ALL ON FUNCTION "public"."get_relationship"("usera" "uuid", "userb" "uuid") TO "service_role"; +GRANT ALL ON FUNCTION "public"."get_relationship"("usera" "uuid", "userb" "uuid") TO "supabase_admin"; +GRANT ALL ON FUNCTION "public"."get_relationship"("usera" "uuid", "userb" "uuid") TO "supabase_auth_admin"; -GRANT ALL ON FUNCTION "public"."remove_memories"("query_table_name" "text", "query_room_id" "uuid") TO "anon"; GRANT ALL ON FUNCTION "public"."remove_memories"("query_table_name" "text", "query_room_id" "uuid") TO "authenticated"; GRANT ALL ON FUNCTION "public"."remove_memories"("query_table_name" "text", "query_room_id" "uuid") TO "service_role"; +GRANT ALL ON FUNCTION "public"."remove_memories"("query_table_name" "text", "query_room_id" "uuid") TO "supabase_admin"; +GRANT ALL ON FUNCTION "public"."remove_memories"("query_table_name" "text", "query_room_id" "uuid") TO "supabase_auth_admin"; -GRANT ALL ON TABLE "public"."accounts" TO "anon"; GRANT ALL ON TABLE "public"."accounts" TO "authenticated"; GRANT ALL ON TABLE "public"."accounts" TO "service_role"; GRANT SELECT,INSERT ON TABLE "public"."accounts" TO "authenticator"; GRANT ALL ON TABLE "public"."accounts" TO "supabase_admin"; GRANT ALL ON TABLE "public"."accounts" TO "supabase_auth_admin"; -GRANT ALL ON TABLE "public"."logs" TO "anon"; GRANT ALL ON TABLE "public"."logs" TO "authenticated"; GRANT ALL ON TABLE "public"."logs" TO "service_role"; GRANT ALL ON TABLE "public"."logs" TO "supabase_admin"; GRANT ALL ON TABLE "public"."logs" TO "supabase_auth_admin"; -GRANT ALL ON TABLE "public"."memories" TO "anon"; GRANT ALL ON TABLE "public"."memories" TO "authenticated"; GRANT ALL ON TABLE "public"."memories" TO "service_role"; GRANT ALL ON TABLE "public"."memories" TO "supabase_admin"; GRANT ALL ON TABLE "public"."memories" TO "supabase_auth_admin"; -GRANT ALL ON TABLE "public"."participants" TO "anon"; GRANT ALL ON TABLE "public"."participants" TO "authenticated"; GRANT ALL ON TABLE "public"."participants" TO "service_role"; GRANT ALL ON TABLE "public"."participants" TO "supabase_admin"; GRANT ALL ON TABLE "public"."participants" TO "supabase_auth_admin"; -GRANT ALL ON TABLE "public"."rooms" TO "anon"; GRANT ALL ON TABLE "public"."rooms" TO "authenticated"; GRANT ALL ON TABLE "public"."rooms" TO "service_role"; GRANT ALL ON TABLE "public"."rooms" TO "supabase_admin"; GRANT ALL ON TABLE "public"."rooms" TO "supabase_auth_admin"; +GRANT ALL ON TABLE "public"."secrets" TO "authenticated"; +GRANT ALL ON TABLE "public"."secrets" TO "service_role"; +GRANT ALL ON TABLE "public"."secrets" TO "supabase_admin"; +GRANT ALL ON TABLE "public"."secrets" TO "supabase_auth_admin"; + ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "postgres"; -ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "anon"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "authenticated"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "service_role"; +ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "supabase_admin"; +ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "supabase_auth_admin"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "postgres"; -ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "anon"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "authenticated"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "service_role"; +ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "supabase_admin"; +ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "supabase_auth_admin"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "postgres"; -ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "anon"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "authenticated"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "service_role"; +ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "supabase_admin"; +ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "supabase_auth_admin"; RESET ALL; \ No newline at end of file