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/README.md b/README.md
index e846d15..6ee4a8a 100644
--- a/README.md
+++ b/README.md
@@ -45,7 +45,11 @@ npx bgent
 Currently bgent is dependent on Supabase for local development. You can install it with the following command:
 
 ```bash
-npm install bgent @supabase/supabase-js
+npm install bgent
+
+# Select your database adapter
+npm install sqlite-vss better-sqlite3 # for sqlite (simple, for local development)
+npm install @supabase/supabase-js # for supabase (more complicated but can be deployed at scale)
 ```
 
 ### Set up environment variables
@@ -60,6 +64,23 @@ SUPABASE_SERVICE_API_KEY="your-supabase-service-api-key"
 OPENAI_API_KEY="your-openai-api-key"
 ```
 
+### SQLite Local Setup (Easiest)
+
+You can use SQLite for local development. This is the easiest way to get started with bgent.
+
+```typescript
+import { BgentRuntime, SqliteDatabaseAdapter } from "bgent";
+import { Database } from "sqlite3";
+const sqliteDatabaseAdapter = new SqliteDatabaseAdapter(new Database(":memory:"));
+
+const runtime = new BgentRuntime({
+  serverUrl: "https://api.openai.com/v1",
+  token: process.env.OPENAI_API_KEY, // Can be an API key or JWT token for your AI services
+  databaseAdapter: sqliteDatabaseAdapter,
+  // ... other options
+});
+```
+
 ### Supabase Local Setup
 
 First, you will need to install the Supabase CLI. You can install it using the instructions [here](https://supabase.com/docs/guides/cli/getting-started).
@@ -115,17 +136,20 @@ npm run shell # start the shell in another terminal to talk to the default agent
 ## Usage
 
 ```typescript
-import { BgentRuntime, SupabaseDatabaseAdapter } from "bgent";
+import { BgentRuntime, SupabaseDatabaseAdapter, SqliteDatabaseAdapter } from "bgent";
+
+const sqliteDatabaseAdapter = new SqliteDatabaseAdapter(new Database(":memory:"));
 
-const databaseAdapter = new SupabaseDatabaseAdapter(
-  process.env.SUPABASE_URL,
-  process.env.SUPABASE_SERVICE_API_KEY)
-  ;
+// You can also use Supabase like this
+// const supabaseDatabaseAdapter = new SupabaseDatabaseAdapter(
+//   process.env.SUPABASE_URL,
+//   process.env.SUPABASE_SERVICE_API_KEY)
+//   ;
 
 const runtime = new BgentRuntime({
   serverUrl: "https://api.openai.com/v1",
   token: process.env.OPENAI_API_KEY, // Can be an API key or JWT token for your AI services
-  databaseAdapter,
+  databaseAdapter: sqliteDatabaseAdapter,
   actions: [
     /* your custom actions */
   ],
@@ -184,13 +208,11 @@ const runtime = new BgentRuntime({
 
 The BgentRuntime instance has a `handleMessage` method that can be used to handle user input. The method returns a promise that resolves to the agent's response.
 
-You will need to make sure that the userIds and room_id already exist in the database. You can use the Supabase client to create new users and rooms if necessary.
+You will need to make sure that the room_id already exists in the database. You can use the Supabase client to create new users and rooms if necessary.
 
 ```typescript
 const message = {
-  agentId: "agent-uuid", // Replace with your agent's UUID
-  senderId: "user-uuid", // Replace with the sender's UUID
-  userIds: ["user-uuid"], // List of user UUIDs involved in the conversation
+  userId: "user-uuid", // Replace with the sender's UUID
   content: { content: content }, // The message content
   room_id: "room-uuid", // Replace with the room's UUID
 };
diff --git a/docs/docs/classes/BgentRuntime.md b/docs/docs/classes/BgentRuntime.md
index f7d438d..0d20922 100644
--- a/docs/docs/classes/BgentRuntime.md
+++ b/docs/docs/classes/BgentRuntime.md
@@ -23,6 +23,7 @@ Creates an instance of BgentRuntime.
 | :------ | :------ | :------ |
 | `opts` | `Object` | The options for configuring the BgentRuntime. |
 | `opts.actions?` | [`Action`](../interfaces/Action.md)[] | Optional custom actions. |
+| `opts.agentId?` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` | Optional ID of the agent. |
 | `opts.databaseAdapter` | [`DatabaseAdapter`](DatabaseAdapter.md) | The database adapter used for interacting with the database. |
 | `opts.debugMode?` | `boolean` | If true, debug messages will be logged. |
 | `opts.embeddingModel?` | `string` | The model to use for embedding. |
@@ -47,6 +48,14 @@ Custom actions that the agent can perform.
 
 ___
 
+### agentId
+
+• **agentId**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` = `zeroUuid`
+
+The ID of the agent
+
+___
+
 ### databaseAdapter
 
 • **databaseAdapter**: [`DatabaseAdapter`](DatabaseAdapter.md)
@@ -170,7 +179,7 @@ ___
 
 ### composeState
 
-▸ **composeState**(`message`): `Promise`\<\{ `actionConditions`: `string` ; `actionExamples`: `string` ; `actionNames`: `string` ; `actions`: `string` ; `actors`: `string` ; `actorsData`: [`Actor`](../interfaces/Actor.md)[] ; `agentId`: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` ; `agentName`: `undefined` \| `string` ; `evaluatorConditions`: `string` ; `evaluatorExamples`: `string` ; `evaluatorNames`: `string` ; `evaluators`: `string` ; `evaluatorsData`: [`Evaluator`](../interfaces/Evaluator.md)[] ; `goals`: `string` ; `goalsData`: [`Goal`](../interfaces/Goal.md)[] ; `lore`: `string` ; `loreData`: [`Memory`](../interfaces/Memory.md)[] ; `providers`: `string` ; `recentFacts`: `string` ; `recentFactsData`: [`Memory`](../interfaces/Memory.md)[] ; `recentMessages`: `string` ; `recentMessagesData`: [`Memory`](../interfaces/Memory.md)[] ; `relevantFacts`: `string` ; `relevantFactsData`: [`Memory`](../interfaces/Memory.md)[] ; `room_id`: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` ; `senderName`: `undefined` \| `string` ; `userIds`: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]  }\>
+▸ **composeState**(`message`): `Promise`\<\{ `actionConditions`: `string` ; `actionExamples`: `string` ; `actionNames`: `string` ; `actions`: `string` ; `actors`: `string` ; `actorsData`: [`Actor`](../interfaces/Actor.md)[] ; `agentId`: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` ; `agentName`: `undefined` \| `string` ; `evaluatorConditions`: `string` ; `evaluatorExamples`: `string` ; `evaluatorNames`: `string` ; `evaluators`: `string` ; `evaluatorsData`: [`Evaluator`](../interfaces/Evaluator.md)[] ; `goals`: `string` ; `goalsData`: [`Goal`](../interfaces/Goal.md)[] ; `lore`: `string` ; `loreData`: [`Memory`](../interfaces/Memory.md)[] ; `providers`: `string` ; `recentFacts`: `string` ; `recentFactsData`: [`Memory`](../interfaces/Memory.md)[] ; `recentMessages`: `string` ; `recentMessagesData`: [`Memory`](../interfaces/Memory.md)[] ; `relevantFacts`: `string` ; `relevantFactsData`: [`Memory`](../interfaces/Memory.md)[] ; `room_id`: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` ; `senderName`: `undefined` \| `string`  }\>
 
 Compose the state of the agent into an object that can be passed or used for response generation.
 
@@ -182,7 +191,7 @@ Compose the state of the agent into an object that can be passed or used for res
 
 #### Returns
 
-`Promise`\<\{ `actionConditions`: `string` ; `actionExamples`: `string` ; `actionNames`: `string` ; `actions`: `string` ; `actors`: `string` ; `actorsData`: [`Actor`](../interfaces/Actor.md)[] ; `agentId`: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` ; `agentName`: `undefined` \| `string` ; `evaluatorConditions`: `string` ; `evaluatorExamples`: `string` ; `evaluatorNames`: `string` ; `evaluators`: `string` ; `evaluatorsData`: [`Evaluator`](../interfaces/Evaluator.md)[] ; `goals`: `string` ; `goalsData`: [`Goal`](../interfaces/Goal.md)[] ; `lore`: `string` ; `loreData`: [`Memory`](../interfaces/Memory.md)[] ; `providers`: `string` ; `recentFacts`: `string` ; `recentFactsData`: [`Memory`](../interfaces/Memory.md)[] ; `recentMessages`: `string` ; `recentMessagesData`: [`Memory`](../interfaces/Memory.md)[] ; `relevantFacts`: `string` ; `relevantFactsData`: [`Memory`](../interfaces/Memory.md)[] ; `room_id`: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` ; `senderName`: `undefined` \| `string` ; `userIds`: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]  }\>
+`Promise`\<\{ `actionConditions`: `string` ; `actionExamples`: `string` ; `actionNames`: `string` ; `actions`: `string` ; `actors`: `string` ; `actorsData`: [`Actor`](../interfaces/Actor.md)[] ; `agentId`: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` ; `agentName`: `undefined` \| `string` ; `evaluatorConditions`: `string` ; `evaluatorExamples`: `string` ; `evaluatorNames`: `string` ; `evaluators`: `string` ; `evaluatorsData`: [`Evaluator`](../interfaces/Evaluator.md)[] ; `goals`: `string` ; `goalsData`: [`Goal`](../interfaces/Goal.md)[] ; `lore`: `string` ; `loreData`: [`Memory`](../interfaces/Memory.md)[] ; `providers`: `string` ; `recentFacts`: `string` ; `recentFactsData`: [`Memory`](../interfaces/Memory.md)[] ; `recentMessages`: `string` ; `recentMessagesData`: [`Memory`](../interfaces/Memory.md)[] ; `relevantFacts`: `string` ; `relevantFactsData`: [`Memory`](../interfaces/Memory.md)[] ; `room_id`: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` ; `senderName`: `undefined` \| `string`  }\>
 
 The state of the agent.
 
@@ -317,9 +326,9 @@ Register an evaluator to assess and guide the agent's responses.
 
 ___
 
-### retriveCachedEmbedding
+### retrieveCachedEmbedding
 
-▸ **retriveCachedEmbedding**(`input`): `Promise`\<``null`` \| `number`[]\>
+▸ **retrieveCachedEmbedding**(`input`): `Promise`\<``null`` \| `number`[]\>
 
 #### Parameters
 
diff --git a/docs/docs/classes/DatabaseAdapter.md b/docs/docs/classes/DatabaseAdapter.md
index bc60193..96a0757 100644
--- a/docs/docs/classes/DatabaseAdapter.md
+++ b/docs/docs/classes/DatabaseAdapter.md
@@ -12,6 +12,8 @@ custom_edit_url: null
 
   ↳ [`SupabaseDatabaseAdapter`](SupabaseDatabaseAdapter.md)
 
+  ↳ [`SqliteDatabaseAdapter`](SqliteDatabaseAdapter.md)
+
 ## Constructors
 
 ### constructor
@@ -24,15 +26,32 @@ custom_edit_url: null
 
 ## Methods
 
-### countMemoriesByUserIds
+### addParticipantToRoom
 
-▸ **countMemoriesByUserIds**(`userIds`, `unique?`, `tableName?`): `Promise`\<`number`\>
+▸ **addParticipantToRoom**(`userId`, `roomId`): `Promise`\<`void`\>
 
 #### Parameters
 
 | Name | Type |
 | :------ | :------ |
-| `userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
+| `userId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+| `roomId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+___
+
+### countMemories
+
+▸ **countMemories**(`room_id`, `unique?`, `tableName?`): `Promise`\<`number`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 | `unique?` | `boolean` |
 | `tableName?` | `string` |
 
@@ -50,7 +69,7 @@ ___
 
 | Name | Type |
 | :------ | :------ |
-| `account` | `Account` |
+| `account` | [`Account`](../interfaces/Account.md) |
 
 #### Returns
 
@@ -110,9 +129,25 @@ ___
 
 ___
 
+### createRoom
+
+▸ **createRoom**(`name`): `Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `name` | `string` |
+
+#### Returns
+
+`Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`\>
+
+___
+
 ### getAccountById
 
-▸ **getAccountById**(`userId`): `Promise`\<``null`` \| `Account`\>
+▸ **getAccountById**(`userId`): `Promise`\<``null`` \| [`Account`](../interfaces/Account.md)\>
 
 #### Parameters
 
@@ -122,7 +157,7 @@ ___
 
 #### Returns
 
-`Promise`\<``null`` \| `Account`\>
+`Promise`\<``null`` \| [`Account`](../interfaces/Account.md)\>
 
 ___
 
@@ -135,7 +170,7 @@ ___
 | Name | Type |
 | :------ | :------ |
 | `params` | `Object` |
-| `params.userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
+| `params.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 
 #### Returns
 
@@ -154,8 +189,8 @@ ___
 | `params` | `Object` |
 | `params.count?` | `number` |
 | `params.onlyInProgress?` | `boolean` |
+| `params.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 | `params.userId?` | ``null`` \| \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
-| `params.userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
 
 #### Returns
 
@@ -163,9 +198,9 @@ ___
 
 ___
 
-### getMemoriesByIds
+### getMemories
 
-▸ **getMemoriesByIds**(`params`): `Promise`\<[`Memory`](../interfaces/Memory.md)[]\>
+▸ **getMemories**(`params`): `Promise`\<[`Memory`](../interfaces/Memory.md)[]\>
 
 #### Parameters
 
@@ -173,9 +208,9 @@ ___
 | :------ | :------ |
 | `params` | `Object` |
 | `params.count?` | `number` |
+| `params.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 | `params.tableName` | `string` |
 | `params.unique?` | `boolean` |
-| `params.userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
 
 #### Returns
 
@@ -183,9 +218,9 @@ ___
 
 ___
 
-### getMemoryByContent
+### getCachedEmbeddings
 
-▸ **getMemoryByContent**(`«destructured»`): `Promise`\<`SimilaritySearch`[]\>
+▸ **getCachedEmbeddings**(`«destructured»`): `Promise`\<`SimilaritySearch`[]\>
 
 #### Parameters
 
@@ -240,6 +275,38 @@ ___
 
 ___
 
+### getRoomsByParticipant
+
+▸ **getRoomsByParticipant**(`userId`): `Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `userId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]\>
+
+___
+
+### getRoomsByParticipants
+
+▸ **getRoomsByParticipants**(`userIds`): `Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
+
+#### Returns
+
+`Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]\>
+
+___
+
 ### log
 
 ▸ **log**(`params`): `Promise`\<`void`\>
@@ -249,12 +316,10 @@ ___
 | Name | Type |
 | :------ | :------ |
 | `params` | `Object` |
-| `params.agent_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 | `params.body` | `Object` |
 | `params.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 | `params.type` | `string` |
 | `params.user_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
-| `params.user_ids` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
 
 #### Returns
 
@@ -262,15 +327,31 @@ ___
 
 ___
 
-### removeAllMemoriesByUserIds
+### removeAllGoals
 
-▸ **removeAllMemoriesByUserIds**(`userIds`, `tableName`): `Promise`\<`void`\>
+▸ **removeAllGoals**(`room_id`): `Promise`\<`void`\>
 
 #### Parameters
 
 | Name | Type |
 | :------ | :------ |
-| `userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
+| `room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+___
+
+### removeAllMemories
+
+▸ **removeAllMemories**(`room_id`, `tableName`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 | `tableName` | `string` |
 
 #### Returns
@@ -279,6 +360,22 @@ ___
 
 ___
 
+### removeGoal
+
+▸ **removeGoal**(`goalId`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `goalId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+___
+
 ### removeMemory
 
 ▸ **removeMemory**(`memoryId`, `tableName`): `Promise`\<`void`\>
@@ -296,6 +393,39 @@ ___
 
 ___
 
+### removeParticipantFromRoom
+
+▸ **removeParticipantFromRoom**(`userId`, `roomId`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `userId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+| `roomId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+___
+
+### removeRoom
+
+▸ **removeRoom**(`roomId`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `roomId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+___
+
 ### searchMemories
 
 ▸ **searchMemories**(`params`): `Promise`\<[`Memory`](../interfaces/Memory.md)[]\>
@@ -308,9 +438,9 @@ ___
 | `params.embedding` | `number`[] |
 | `params.match_count` | `number` |
 | `params.match_threshold` | `number` |
+| `params.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 | `params.tableName` | `string` |
 | `params.unique` | `boolean` |
-| `params.userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
 
 #### Returns
 
@@ -330,9 +460,9 @@ ___
 | `params` | `Object` |
 | `params.count?` | `number` |
 | `params.match_threshold?` | `number` |
+| `params.room_id?` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 | `params.tableName` | `string` |
 | `params.unique?` | `boolean` |
-| `params.userIds?` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
 
 #### Returns
 
diff --git a/docs/docs/classes/MemoryManager.md b/docs/docs/classes/MemoryManager.md
index a8a873a..8c65bae 100644
--- a/docs/docs/classes/MemoryManager.md
+++ b/docs/docs/classes/MemoryManager.md
@@ -66,9 +66,9 @@ A Promise resolving to the memory object, potentially updated with an embedding
 
 ___
 
-### countMemoriesByUserIds
+### countMemories
 
-▸ **countMemoriesByUserIds**(`userIds`, `unique?`): `Promise`\<`number`\>
+▸ **countMemories**(`room_id`, `unique?`): `Promise`\<`number`\>
 
 Counts the number of memories associated with a set of user IDs, with an option for uniqueness.
 
@@ -76,7 +76,7 @@ Counts the number of memories associated with a set of user IDs, with an option
 
 | Name | Type | Default value | Description |
 | :------ | :------ | :------ | :------ |
-| `userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] | `undefined` | An array of user IDs to count memories for. |
+| `room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` | `undefined` | The room ID to count memories for. |
 | `unique` | `boolean` | `true` | Whether to count unique memories only. |
 
 #### Returns
@@ -108,9 +108,9 @@ A Promise that resolves when the operation completes.
 
 ___
 
-### getMemoriesByIds
+### getMemories
 
-▸ **getMemoriesByIds**(`opts`): `Promise`\<[`Memory`](../interfaces/Memory.md)[]\>
+▸ **getMemories**(`opts`): `Promise`\<[`Memory`](../interfaces/Memory.md)[]\>
 
 Retrieves a list of memories by user IDs, with optional deduplication.
 
@@ -120,8 +120,8 @@ Retrieves a list of memories by user IDs, with optional deduplication.
 | :------ | :------ | :------ | :------ |
 | `opts` | `Object` | `undefined` | Options including user IDs, count, and uniqueness. |
 | `opts.count?` | `number` | `10` | The number of memories to retrieve. |
+| `opts.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` | `undefined` | The room ID to retrieve memories for. |
 | `opts.unique?` | `boolean` | `true` | Whether to retrieve unique memories only. |
-| `opts.userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] | `undefined` | An array of user IDs to retrieve memories for. |
 
 #### Returns
 
@@ -131,9 +131,9 @@ A Promise resolving to an array of Memory objects.
 
 ___
 
-### getMemoryByContent
+### getCachedEmbeddings
 
-▸ **getMemoryByContent**(`content`): `Promise`\<`SimilaritySearch`[]\>
+▸ **getCachedEmbeddings**(`content`): `Promise`\<`SimilaritySearch`[]\>
 
 #### Parameters
 
@@ -147,9 +147,9 @@ ___
 
 ___
 
-### removeAllMemoriesByUserIds
+### removeAllMemories
 
-▸ **removeAllMemoriesByUserIds**(`userIds`): `Promise`\<`void`\>
+▸ **removeAllMemories**(`room_id`): `Promise`\<`void`\>
 
 Removes all memories associated with a set of user IDs.
 
@@ -157,7 +157,7 @@ Removes all memories associated with a set of user IDs.
 
 | Name | Type | Description |
 | :------ | :------ | :------ |
-| `userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] | An array of user IDs to remove memories for. |
+| `room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` | The room ID to remove memories for. |
 
 #### Returns
 
@@ -201,8 +201,8 @@ Searches for memories similar to a given embedding vector.
 | `opts` | `Object` | Options including match threshold, count, user IDs, and uniqueness. |
 | `opts.count?` | `number` | The maximum number of memories to retrieve. |
 | `opts.match_threshold?` | `number` | The similarity threshold for matching memories. |
+| `opts.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` | The room ID to retrieve memories for. |
 | `opts.unique?` | `boolean` | Whether to retrieve unique memories only. |
-| `opts.userIds?` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] | An array of user IDs to retrieve memories for. |
 
 #### Returns
 
diff --git a/docs/docs/classes/SqliteDatabaseAdapter.md b/docs/docs/classes/SqliteDatabaseAdapter.md
new file mode 100644
index 0000000..ec1290d
--- /dev/null
+++ b/docs/docs/classes/SqliteDatabaseAdapter.md
@@ -0,0 +1,619 @@
+---
+id: "SqliteDatabaseAdapter"
+title: "Class: SqliteDatabaseAdapter"
+sidebar_label: "SqliteDatabaseAdapter"
+sidebar_position: 0
+custom_edit_url: null
+---
+
+## Hierarchy
+
+- [`DatabaseAdapter`](DatabaseAdapter.md)
+
+  ↳ **`SqliteDatabaseAdapter`**
+
+## Constructors
+
+### constructor
+
+• **new SqliteDatabaseAdapter**(`db`): [`SqliteDatabaseAdapter`](SqliteDatabaseAdapter.md)
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `db` | `Database` |
+
+#### Returns
+
+[`SqliteDatabaseAdapter`](SqliteDatabaseAdapter.md)
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[constructor](DatabaseAdapter.md#constructor)
+
+## Methods
+
+### addParticipantToRoom
+
+▸ **addParticipantToRoom**(`userId`, `roomId`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `userId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+| `roomId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[addParticipantToRoom](DatabaseAdapter.md#addparticipanttoroom)
+
+___
+
+### countMemories
+
+▸ **countMemories**(`room_id`, `unique?`, `tableName?`): `Promise`\<`number`\>
+
+#### Parameters
+
+| Name | Type | Default value |
+| :------ | :------ | :------ |
+| `room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` | `undefined` |
+| `unique` | `boolean` | `true` |
+| `tableName` | `string` | `""` |
+
+#### Returns
+
+`Promise`\<`number`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[countMemories](DatabaseAdapter.md#countmemoriesbyroomid)
+
+___
+
+### createAccount
+
+▸ **createAccount**(`account`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `account` | [`Account`](../interfaces/Account.md) |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[createAccount](DatabaseAdapter.md#createaccount)
+
+___
+
+### createGoal
+
+▸ **createGoal**(`goal`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `goal` | [`Goal`](../interfaces/Goal.md) |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[createGoal](DatabaseAdapter.md#creategoal)
+
+___
+
+### createMemory
+
+▸ **createMemory**(`memory`, `tableName`, `unique?`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type | Default value |
+| :------ | :------ | :------ |
+| `memory` | [`Memory`](../interfaces/Memory.md) | `undefined` |
+| `tableName` | `string` | `undefined` |
+| `unique` | `boolean` | `false` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[createMemory](DatabaseAdapter.md#creatememory)
+
+___
+
+### createRelationship
+
+▸ **createRelationship**(`params`): `Promise`\<`boolean`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | `Object` |
+| `params.userA` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+| `params.userB` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`boolean`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[createRelationship](DatabaseAdapter.md#createrelationship)
+
+___
+
+### createRoom
+
+▸ **createRoom**(`name`): `Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `name` | `string` |
+
+#### Returns
+
+`Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[createRoom](DatabaseAdapter.md#createroom)
+
+___
+
+### getAccountById
+
+▸ **getAccountById**(`userId`): `Promise`\<``null`` \| [`Account`](../interfaces/Account.md)\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `userId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<``null`` \| [`Account`](../interfaces/Account.md)\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[getAccountById](DatabaseAdapter.md#getaccountbyid)
+
+___
+
+### getActorDetails
+
+▸ **getActorDetails**(`params`): `Promise`\<[`Actor`](../interfaces/Actor.md)[]\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | `Object` |
+| `params.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<[`Actor`](../interfaces/Actor.md)[]\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[getActorDetails](DatabaseAdapter.md#getactordetails)
+
+___
+
+### getGoals
+
+▸ **getGoals**(`params`): `Promise`\<[`Goal`](../interfaces/Goal.md)[]\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | `Object` |
+| `params.count?` | `number` |
+| `params.onlyInProgress?` | `boolean` |
+| `params.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+| `params.userId?` | ``null`` \| \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<[`Goal`](../interfaces/Goal.md)[]\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[getGoals](DatabaseAdapter.md#getgoals)
+
+___
+
+### getMemories
+
+▸ **getMemories**(`params`): `Promise`\<[`Memory`](../interfaces/Memory.md)[]\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | `Object` |
+| `params.count?` | `number` |
+| `params.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+| `params.tableName` | `string` |
+| `params.unique?` | `boolean` |
+
+#### Returns
+
+`Promise`\<[`Memory`](../interfaces/Memory.md)[]\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[getMemories](DatabaseAdapter.md#getmemoriesbyroomid)
+
+___
+
+### getCachedEmbeddings
+
+▸ **getCachedEmbeddings**(`opts`): `Promise`\<[]\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `opts` | `Object` |
+| `opts.query_field_name` | `string` |
+| `opts.query_field_sub_name` | `string` |
+| `opts.query_input` | `string` |
+| `opts.query_match_count` | `number` |
+| `opts.query_table_name` | `string` |
+| `opts.query_threshold` | `number` |
+
+#### Returns
+
+`Promise`\<[]\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[getCachedEmbeddings](DatabaseAdapter.md#getmemorybycontent)
+
+___
+
+### getRelationship
+
+▸ **getRelationship**(`params`): `Promise`\<``null`` \| [`Relationship`](../interfaces/Relationship.md)\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | `Object` |
+| `params.userA` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+| `params.userB` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<``null`` \| [`Relationship`](../interfaces/Relationship.md)\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[getRelationship](DatabaseAdapter.md#getrelationship)
+
+___
+
+### getRelationships
+
+▸ **getRelationships**(`params`): `Promise`\<[`Relationship`](../interfaces/Relationship.md)[]\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | `Object` |
+| `params.userId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<[`Relationship`](../interfaces/Relationship.md)[]\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[getRelationships](DatabaseAdapter.md#getrelationships)
+
+___
+
+### getRoomsByParticipant
+
+▸ **getRoomsByParticipant**(`userId`): `Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `userId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[getRoomsByParticipant](DatabaseAdapter.md#getroomsbyparticipant)
+
+___
+
+### getRoomsByParticipants
+
+▸ **getRoomsByParticipants**(`userIds`): `Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
+
+#### Returns
+
+`Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[getRoomsByParticipants](DatabaseAdapter.md#getroomsbyparticipants)
+
+___
+
+### log
+
+▸ **log**(`params`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | `Object` |
+| `params.body` | `Object` |
+| `params.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+| `params.type` | `string` |
+| `params.user_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[log](DatabaseAdapter.md#log)
+
+___
+
+### removeAllGoals
+
+▸ **removeAllGoals**(`room_id`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[removeAllGoals](DatabaseAdapter.md#removeallgoalsbyroomid)
+
+___
+
+### removeAllMemories
+
+▸ **removeAllMemories**(`room_id`, `tableName`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+| `tableName` | `string` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[removeAllMemories](DatabaseAdapter.md#removeallmemoriesbyroomid)
+
+___
+
+### removeGoal
+
+▸ **removeGoal**(`goalId`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `goalId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[removeGoal](DatabaseAdapter.md#removegoal)
+
+___
+
+### removeMemory
+
+▸ **removeMemory**(`memoryId`, `tableName`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `memoryId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+| `tableName` | `string` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[removeMemory](DatabaseAdapter.md#removememory)
+
+___
+
+### removeParticipantFromRoom
+
+▸ **removeParticipantFromRoom**(`userId`, `roomId`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `userId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+| `roomId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[removeParticipantFromRoom](DatabaseAdapter.md#removeparticipantfromroom)
+
+___
+
+### removeRoom
+
+▸ **removeRoom**(`roomId`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `roomId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[removeRoom](DatabaseAdapter.md#removeroom)
+
+___
+
+### searchMemories
+
+▸ **searchMemories**(`params`): `Promise`\<[`Memory`](../interfaces/Memory.md)[]\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | `Object` |
+| `params.embedding` | `number`[] |
+| `params.match_count` | `number` |
+| `params.match_threshold` | `number` |
+| `params.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+| `params.tableName` | `string` |
+| `params.unique` | `boolean` |
+
+#### Returns
+
+`Promise`\<[`Memory`](../interfaces/Memory.md)[]\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[searchMemories](DatabaseAdapter.md#searchmemories)
+
+___
+
+### searchMemoriesByEmbedding
+
+▸ **searchMemoriesByEmbedding**(`embedding`, `params`): `Promise`\<[`Memory`](../interfaces/Memory.md)[]\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `embedding` | `number`[] |
+| `params` | `Object` |
+| `params.count?` | `number` |
+| `params.match_threshold?` | `number` |
+| `params.room_id?` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+| `params.tableName` | `string` |
+| `params.unique?` | `boolean` |
+
+#### Returns
+
+`Promise`\<[`Memory`](../interfaces/Memory.md)[]\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[searchMemoriesByEmbedding](DatabaseAdapter.md#searchmemoriesbyembedding)
+
+___
+
+### updateGoal
+
+▸ **updateGoal**(`goal`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `goal` | [`Goal`](../interfaces/Goal.md) |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[updateGoal](DatabaseAdapter.md#updategoal)
+
+___
+
+### updateGoalStatus
+
+▸ **updateGoalStatus**(`params`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `params` | `Object` |
+| `params.goalId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+| `params.status` | [`GoalStatus`](../enums/GoalStatus.md) |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[updateGoalStatus](DatabaseAdapter.md#updategoalstatus)
diff --git a/docs/docs/classes/SupabaseDatabaseAdapter.md b/docs/docs/classes/SupabaseDatabaseAdapter.md
index c0abc51..5cda4c7 100644
--- a/docs/docs/classes/SupabaseDatabaseAdapter.md
+++ b/docs/docs/classes/SupabaseDatabaseAdapter.md
@@ -35,15 +35,36 @@ custom_edit_url: null
 
 ## Methods
 
-### countMemoriesByUserIds
+### addParticipantToRoom
 
-▸ **countMemoriesByUserIds**(`userIds`, `unique?`, `tableName`): `Promise`\<`number`\>
+▸ **addParticipantToRoom**(`userId`, `roomId`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `userId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+| `roomId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[addParticipantToRoom](DatabaseAdapter.md#addparticipanttoroom)
+
+___
+
+### countMemories
+
+▸ **countMemories**(`room_id`, `unique?`, `tableName`): `Promise`\<`number`\>
 
 #### Parameters
 
 | Name | Type | Default value |
 | :------ | :------ | :------ |
-| `userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] | `undefined` |
+| `room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` | `undefined` |
 | `unique` | `boolean` | `true` |
 | `tableName` | `string` | `undefined` |
 
@@ -53,7 +74,7 @@ custom_edit_url: null
 
 #### Overrides
 
-[DatabaseAdapter](DatabaseAdapter.md).[countMemoriesByUserIds](DatabaseAdapter.md#countmemoriesbyuserids)
+[DatabaseAdapter](DatabaseAdapter.md).[countMemories](DatabaseAdapter.md#countmemoriesbyroomid)
 
 ___
 
@@ -65,7 +86,7 @@ ___
 
 | Name | Type |
 | :------ | :------ |
-| `account` | `Account` |
+| `account` | [`Account`](../interfaces/Account.md) |
 
 #### Returns
 
@@ -141,9 +162,29 @@ ___
 
 ___
 
+### createRoom
+
+▸ **createRoom**(`name`): `Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `name` | `string` |
+
+#### Returns
+
+`Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[createRoom](DatabaseAdapter.md#createroom)
+
+___
+
 ### getAccountById
 
-▸ **getAccountById**(`userId`): `Promise`\<``null`` \| `Account`\>
+▸ **getAccountById**(`userId`): `Promise`\<``null`` \| [`Account`](../interfaces/Account.md)\>
 
 #### Parameters
 
@@ -153,7 +194,7 @@ ___
 
 #### Returns
 
-`Promise`\<``null`` \| `Account`\>
+`Promise`\<``null`` \| [`Account`](../interfaces/Account.md)\>
 
 #### Overrides
 
@@ -170,7 +211,7 @@ ___
 | Name | Type |
 | :------ | :------ |
 | `params` | `Object` |
-| `params.userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
+| `params.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 
 #### Returns
 
@@ -193,8 +234,8 @@ ___
 | `params` | `Object` |
 | `params.count?` | `number` |
 | `params.onlyInProgress?` | `boolean` |
+| `params.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 | `params.userId?` | ``null`` \| \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
-| `params.userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
 
 #### Returns
 
@@ -206,9 +247,9 @@ ___
 
 ___
 
-### getMemoriesByIds
+### getMemories
 
-▸ **getMemoriesByIds**(`params`): `Promise`\<[`Memory`](../interfaces/Memory.md)[]\>
+▸ **getMemories**(`params`): `Promise`\<[`Memory`](../interfaces/Memory.md)[]\>
 
 #### Parameters
 
@@ -216,9 +257,9 @@ ___
 | :------ | :------ |
 | `params` | `Object` |
 | `params.count?` | `number` |
+| `params.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 | `params.tableName` | `string` |
 | `params.unique?` | `boolean` |
-| `params.userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
 
 #### Returns
 
@@ -226,13 +267,13 @@ ___
 
 #### Overrides
 
-[DatabaseAdapter](DatabaseAdapter.md).[getMemoriesByIds](DatabaseAdapter.md#getmemoriesbyids)
+[DatabaseAdapter](DatabaseAdapter.md).[getMemories](DatabaseAdapter.md#getmemoriesbyroomid)
 
 ___
 
-### getMemoryByContent
+### getCachedEmbeddings
 
-▸ **getMemoryByContent**(`opts`): `Promise`\<`SimilaritySearch`[]\>
+▸ **getCachedEmbeddings**(`opts`): `Promise`\<`SimilaritySearch`[]\>
 
 #### Parameters
 
@@ -252,7 +293,7 @@ ___
 
 #### Overrides
 
-[DatabaseAdapter](DatabaseAdapter.md).[getMemoryByContent](DatabaseAdapter.md#getmemorybycontent)
+[DatabaseAdapter](DatabaseAdapter.md).[getCachedEmbeddings](DatabaseAdapter.md#getmemorybycontent)
 
 ___
 
@@ -299,6 +340,46 @@ ___
 
 ___
 
+### getRoomsByParticipant
+
+▸ **getRoomsByParticipant**(`userId`): `Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `userId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[getRoomsByParticipant](DatabaseAdapter.md#getroomsbyparticipant)
+
+___
+
+### getRoomsByParticipants
+
+▸ **getRoomsByParticipants**(`userIds`): `Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
+
+#### Returns
+
+`Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[getRoomsByParticipants](DatabaseAdapter.md#getroomsbyparticipants)
+
+___
+
 ### log
 
 ▸ **log**(`params`): `Promise`\<`void`\>
@@ -308,12 +389,10 @@ ___
 | Name | Type |
 | :------ | :------ |
 | `params` | `Object` |
-| `params.agent_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 | `params.body` | `Object` |
 | `params.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 | `params.type` | `string` |
 | `params.user_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
-| `params.user_ids` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
 
 #### Returns
 
@@ -325,15 +404,35 @@ ___
 
 ___
 
-### removeAllMemoriesByUserIds
+### removeAllGoals
 
-▸ **removeAllMemoriesByUserIds**(`userIds`, `tableName`): `Promise`\<`void`\>
+▸ **removeAllGoals**(`room_id`): `Promise`\<`void`\>
 
 #### Parameters
 
 | Name | Type |
 | :------ | :------ |
-| `userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
+| `room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[removeAllGoals](DatabaseAdapter.md#removeallgoalsbyroomid)
+
+___
+
+### removeAllMemories
+
+▸ **removeAllMemories**(`room_id`, `tableName`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 | `tableName` | `string` |
 
 #### Returns
@@ -342,20 +441,39 @@ ___
 
 #### Overrides
 
-[DatabaseAdapter](DatabaseAdapter.md).[removeAllMemoriesByUserIds](DatabaseAdapter.md#removeallmemoriesbyuserids)
+[DatabaseAdapter](DatabaseAdapter.md).[removeAllMemories](DatabaseAdapter.md#removeallmemoriesbyroomid)
+
+___
+
+### removeGoal
+
+▸ **removeGoal**(`goalId`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `goalId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[removeGoal](DatabaseAdapter.md#removegoal)
 
 ___
 
 ### removeMemory
 
-▸ **removeMemory**(`memoryId`, `tableName`): `Promise`\<`void`\>
+▸ **removeMemory**(`memoryId`): `Promise`\<`void`\>
 
 #### Parameters
 
 | Name | Type |
 | :------ | :------ |
 | `memoryId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
-| `tableName` | `string` |
 
 #### Returns
 
@@ -367,6 +485,47 @@ ___
 
 ___
 
+### removeParticipantFromRoom
+
+▸ **removeParticipantFromRoom**(`userId`, `roomId`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `userId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+| `roomId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[removeParticipantFromRoom](DatabaseAdapter.md#removeparticipantfromroom)
+
+___
+
+### removeRoom
+
+▸ **removeRoom**(`roomId`): `Promise`\<`void`\>
+
+#### Parameters
+
+| Name | Type |
+| :------ | :------ |
+| `roomId` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
+
+#### Returns
+
+`Promise`\<`void`\>
+
+#### Overrides
+
+[DatabaseAdapter](DatabaseAdapter.md).[removeRoom](DatabaseAdapter.md#removeroom)
+
+___
+
 ### searchMemories
 
 ▸ **searchMemories**(`params`): `Promise`\<[`Memory`](../interfaces/Memory.md)[]\>
@@ -379,9 +538,9 @@ ___
 | `params.embedding` | `number`[] |
 | `params.match_count` | `number` |
 | `params.match_threshold` | `number` |
+| `params.room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 | `params.tableName` | `string` |
 | `params.unique` | `boolean` |
-| `params.userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
 
 #### Returns
 
@@ -405,9 +564,9 @@ ___
 | `params` | `Object` |
 | `params.count?` | `number` |
 | `params.match_threshold?` | `number` |
+| `params.room_id?` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 | `params.tableName` | `string` |
 | `params.unique?` | `boolean` |
-| `params.userIds?` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
 
 #### Returns
 
diff --git a/docs/docs/functions/getActorDetails.md b/docs/docs/functions/getActorDetails.md
index d4b1181..fd5366d 100644
--- a/docs/docs/functions/getActorDetails.md
+++ b/docs/docs/functions/getActorDetails.md
@@ -15,8 +15,8 @@ Get details for a list of actors.
 | Name | Type |
 | :------ | :------ |
 | `«destructured»` | `Object` |
+| › `room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` |
 | › `runtime` | [`BgentRuntime`](../classes/BgentRuntime.md) |
-| › `userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] |
 
 #### Returns
 
diff --git a/docs/docs/functions/getGoals.md b/docs/docs/functions/getGoals.md
index deedad5..8e99ef4 100644
--- a/docs/docs/functions/getGoals.md
+++ b/docs/docs/functions/getGoals.md
@@ -15,9 +15,9 @@ custom_edit_url: null
 | `«destructured»` | `Object` | `undefined` |
 | › `count?` | `number` | `5` |
 | › `onlyInProgress?` | `boolean` | `true` |
+| › `room_id` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` | `undefined` |
 | › `runtime` | [`BgentRuntime`](../classes/BgentRuntime.md) | `undefined` |
 | › `userId?` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` | `undefined` |
-| › `userIds` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[] | `undefined` |
 
 #### Returns
 
diff --git a/docs/docs/functions/getLore.md b/docs/docs/functions/getLore.md
index 44c87da..878c702 100644
--- a/docs/docs/functions/getLore.md
+++ b/docs/docs/functions/getLore.md
@@ -12,13 +12,14 @@ Retrieves lore from the lore database based on a search query. This function use
 
 #### Parameters
 
-| Name | Type | Description |
-| :------ | :------ | :------ |
-| `params` | `Object` | The parameters for retrieving lore. |
-| `params.count?` | `number` | The maximum number of lore entries to retrieve. |
-| `params.match_threshold?` | `number` | The similarity threshold for matching lore entries, lower values mean more strict matching. |
-| `params.message` | `string` | The search query message to find relevant lore. |
-| `params.runtime` | [`BgentRuntime`](../classes/BgentRuntime.md) | The runtime environment of the agent. |
+| Name | Type | Default value | Description |
+| :------ | :------ | :------ | :------ |
+| `params` | `Object` | `undefined` | The parameters for retrieving lore. |
+| `params.count?` | `number` | `undefined` | The maximum number of lore entries to retrieve. |
+| `params.match_threshold?` | `number` | `undefined` | The similarity threshold for matching lore entries, lower values mean more strict matching. |
+| `params.message` | `string` | `undefined` | The search query message to find relevant lore. |
+| `params.room_id?` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` | `zeroUuid` | - |
+| `params.runtime` | [`BgentRuntime`](../classes/BgentRuntime.md) | `undefined` | The runtime environment of the agent. |
 
 #### Returns
 
diff --git a/docs/docs/index.md b/docs/docs/index.md
index 4a6d18b..4e1859a 100644
--- a/docs/docs/index.md
+++ b/docs/docs/index.md
@@ -53,7 +53,11 @@ npx bgent
 Currently bgent is dependent on Supabase for local development. You can install it with the following command:
 
 ```bash
-npm install bgent @supabase/supabase-js
+npm install bgent
+
+# Select your database adapter
+npm install sqlite-vss better-sqlite3 # for sqlite (simple, for local development)
+npm install @supabase/supabase-js # for supabase (more complicated but can be deployed at scale)
 ```
 
 ### Set up environment variables
@@ -191,13 +195,11 @@ const runtime = new BgentRuntime({
 
 The BgentRuntime instance has a `handleMessage` method that can be used to handle user input. The method returns a promise that resolves to the agent's response.
 
-You will need to make sure that the userIds and room_id already exist in the database. You can use the Supabase client to create new users and rooms if necessary.
+You will need to make sure that the room_id already exists in the database. You can use the Supabase client to create new users and rooms if necessary.
 
 ```typescript
 const message = {
-  agentId: "agent-uuid", // Replace with your agent's UUID
-  senderId: "user-uuid", // Replace with the sender's UUID
-  userIds: ["user-uuid"], // List of user UUIDs involved in the conversation
+  userId: "user-uuid", // Replace with the sender's UUID
   content: { content: content }, // The message content
   room_id: "room-uuid", // Replace with the room's UUID
 };
diff --git a/docs/docs/interfaces/Account.md b/docs/docs/interfaces/Account.md
new file mode 100644
index 0000000..c659f30
--- /dev/null
+++ b/docs/docs/interfaces/Account.md
@@ -0,0 +1,39 @@
+---
+id: "Account"
+title: "Interface: Account"
+sidebar_label: "Account"
+sidebar_position: 0
+custom_edit_url: null
+---
+
+Represents a user, including their name, details, and a unique identifier.
+
+## Properties
+
+### avatar\_url
+
+• `Optional` **avatar\_url**: `string`
+
+___
+
+### details
+
+• `Optional` **details**: `string`
+
+___
+
+### email
+
+• `Optional` **email**: `string`
+
+___
+
+### id
+
+• **id**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`
+
+___
+
+### name
+
+• **name**: `string`
diff --git a/docs/docs/interfaces/Goal.md b/docs/docs/interfaces/Goal.md
index 5b4268b..8feb250 100644
--- a/docs/docs/interfaces/Goal.md
+++ b/docs/docs/interfaces/Goal.md
@@ -28,18 +28,18 @@ ___
 
 ___
 
-### status
+### room\_id
 
-• **status**: [`GoalStatus`](../enums/GoalStatus.md)
+• **room\_id**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`
 
 ___
 
-### user\_id
+### status
 
-• **user\_id**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`
+• **status**: [`GoalStatus`](../enums/GoalStatus.md)
 
 ___
 
-### user\_ids
+### user\_id
 
-• **user\_ids**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]
+• **user\_id**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`
diff --git a/docs/docs/interfaces/Memory.md b/docs/docs/interfaces/Memory.md
index a1e897f..3208495 100644
--- a/docs/docs/interfaces/Memory.md
+++ b/docs/docs/interfaces/Memory.md
@@ -43,9 +43,3 @@ ___
 ### user\_id
 
 • **user\_id**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`
-
-___
-
-### user\_ids
-
-• **user\_ids**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]
diff --git a/docs/docs/interfaces/Message.md b/docs/docs/interfaces/Message.md
index f3c69ff..bc181cf 100644
--- a/docs/docs/interfaces/Message.md
+++ b/docs/docs/interfaces/Message.md
@@ -10,12 +10,6 @@ Represents a message within the conversation, including its content and associat
 
 ## Properties
 
-### agentId
-
-• **agentId**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`
-
-___
-
 ### content
 
 • **content**: [`Content`](Content.md)
@@ -28,12 +22,6 @@ ___
 
 ___
 
-### senderId
-
-• **senderId**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`
-
-___
-
-### userIds
+### userId
 
-• **userIds**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]
+• **userId**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`
diff --git a/docs/docs/interfaces/State.md b/docs/docs/interfaces/State.md
index 151de2d..c0b63d3 100644
--- a/docs/docs/interfaces/State.md
+++ b/docs/docs/interfaces/State.md
@@ -128,18 +128,12 @@ ___
 
 ___
 
-### senderId
-
-• `Optional` **senderId**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`
-
-___
-
 ### senderName
 
 • `Optional` **senderName**: `string`
 
 ___
 
-### userIds
+### userId
 
-• **userIds**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]
+• `Optional` **userId**: \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`
diff --git a/docs/docs/modules.md b/docs/docs/modules.md
index d5468f7..35eb254 100644
--- a/docs/docs/modules.md
+++ b/docs/docs/modules.md
@@ -15,10 +15,12 @@ custom_edit_url: null
 - [BgentRuntime](classes/BgentRuntime.md)
 - [DatabaseAdapter](classes/DatabaseAdapter.md)
 - [MemoryManager](classes/MemoryManager.md)
+- [SqliteDatabaseAdapter](classes/SqliteDatabaseAdapter.md)
 - [SupabaseDatabaseAdapter](classes/SupabaseDatabaseAdapter.md)
 
 ## Interfaces
 
+- [Account](interfaces/Account.md)
 - [Action](interfaces/Action.md)
 - [ActionExample](interfaces/ActionExample.md)
 - [Actor](interfaces/Actor.md)
diff --git a/package-lock.json b/package-lock.json
index 59328bf..a6ddd5c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "bgent",
-  "version": "0.0.41",
+  "version": "0.0.46",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "bgent",
-      "version": "0.0.41",
+      "version": "0.0.46",
       "hasInstallScript": true,
       "license": "MIT",
       "dependencies": {
@@ -15,9 +15,11 @@
         "@tsndr/cloudflare-worker-jwt": "^2.2.1",
         "@typescript-eslint/eslint-plugin": "^7.0.1",
         "ansi-colors": "^4.1.3",
+        "better-sqlite3": "^9.4.3",
         "dotenv": "^16.4.4",
         "figlet": "^1.7.0",
         "inquirer": "^9.2.14",
+        "sqlite-vss": "^0.1.2",
         "ts-node": "^10.9.2",
         "unique-names-generator": "^4.7.1"
       },
@@ -30,6 +32,7 @@
         "@rollup/plugin-node-resolve": "^15.2.3",
         "@rollup/plugin-replace": "^5.0.5",
         "@rollup/plugin-typescript": "^11.1.6",
+        "@types/better-sqlite3": "^7.6.9",
         "@types/jest": "^27.5.2",
         "@types/node": "20.9.4",
         "@typescript-eslint/parser": "^7.0.1",
@@ -60,13 +63,13 @@
       }
     },
     "node_modules/@ampproject/remapping": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
-      "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+      "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/gen-mapping": "^0.3.0",
-        "@jridgewell/trace-mapping": "^0.3.9"
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.24"
       },
       "engines": {
         "node": ">=6.0.0"
@@ -166,9 +169,9 @@
       }
     },
     "node_modules/@babel/core": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz",
-      "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz",
+      "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==",
       "dev": true,
       "dependencies": {
         "@ampproject/remapping": "^2.2.0",
@@ -176,11 +179,11 @@
         "@babel/generator": "^7.23.6",
         "@babel/helper-compilation-targets": "^7.23.6",
         "@babel/helper-module-transforms": "^7.23.3",
-        "@babel/helpers": "^7.23.9",
-        "@babel/parser": "^7.23.9",
-        "@babel/template": "^7.23.9",
-        "@babel/traverse": "^7.23.9",
-        "@babel/types": "^7.23.9",
+        "@babel/helpers": "^7.24.0",
+        "@babel/parser": "^7.24.0",
+        "@babel/template": "^7.24.0",
+        "@babel/traverse": "^7.24.0",
+        "@babel/types": "^7.24.0",
         "convert-source-map": "^2.0.0",
         "debug": "^4.1.0",
         "gensync": "^1.0.0-beta.2",
@@ -310,9 +313,9 @@
       }
     },
     "node_modules/@babel/helper-plugin-utils": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
-      "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz",
+      "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
@@ -370,14 +373,14 @@
       }
     },
     "node_modules/@babel/helpers": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz",
-      "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz",
+      "integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==",
       "dev": true,
       "dependencies": {
-        "@babel/template": "^7.23.9",
-        "@babel/traverse": "^7.23.9",
-        "@babel/types": "^7.23.9"
+        "@babel/template": "^7.24.0",
+        "@babel/traverse": "^7.24.0",
+        "@babel/types": "^7.24.0"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -469,9 +472,9 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz",
-      "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz",
+      "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==",
       "dev": true,
       "bin": {
         "parser": "bin/babel-parser.js"
@@ -658,23 +661,23 @@
       }
     },
     "node_modules/@babel/template": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz",
-      "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz",
+      "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==",
       "dev": true,
       "dependencies": {
         "@babel/code-frame": "^7.23.5",
-        "@babel/parser": "^7.23.9",
-        "@babel/types": "^7.23.9"
+        "@babel/parser": "^7.24.0",
+        "@babel/types": "^7.24.0"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/traverse": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz",
-      "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz",
+      "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==",
       "dev": true,
       "dependencies": {
         "@babel/code-frame": "^7.23.5",
@@ -683,8 +686,8 @@
         "@babel/helper-function-name": "^7.23.0",
         "@babel/helper-hoist-variables": "^7.22.5",
         "@babel/helper-split-export-declaration": "^7.22.6",
-        "@babel/parser": "^7.23.9",
-        "@babel/types": "^7.23.9",
+        "@babel/parser": "^7.24.0",
+        "@babel/types": "^7.24.0",
         "debug": "^4.3.1",
         "globals": "^11.1.0"
       },
@@ -702,9 +705,9 @@
       }
     },
     "node_modules/@babel/types": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz",
-      "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz",
+      "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==",
       "dev": true,
       "dependencies": {
         "@babel/helper-string-parser": "^7.23.4",
@@ -730,10 +733,26 @@
         "mime": "^3.0.0"
       }
     },
+    "node_modules/@cloudflare/workerd-darwin-64": {
+      "version": "1.20240304.0",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240304.0.tgz",
+      "integrity": "sha512-rfHlvsWzkqEEQNvm14AOE/BYHYzB9wxQHCaZZEgwOuTl5KpDcs9La0N0LaDTR78ESumIWOcifVmko2VTrZb7TQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=16"
+      }
+    },
     "node_modules/@cloudflare/workerd-darwin-arm64": {
-      "version": "1.20240129.0",
-      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240129.0.tgz",
-      "integrity": "sha512-t0q8ABkmumG1zRM/MZ/vIv/Ysx0vTAXnQAPy/JW5aeQi/tqrypXkO9/NhPc0jbF/g/hIPrWEqpDgEp3CB7Da7Q==",
+      "version": "1.20240304.0",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240304.0.tgz",
+      "integrity": "sha512-IXGOxHsPdRYfAzcY6IroI1PDvx3hhXf18qFCloHp8Iw5bzLgq/PTjcp10Z/2xedZ2hVlfpHy1eEptsTmi9YeNw==",
       "cpu": [
         "arm64"
       ],
@@ -746,10 +765,58 @@
         "node": ">=16"
       }
     },
+    "node_modules/@cloudflare/workerd-linux-64": {
+      "version": "1.20240304.0",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20240304.0.tgz",
+      "integrity": "sha512-G1BEzbw9TFIeMvc425F145IetC7fuH4KOkGhseLq9y/mt5PfDWkghwmXSK+q0BiMwm0XAobtzVlHcEr2u4WlRQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=16"
+      }
+    },
+    "node_modules/@cloudflare/workerd-linux-arm64": {
+      "version": "1.20240304.0",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20240304.0.tgz",
+      "integrity": "sha512-LLk/d/y77TRu6QOG3CJUI2cD3Ff2lSg0ts6G83bsm9ZK+WKObWFFSPBy9l81m3EnlKFh7RZCzxN4J10kuDaO8w==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=16"
+      }
+    },
+    "node_modules/@cloudflare/workerd-windows-64": {
+      "version": "1.20240304.0",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20240304.0.tgz",
+      "integrity": "sha512-I/j6nVpM+WDPg+bYUAiKLkwQsjrXFjpOGHvwYmcM44hnDjgODzk7AbVssEIXnhEO3oupBeuKvffr0lvX0Ngmpw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=16"
+      }
+    },
     "node_modules/@cloudflare/workers-types": {
-      "version": "4.20240208.0",
-      "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240208.0.tgz",
-      "integrity": "sha512-MVGTTjZpJu4kJONvai5SdJzWIhOJbuweVZ3goI7FNyG+JdoQH41OoB+nMhLsX626vPLZVWGPIWsiSo/WZHzgQw==",
+      "version": "4.20240314.0",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240314.0.tgz",
+      "integrity": "sha512-eg2dK/tYSiFvQu3sexjB32WEGi3GEmY6pLRF4nrV9Rwi2F2965o6f6604jQY8whhrmNdEoWErSjhuuUld6xgKQ==",
       "dev": true
     },
     "node_modules/@cspotcode/source-map-support": {
@@ -794,6 +861,54 @@
         "esbuild": "*"
       }
     },
+    "node_modules/@esbuild/android-arm": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz",
+      "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-arm64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz",
+      "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/android-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz",
+      "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
     "node_modules/@esbuild/darwin-arm64": {
       "version": "0.17.19",
       "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz",
@@ -810,6 +925,294 @@
         "node": ">=12"
       }
     },
+    "node_modules/@esbuild/darwin-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz",
+      "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz",
+      "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/freebsd-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz",
+      "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-arm": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz",
+      "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-arm64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz",
+      "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-ia32": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz",
+      "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-loong64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz",
+      "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==",
+      "cpu": [
+        "loong64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-mips64el": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz",
+      "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==",
+      "cpu": [
+        "mips64el"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-ppc64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz",
+      "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-riscv64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz",
+      "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-s390x": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz",
+      "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/linux-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz",
+      "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/netbsd-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz",
+      "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/openbsd-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz",
+      "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/sunos-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz",
+      "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-arm64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz",
+      "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-ia32": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz",
+      "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@esbuild/win32-x64": {
+      "version": "0.17.19",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz",
+      "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
     "node_modules/@eslint-community/eslint-utils": {
       "version": "4.4.0",
       "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@@ -875,17 +1278,17 @@
       }
     },
     "node_modules/@eslint/js": {
-      "version": "8.56.0",
-      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
-      "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==",
+      "version": "8.57.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
+      "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
       }
     },
     "node_modules/@fastify/busboy": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz",
-      "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==",
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
+      "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
       "dev": true,
       "engines": {
         "node": ">=14"
@@ -1498,14 +1901,14 @@
       }
     },
     "node_modules/@jridgewell/gen-mapping": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
-      "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+      "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/set-array": "^1.0.1",
+        "@jridgewell/set-array": "^1.2.1",
         "@jridgewell/sourcemap-codec": "^1.4.10",
-        "@jridgewell/trace-mapping": "^0.3.9"
+        "@jridgewell/trace-mapping": "^0.3.24"
       },
       "engines": {
         "node": ">=6.0.0"
@@ -1520,22 +1923,22 @@
       }
     },
     "node_modules/@jridgewell/set-array": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
-      "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+      "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
       "dev": true,
       "engines": {
         "node": ">=6.0.0"
       }
     },
     "node_modules/@jridgewell/source-map": {
-      "version": "0.3.5",
-      "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
-      "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
+      "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/gen-mapping": "^0.3.0",
-        "@jridgewell/trace-mapping": "^0.3.9"
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.25"
       }
     },
     "node_modules/@jridgewell/sourcemap-codec": {
@@ -1544,9 +1947,9 @@
       "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
     },
     "node_modules/@jridgewell/trace-mapping": {
-      "version": "0.3.22",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz",
-      "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==",
+      "version": "0.3.25",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+      "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
       "dev": true,
       "dependencies": {
         "@jridgewell/resolve-uri": "^3.1.0",
@@ -1554,11 +1957,11 @@
       }
     },
     "node_modules/@ljharb/through": {
-      "version": "2.3.12",
-      "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.12.tgz",
-      "integrity": "sha512-ajo/heTlG3QgC8EGP6APIejksVAYt4ayz4tqoP3MolFELzcH1x1fzwEYRJTPO0IELutZ5HQ0c26/GqAYy79u3g==",
+      "version": "2.3.13",
+      "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.13.tgz",
+      "integrity": "sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==",
       "dependencies": {
-        "call-bind": "^1.0.5"
+        "call-bind": "^1.0.7"
       },
       "engines": {
         "node": ">= 0.4"
@@ -1834,9 +2237,9 @@
       }
     },
     "node_modules/@supabase/supabase-js": {
-      "version": "2.39.6",
-      "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.39.6.tgz",
-      "integrity": "sha512-HlflDzem0+l3KYYTqHV0UsqkDooV9my5UcBCV2zvvTrl77UtW97uKTZWn9lSWMuiy+ZvRLsiuG+WTiBuKMQl0Q==",
+      "version": "2.39.8",
+      "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.39.8.tgz",
+      "integrity": "sha512-WpiawHjseIRcCQTZbMJtHUSOepz5+M9qE1jP9BDmg8X7ehALFwgEkiKyHAu59qm/pKP2ryyQXLtu2XZNRbUarw==",
       "dependencies": {
         "@supabase/functions-js": "2.1.5",
         "@supabase/gotrue-js": "2.62.2",
@@ -1867,9 +2270,9 @@
       "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA=="
     },
     "node_modules/@tsndr/cloudflare-worker-jwt": {
-      "version": "2.4.5",
-      "resolved": "https://registry.npmjs.org/@tsndr/cloudflare-worker-jwt/-/cloudflare-worker-jwt-2.4.5.tgz",
-      "integrity": "sha512-XLujJR463BLHNMfGJY0jsmw7ZPbicuk5UNJofldZEWbMsWXYWOoX0bpq3vZ87uSSi5By3CH0+7KyJ/26XSlVGQ=="
+      "version": "2.5.3",
+      "resolved": "https://registry.npmjs.org/@tsndr/cloudflare-worker-jwt/-/cloudflare-worker-jwt-2.5.3.tgz",
+      "integrity": "sha512-zbdvjRG86y/ObiBgTJrzBC39t2FcaeGwB6AV7VO4LvHKJNyZvLYRbKT68eaoJhnJldyHhs7yZ69neRVdUd9knA=="
     },
     "node_modules/@types/babel__core": {
       "version": "7.20.5",
@@ -1912,6 +2315,15 @@
         "@babel/types": "^7.20.7"
       }
     },
+    "node_modules/@types/better-sqlite3": {
+      "version": "7.6.9",
+      "resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.9.tgz",
+      "integrity": "sha512-FvktcujPDj9XKMJQWFcl2vVl7OdRIqsSRX9b0acWwTmwLK9CF2eqo/FRcmMLNpugKoX/avA6pb7TorDLmpgTnQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/estree": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
@@ -1994,9 +2406,9 @@
       "dev": true
     },
     "node_modules/@types/semver": {
-      "version": "7.5.7",
-      "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz",
-      "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg=="
+      "version": "7.5.8",
+      "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
+      "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ=="
     },
     "node_modules/@types/stack-utils": {
       "version": "2.0.3",
@@ -2028,15 +2440,15 @@
       "dev": true
     },
     "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.0.1.tgz",
-      "integrity": "sha512-OLvgeBv3vXlnnJGIAgCLYKjgMEU+wBGj07MQ/nxAaON+3mLzX7mJbhRYrVGiVvFiXtwFlkcBa/TtmglHy0UbzQ==",
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.2.0.tgz",
+      "integrity": "sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==",
       "dependencies": {
         "@eslint-community/regexpp": "^4.5.1",
-        "@typescript-eslint/scope-manager": "7.0.1",
-        "@typescript-eslint/type-utils": "7.0.1",
-        "@typescript-eslint/utils": "7.0.1",
-        "@typescript-eslint/visitor-keys": "7.0.1",
+        "@typescript-eslint/scope-manager": "7.2.0",
+        "@typescript-eslint/type-utils": "7.2.0",
+        "@typescript-eslint/utils": "7.2.0",
+        "@typescript-eslint/visitor-keys": "7.2.0",
         "debug": "^4.3.4",
         "graphemer": "^1.4.0",
         "ignore": "^5.2.4",
@@ -2062,14 +2474,14 @@
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.0.1.tgz",
-      "integrity": "sha512-8GcRRZNzaHxKzBPU3tKtFNing571/GwPBeCvmAUw0yBtfE2XVd0zFKJIMSWkHJcPQi0ekxjIts6L/rrZq5cxGQ==",
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz",
+      "integrity": "sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==",
       "dependencies": {
-        "@typescript-eslint/scope-manager": "7.0.1",
-        "@typescript-eslint/types": "7.0.1",
-        "@typescript-eslint/typescript-estree": "7.0.1",
-        "@typescript-eslint/visitor-keys": "7.0.1",
+        "@typescript-eslint/scope-manager": "7.2.0",
+        "@typescript-eslint/types": "7.2.0",
+        "@typescript-eslint/typescript-estree": "7.2.0",
+        "@typescript-eslint/visitor-keys": "7.2.0",
         "debug": "^4.3.4"
       },
       "engines": {
@@ -2089,12 +2501,12 @@
       }
     },
     "node_modules/@typescript-eslint/scope-manager": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.0.1.tgz",
-      "integrity": "sha512-v7/T7As10g3bcWOOPAcbnMDuvctHzCFYCG/8R4bK4iYzdFqsZTbXGln0cZNVcwQcwewsYU2BJLay8j0/4zOk4w==",
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz",
+      "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==",
       "dependencies": {
-        "@typescript-eslint/types": "7.0.1",
-        "@typescript-eslint/visitor-keys": "7.0.1"
+        "@typescript-eslint/types": "7.2.0",
+        "@typescript-eslint/visitor-keys": "7.2.0"
       },
       "engines": {
         "node": "^16.0.0 || >=18.0.0"
@@ -2105,12 +2517,12 @@
       }
     },
     "node_modules/@typescript-eslint/type-utils": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.0.1.tgz",
-      "integrity": "sha512-YtT9UcstTG5Yqy4xtLiClm1ZpM/pWVGFnkAa90UfdkkZsR1eP2mR/1jbHeYp8Ay1l1JHPyGvoUYR6o3On5Nhmw==",
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.2.0.tgz",
+      "integrity": "sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA==",
       "dependencies": {
-        "@typescript-eslint/typescript-estree": "7.0.1",
-        "@typescript-eslint/utils": "7.0.1",
+        "@typescript-eslint/typescript-estree": "7.2.0",
+        "@typescript-eslint/utils": "7.2.0",
         "debug": "^4.3.4",
         "ts-api-utils": "^1.0.1"
       },
@@ -2131,9 +2543,9 @@
       }
     },
     "node_modules/@typescript-eslint/types": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.0.1.tgz",
-      "integrity": "sha512-uJDfmirz4FHib6ENju/7cz9SdMSkeVvJDK3VcMFvf/hAShg8C74FW+06MaQPODHfDJp/z/zHfgawIJRjlu0RLg==",
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz",
+      "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==",
       "engines": {
         "node": "^16.0.0 || >=18.0.0"
       },
@@ -2143,12 +2555,12 @@
       }
     },
     "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.0.1.tgz",
-      "integrity": "sha512-SO9wHb6ph0/FN5OJxH4MiPscGah5wjOd0RRpaLvuBv9g8565Fgu0uMySFEPqwPHiQU90yzJ2FjRYKGrAhS1xig==",
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz",
+      "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==",
       "dependencies": {
-        "@typescript-eslint/types": "7.0.1",
-        "@typescript-eslint/visitor-keys": "7.0.1",
+        "@typescript-eslint/types": "7.2.0",
+        "@typescript-eslint/visitor-keys": "7.2.0",
         "debug": "^4.3.4",
         "globby": "^11.1.0",
         "is-glob": "^4.0.3",
@@ -2170,16 +2582,16 @@
       }
     },
     "node_modules/@typescript-eslint/utils": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.0.1.tgz",
-      "integrity": "sha512-oe4his30JgPbnv+9Vef1h48jm0S6ft4mNwi9wj7bX10joGn07QRfqIqFHoMiajrtoU88cIhXf8ahwgrcbNLgPA==",
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz",
+      "integrity": "sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==",
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.4.0",
         "@types/json-schema": "^7.0.12",
         "@types/semver": "^7.5.0",
-        "@typescript-eslint/scope-manager": "7.0.1",
-        "@typescript-eslint/types": "7.0.1",
-        "@typescript-eslint/typescript-estree": "7.0.1",
+        "@typescript-eslint/scope-manager": "7.2.0",
+        "@typescript-eslint/types": "7.2.0",
+        "@typescript-eslint/typescript-estree": "7.2.0",
         "semver": "^7.5.4"
       },
       "engines": {
@@ -2194,11 +2606,11 @@
       }
     },
     "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.0.1.tgz",
-      "integrity": "sha512-hwAgrOyk++RTXrP4KzCg7zB2U0xt7RUU0ZdMSCsqF3eKUwkdXUMyTb0qdCuji7VIbcpG62kKTU9M1J1c9UpFBw==",
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz",
+      "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==",
       "dependencies": {
-        "@typescript-eslint/types": "7.0.1",
+        "@typescript-eslint/types": "7.2.0",
         "eslint-visitor-keys": "^3.4.1"
       },
       "engines": {
@@ -2402,10 +2814,13 @@
       }
     },
     "node_modules/available-typed-arrays": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz",
-      "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==",
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+      "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
       "dev": true,
+      "dependencies": {
+        "possible-typed-array-names": "^1.0.0"
+      },
       "engines": {
         "node": ">= 0.4"
       },
@@ -2553,6 +2968,16 @@
         }
       ]
     },
+    "node_modules/better-sqlite3": {
+      "version": "9.4.3",
+      "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-9.4.3.tgz",
+      "integrity": "sha512-ud0bTmD9O3uWJGuXDltyj3R47Nz0OHX8iqPOT5PMspGqlu/qQFn+5S2eFBUCrySpavTjFXbi4EgrfVvPAHlImw==",
+      "hasInstallScript": true,
+      "dependencies": {
+        "bindings": "^1.5.0",
+        "prebuild-install": "^7.1.1"
+      }
+    },
     "node_modules/bin-links": {
       "version": "4.0.3",
       "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.3.tgz",
@@ -2594,12 +3019,23 @@
       }
     },
     "node_modules/binary-extensions": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
-      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+      "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
       "dev": true,
       "engines": {
         "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/bindings": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+      "dependencies": {
+        "file-uri-to-path": "1.0.0"
       }
     },
     "node_modules/bl": {
@@ -2767,9 +3203,9 @@
       }
     },
     "node_modules/caniuse-lite": {
-      "version": "1.0.30001587",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz",
-      "integrity": "sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==",
+      "version": "1.0.30001597",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001597.tgz",
+      "integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==",
       "dev": true,
       "funding": [
         {
@@ -3148,10 +3584,13 @@
       }
     },
     "node_modules/data-uri-to-buffer": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-2.0.2.tgz",
-      "integrity": "sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==",
-      "dev": true
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
+      "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
+      "dev": true,
+      "engines": {
+        "node": ">= 12"
+      }
     },
     "node_modules/debug": {
       "version": "4.3.4",
@@ -3163,10 +3602,24 @@
       "engines": {
         "node": ">=6.0"
       },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/decompress-response": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+      "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+      "dependencies": {
+        "mimic-response": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/dedent": {
@@ -3183,6 +3636,14 @@
         }
       }
     },
+    "node_modules/deep-extend": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
     "node_modules/deep-is": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -3241,6 +3702,14 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/detect-libc": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
+      "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/detect-newline": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
@@ -3290,9 +3759,9 @@
       }
     },
     "node_modules/dotenv": {
-      "version": "16.4.4",
-      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.4.tgz",
-      "integrity": "sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==",
+      "version": "16.4.5",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
+      "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
       "engines": {
         "node": ">=12"
       },
@@ -3307,9 +3776,9 @@
       "dev": true
     },
     "node_modules/electron-to-chromium": {
-      "version": "1.4.670",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.670.tgz",
-      "integrity": "sha512-hcijYOWjOtjKrKPtNA6tuLlA/bTLO3heFG8pQA6mLpq7dRydSWicXova5lyxDzp1iVJaYhK7J2OQlGE52KYn7A==",
+      "version": "1.4.706",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.706.tgz",
+      "integrity": "sha512-fO01fufoGd6jKK3HR8ofBapF3ZPfgxNJ/ua9xQAhFu93TwWIs4d+weDn3kje3GB4S7aGUTfk5nvdU5F7z5mF9Q==",
       "dev": true
     },
     "node_modules/emittery": {
@@ -3329,6 +3798,14 @@
       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
       "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
     },
+    "node_modules/end-of-stream": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+      "dependencies": {
+        "once": "^1.4.0"
+      }
+    },
     "node_modules/error-ex": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -3339,18 +3816,18 @@
       }
     },
     "node_modules/es-abstract": {
-      "version": "1.22.4",
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.4.tgz",
-      "integrity": "sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==",
+      "version": "1.22.5",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz",
+      "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==",
       "dev": true,
       "dependencies": {
         "array-buffer-byte-length": "^1.0.1",
         "arraybuffer.prototype.slice": "^1.0.3",
-        "available-typed-arrays": "^1.0.6",
+        "available-typed-arrays": "^1.0.7",
         "call-bind": "^1.0.7",
         "es-define-property": "^1.0.0",
         "es-errors": "^1.3.0",
-        "es-set-tostringtag": "^2.0.2",
+        "es-set-tostringtag": "^2.0.3",
         "es-to-primitive": "^1.2.1",
         "function.prototype.name": "^1.1.6",
         "get-intrinsic": "^1.2.4",
@@ -3358,15 +3835,15 @@
         "globalthis": "^1.0.3",
         "gopd": "^1.0.1",
         "has-property-descriptors": "^1.0.2",
-        "has-proto": "^1.0.1",
+        "has-proto": "^1.0.3",
         "has-symbols": "^1.0.3",
         "hasown": "^2.0.1",
         "internal-slot": "^1.0.7",
         "is-array-buffer": "^3.0.4",
         "is-callable": "^1.2.7",
-        "is-negative-zero": "^2.0.2",
+        "is-negative-zero": "^2.0.3",
         "is-regex": "^1.1.4",
-        "is-shared-array-buffer": "^1.0.2",
+        "is-shared-array-buffer": "^1.0.3",
         "is-string": "^1.0.7",
         "is-typed-array": "^1.1.13",
         "is-weakref": "^1.0.2",
@@ -3379,10 +3856,10 @@
         "string.prototype.trim": "^1.2.8",
         "string.prototype.trimend": "^1.0.7",
         "string.prototype.trimstart": "^1.0.7",
-        "typed-array-buffer": "^1.0.1",
-        "typed-array-byte-length": "^1.0.0",
-        "typed-array-byte-offset": "^1.0.0",
-        "typed-array-length": "^1.0.4",
+        "typed-array-buffer": "^1.0.2",
+        "typed-array-byte-length": "^1.0.1",
+        "typed-array-byte-offset": "^1.0.2",
+        "typed-array-length": "^1.0.5",
         "unbox-primitive": "^1.0.2",
         "which-typed-array": "^1.1.14"
       },
@@ -3413,14 +3890,14 @@
       }
     },
     "node_modules/es-set-tostringtag": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz",
-      "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==",
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
+      "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
       "dev": true,
       "dependencies": {
-        "get-intrinsic": "^1.2.2",
-        "has-tostringtag": "^1.0.0",
-        "hasown": "^2.0.0"
+        "get-intrinsic": "^1.2.4",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.1"
       },
       "engines": {
         "node": ">= 0.4"
@@ -3501,15 +3978,15 @@
       }
     },
     "node_modules/eslint": {
-      "version": "8.56.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
-      "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
+      "version": "8.57.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
+      "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.2.0",
         "@eslint-community/regexpp": "^4.6.1",
         "@eslint/eslintrc": "^2.1.4",
-        "@eslint/js": "8.56.0",
-        "@humanwhocodes/config-array": "^0.11.13",
+        "@eslint/js": "8.57.0",
+        "@humanwhocodes/config-array": "^0.11.14",
         "@humanwhocodes/module-importer": "^1.0.1",
         "@nodelib/fs.walk": "^1.2.8",
         "@ungap/structured-clone": "^1.2.0",
@@ -3764,6 +4241,14 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/expand-template": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+      "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/expect": {
       "version": "29.7.0",
       "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz",
@@ -3995,6 +4480,11 @@
         "node": "^10.12.0 || >=12.0.0"
       }
     },
+    "node_modules/file-uri-to-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
+    },
     "node_modules/fill-range": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@@ -4088,9 +4578,9 @@
       }
     },
     "node_modules/flatted": {
-      "version": "3.2.9",
-      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz",
-      "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ=="
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
+      "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw=="
     },
     "node_modules/for-each": {
       "version": "0.3.3",
@@ -4141,6 +4631,11 @@
         "node": ">=12.20.0"
       }
     },
+    "node_modules/fs-constants": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+      "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
+    },
     "node_modules/fs-minipass": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
@@ -4180,6 +4675,7 @@
       "version": "2.3.3",
       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
       "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+      "dev": true,
       "hasInstallScript": true,
       "optional": true,
       "os": [
@@ -4291,6 +4787,12 @@
         "source-map": "^0.6.1"
       }
     },
+    "node_modules/get-source/node_modules/data-uri-to-buffer": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-2.0.2.tgz",
+      "integrity": "sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==",
+      "dev": true
+    },
     "node_modules/get-stream": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
@@ -4320,6 +4822,11 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/github-from-package": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+      "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="
+    },
     "node_modules/glob": {
       "version": "8.1.0",
       "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
@@ -4467,9 +4974,9 @@
       }
     },
     "node_modules/has-proto": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
-      "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
+      "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
       "engines": {
         "node": ">= 0.4"
       },
@@ -4504,9 +5011,9 @@
       }
     },
     "node_modules/hasown": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz",
-      "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
       "dependencies": {
         "function-bind": "^1.1.2"
       },
@@ -4642,12 +5149,17 @@
       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
       "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
     },
+    "node_modules/ini": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+      "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+    },
     "node_modules/inquirer": {
-      "version": "9.2.14",
-      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.14.tgz",
-      "integrity": "sha512-4ByIMt677Iz5AvjyKrDpzaepIyMewNvDcvwpVVRZNmy9dLakVoVgdCHZXbK1SlVJra1db0JZ6XkJyHsanpdrdQ==",
+      "version": "9.2.16",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.16.tgz",
+      "integrity": "sha512-qzgbB+yNjgSzk2omeqMDtO9IgJet/UL67luT1MaaggRpGK73DBQct5Q4pipwFQcIKK1GbMODYd4UfsRCkSP1DA==",
       "dependencies": {
-        "@ljharb/through": "^2.3.12",
+        "@ljharb/through": "^2.3.13",
         "ansi-escapes": "^4.3.2",
         "chalk": "^5.3.0",
         "cli-cursor": "^3.1.0",
@@ -4863,9 +5375,9 @@
       "dev": true
     },
     "node_modules/is-negative-zero": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
-      "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+      "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
       "dev": true,
       "engines": {
         "node": ">= 0.4"
@@ -4931,12 +5443,15 @@
       }
     },
     "node_modules/is-shared-array-buffer": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
-      "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
+      "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.2"
+        "call-bind": "^1.0.7"
+      },
+      "engines": {
+        "node": ">= 0.4"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -5043,14 +5558,14 @@
       }
     },
     "node_modules/istanbul-lib-instrument": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz",
-      "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==",
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz",
+      "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==",
       "dev": true,
       "dependencies": {
-        "@babel/core": "^7.12.3",
-        "@babel/parser": "^7.14.7",
-        "@istanbuljs/schema": "^0.1.2",
+        "@babel/core": "^7.23.9",
+        "@babel/parser": "^7.23.9",
+        "@istanbuljs/schema": "^0.1.3",
         "istanbul-lib-coverage": "^3.2.0",
         "semver": "^7.5.4"
       },
@@ -5087,9 +5602,9 @@
       }
     },
     "node_modules/istanbul-reports": {
-      "version": "3.1.6",
-      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz",
-      "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==",
+      "version": "3.1.7",
+      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
+      "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
       "dev": true,
       "dependencies": {
         "html-escaper": "^2.0.0",
@@ -6311,9 +6826,9 @@
       }
     },
     "node_modules/lint-staged/node_modules/npm-run-path": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz",
-      "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==",
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
+      "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
       "dev": true,
       "dependencies": {
         "path-key": "^4.0.0"
@@ -6751,9 +7266,9 @@
       }
     },
     "node_modules/magic-string": {
-      "version": "0.30.7",
-      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz",
-      "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==",
+      "version": "0.30.8",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
+      "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
       "dev": true,
       "dependencies": {
         "@jridgewell/sourcemap-codec": "^1.4.15"
@@ -6846,10 +7361,21 @@
         "node": ">=6"
       }
     },
+    "node_modules/mimic-response": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+      "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/miniflare": {
-      "version": "3.20240129.2",
-      "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240129.2.tgz",
-      "integrity": "sha512-BPUg8HsPmWQlRFUeiQk274i8M9L0gOvzbkjryuTvCX+M53EwBpP0gM2wyrRr/HokQoJcxWGh3InBu6L8+0bbPw==",
+      "version": "3.20240304.2",
+      "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240304.2.tgz",
+      "integrity": "sha512-yQ5TBKv7TlvF8khFvvH+1WWk8cBnaLgNzcbJ5DLQOdecxdDxUCVlN38HThd6Nhcz6EY+ckDkww8FkugUbSSpIQ==",
       "dev": true,
       "dependencies": {
         "@cspotcode/source-map-support": "0.8.1",
@@ -6860,7 +7386,7 @@
         "glob-to-regexp": "^0.4.1",
         "stoppable": "^1.1.0",
         "undici": "^5.28.2",
-        "workerd": "1.20240129.0",
+        "workerd": "1.20240304.0",
         "ws": "^8.11.0",
         "youch": "^3.2.2",
         "zod": "^3.20.6"
@@ -6886,13 +7412,21 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
+    "node_modules/minimist": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/minipass": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
-      "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+      "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
       "dev": true,
       "engines": {
-        "node": ">=16 || 14 >=14.17"
+        "node": ">=8"
       }
     },
     "node_modules/minizlib": {
@@ -6938,6 +7472,11 @@
         "node": ">=10"
       }
     },
+    "node_modules/mkdirp-classic": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+      "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
+    },
     "node_modules/ms": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -6978,6 +7517,11 @@
         "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
       }
     },
+    "node_modules/napi-build-utils": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
+      "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
+    },
     "node_modules/natural-compare": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@@ -6989,6 +7533,17 @@
       "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
       "dev": true
     },
+    "node_modules/node-abi": {
+      "version": "3.56.0",
+      "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.56.0.tgz",
+      "integrity": "sha512-fZjdhDOeRcaS+rcpve7XuwHBmktS1nS1gzgghwKUQQ8nTy2FdSDr6ZT8k6YhvlJeHmmQMYiT/IH9hfco5zeW2Q==",
+      "dependencies": {
+        "semver": "^7.3.5"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/node-domexception": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
@@ -7026,15 +7581,6 @@
         "url": "https://opencollective.com/node-fetch"
       }
     },
-    "node_modules/node-fetch/node_modules/data-uri-to-buffer": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
-      "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
-      "dev": true,
-      "engines": {
-        "node": ">= 12"
-      }
-    },
     "node_modules/node-forge": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
@@ -7654,6 +8200,40 @@
         "node": ">=8"
       }
     },
+    "node_modules/possible-typed-array-names": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
+      "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/prebuild-install": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz",
+      "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==",
+      "dependencies": {
+        "detect-libc": "^2.0.0",
+        "expand-template": "^2.0.3",
+        "github-from-package": "0.0.0",
+        "minimist": "^1.2.3",
+        "mkdirp-classic": "^0.5.3",
+        "napi-build-utils": "^1.0.1",
+        "node-abi": "^3.3.0",
+        "pump": "^3.0.0",
+        "rc": "^1.2.7",
+        "simple-get": "^4.0.0",
+        "tar-fs": "^2.0.0",
+        "tunnel-agent": "^0.6.0"
+      },
+      "bin": {
+        "prebuild-install": "bin.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/prelude-ls": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -7734,6 +8314,15 @@
         "node": ">= 6"
       }
     },
+    "node_modules/pump": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+      "dependencies": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
     "node_modules/punycode": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -7786,6 +8375,28 @@
         "safe-buffer": "^5.1.0"
       }
     },
+    "node_modules/rc": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+      "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+      "dependencies": {
+        "deep-extend": "^0.6.0",
+        "ini": "~1.3.0",
+        "minimist": "^1.2.0",
+        "strip-json-comments": "~2.0.1"
+      },
+      "bin": {
+        "rc": "cli.js"
+      }
+    },
+    "node_modules/rc/node_modules/strip-json-comments": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+      "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/react-is": {
       "version": "17.0.2",
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
@@ -8136,13 +8747,13 @@
       }
     },
     "node_modules/safe-array-concat": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz",
-      "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==",
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz",
+      "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.5",
-        "get-intrinsic": "^1.2.2",
+        "call-bind": "^1.0.7",
+        "get-intrinsic": "^1.2.4",
         "has-symbols": "^1.0.3",
         "isarray": "^2.0.5"
       },
@@ -8247,30 +8858,31 @@
       }
     },
     "node_modules/set-function-length": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz",
-      "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==",
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+      "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
       "dependencies": {
-        "define-data-property": "^1.1.2",
+        "define-data-property": "^1.1.4",
         "es-errors": "^1.3.0",
         "function-bind": "^1.1.2",
-        "get-intrinsic": "^1.2.3",
+        "get-intrinsic": "^1.2.4",
         "gopd": "^1.0.1",
-        "has-property-descriptors": "^1.0.1"
+        "has-property-descriptors": "^1.0.2"
       },
       "engines": {
         "node": ">= 0.4"
       }
     },
     "node_modules/set-function-name": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz",
-      "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+      "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
       "dev": true,
       "dependencies": {
-        "define-data-property": "^1.0.1",
+        "define-data-property": "^1.1.4",
+        "es-errors": "^1.3.0",
         "functions-have-names": "^1.2.3",
-        "has-property-descriptors": "^1.0.0"
+        "has-property-descriptors": "^1.0.2"
       },
       "engines": {
         "node": ">= 0.4"
@@ -8305,12 +8917,12 @@
       }
     },
     "node_modules/side-channel": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz",
-      "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==",
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
+      "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.6",
+        "call-bind": "^1.0.7",
         "es-errors": "^1.3.0",
         "get-intrinsic": "^1.2.4",
         "object-inspect": "^1.13.1"
@@ -8327,6 +8939,49 @@
       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
       "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
     },
+    "node_modules/simple-concat": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+      "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/simple-get": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
+      "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "dependencies": {
+        "decompress-response": "^6.0.0",
+        "once": "^1.3.1",
+        "simple-concat": "^1.0.0"
+      }
+    },
     "node_modules/sisteransi": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
@@ -8433,6 +9088,52 @@
       "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
       "dev": true
     },
+    "node_modules/sqlite-vss": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/sqlite-vss/-/sqlite-vss-0.1.2.tgz",
+      "integrity": "sha512-MgTz3GLT04ckv1kaesbrsUU6/kcVsA6vGeCS/HO5d/8zKqCuZFCD0QlJaQnS6zwaMyPG++BO/uu40MMrMa0cow==",
+      "optionalDependencies": {
+        "sqlite-vss-darwin-arm64": "0.1.2",
+        "sqlite-vss-darwin-x64": "0.1.2",
+        "sqlite-vss-linux-x64": "0.1.2"
+      }
+    },
+    "node_modules/sqlite-vss-darwin-arm64": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/sqlite-vss-darwin-arm64/-/sqlite-vss-darwin-arm64-0.1.2.tgz",
+      "integrity": "sha512-zyDk9eg33nBABrUC4cqQ7el8KJaRPzsqp8Y/nGZ0CAt7o1PMqLoCOgREorill5MGiZEBmLqxdAgw0O2MFwq4mw==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/sqlite-vss-darwin-x64": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/sqlite-vss-darwin-x64/-/sqlite-vss-darwin-x64-0.1.2.tgz",
+      "integrity": "sha512-w+ODOH2dNkyO6UaGclwC0jwNf/FBsKaE53XKJ7dFmpOvlvO0/9sA1stkWXygykRVWwa3UD8ow0qbQpRwdOFyqg==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/sqlite-vss-linux-x64": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/sqlite-vss-linux-x64/-/sqlite-vss-linux-x64-0.1.2.tgz",
+      "integrity": "sha512-y1qktcHAZcfN1nYMcF5os/cCRRyaisaNc2C9I3ceLKLPAqUWIocsOdD5nNK/dIeGPag/QeT2ZItJ6uYWciLiAg==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
     "node_modules/stack-utils": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
@@ -8665,9 +9366,9 @@
       }
     },
     "node_modules/supabase": {
-      "version": "1.145.4",
-      "resolved": "https://registry.npmjs.org/supabase/-/supabase-1.145.4.tgz",
-      "integrity": "sha512-j6OvAQjTNcJ8SBlqZpUTFJ7C3iXliZ8VjcleFvUBAlFLqot1EhXT8tqSLZiOP1B91Ks2DPOxT8D94cAIWYWvLQ==",
+      "version": "1.148.6",
+      "resolved": "https://registry.npmjs.org/supabase/-/supabase-1.148.6.tgz",
+      "integrity": "sha512-/VXbN0C/r/o1TkHGw4EXYvwtwfsSvRaBd6lWa5HamcC6HdFpbof8VsSglWjiie5ONTg3lwqv06wcOrtdpzz/Bg==",
       "dev": true,
       "hasInstallScript": true,
       "dependencies": {
@@ -8739,13 +9440,35 @@
         "node": ">=10"
       }
     },
-    "node_modules/tar/node_modules/minipass": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
-      "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
-      "dev": true,
+    "node_modules/tar-fs": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
+      "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+      "dependencies": {
+        "chownr": "^1.1.1",
+        "mkdirp-classic": "^0.5.2",
+        "pump": "^3.0.0",
+        "tar-stream": "^2.1.4"
+      }
+    },
+    "node_modules/tar-fs/node_modules/chownr": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
+    },
+    "node_modules/tar-stream": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+      "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+      "dependencies": {
+        "bl": "^4.0.3",
+        "end-of-stream": "^1.4.1",
+        "fs-constants": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^3.1.1"
+      },
       "engines": {
-        "node": ">=8"
+        "node": ">=6"
       }
     },
     "node_modules/tar/node_modules/yallist": {
@@ -8755,9 +9478,9 @@
       "dev": true
     },
     "node_modules/terser": {
-      "version": "5.27.0",
-      "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz",
-      "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==",
+      "version": "5.29.2",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.2.tgz",
+      "integrity": "sha512-ZiGkhUBIM+7LwkNjXYJq8svgkd+QK3UUr0wJqY4MieaezBSAIPgbSPZyIx0idM6XWK5CMzSWa8MJIzmRcB8Caw==",
       "dev": true,
       "dependencies": {
         "@jridgewell/source-map": "^0.3.3",
@@ -8892,9 +9615,9 @@
       "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
     },
     "node_modules/ts-api-utils": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz",
-      "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==",
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
+      "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
       "engines": {
         "node": ">=16"
       },
@@ -8992,6 +9715,17 @@
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
       "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
     },
+    "node_modules/tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/type-check": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -9024,12 +9758,12 @@
       }
     },
     "node_modules/typed-array-buffer": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.1.tgz",
-      "integrity": "sha512-RSqu1UEuSlrBhHTWC8O9FnPjOduNs4M7rJ4pRKoEjtx1zUNOPN2sSXHLDX+Y2WPbHIxbvg4JFo2DNAEfPIKWoQ==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
+      "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.6",
+        "call-bind": "^1.0.7",
         "es-errors": "^1.3.0",
         "is-typed-array": "^1.1.13"
       },
@@ -9038,15 +9772,16 @@
       }
     },
     "node_modules/typed-array-byte-length": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz",
-      "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==",
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz",
+      "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.2",
+        "call-bind": "^1.0.7",
         "for-each": "^0.3.3",
-        "has-proto": "^1.0.1",
-        "is-typed-array": "^1.1.10"
+        "gopd": "^1.0.1",
+        "has-proto": "^1.0.3",
+        "is-typed-array": "^1.1.13"
       },
       "engines": {
         "node": ">= 0.4"
@@ -9056,16 +9791,17 @@
       }
     },
     "node_modules/typed-array-byte-offset": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz",
-      "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz",
+      "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==",
       "dev": true,
       "dependencies": {
-        "available-typed-arrays": "^1.0.5",
-        "call-bind": "^1.0.2",
+        "available-typed-arrays": "^1.0.7",
+        "call-bind": "^1.0.7",
         "for-each": "^0.3.3",
-        "has-proto": "^1.0.1",
-        "is-typed-array": "^1.1.10"
+        "gopd": "^1.0.1",
+        "has-proto": "^1.0.3",
+        "is-typed-array": "^1.1.13"
       },
       "engines": {
         "node": ">= 0.4"
@@ -9075,23 +9811,29 @@
       }
     },
     "node_modules/typed-array-length": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
-      "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz",
+      "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.2",
+        "call-bind": "^1.0.7",
         "for-each": "^0.3.3",
-        "is-typed-array": "^1.1.9"
+        "gopd": "^1.0.1",
+        "has-proto": "^1.0.3",
+        "is-typed-array": "^1.1.13",
+        "possible-typed-array-names": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/typescript": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
-      "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
+      "version": "5.4.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz",
+      "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==",
       "bin": {
         "tsc": "bin/tsc",
         "tsserver": "bin/tsserver"
@@ -9283,16 +10025,16 @@
       }
     },
     "node_modules/which-typed-array": {
-      "version": "1.1.14",
-      "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz",
-      "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==",
+      "version": "1.1.15",
+      "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
+      "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
       "dev": true,
       "dependencies": {
-        "available-typed-arrays": "^1.0.6",
-        "call-bind": "^1.0.5",
+        "available-typed-arrays": "^1.0.7",
+        "call-bind": "^1.0.7",
         "for-each": "^0.3.3",
         "gopd": "^1.0.1",
-        "has-tostringtag": "^1.0.1"
+        "has-tostringtag": "^1.0.2"
       },
       "engines": {
         "node": ">= 0.4"
@@ -9302,9 +10044,9 @@
       }
     },
     "node_modules/workerd": {
-      "version": "1.20240129.0",
-      "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240129.0.tgz",
-      "integrity": "sha512-t4pnsmjjk/u+GdVDgH2M1AFmJaBUABshYK/vT/HNrAXsHSwN6VR8Yqw0JQ845OokO34VLkuUtYQYyxHHKpdtsw==",
+      "version": "1.20240304.0",
+      "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240304.0.tgz",
+      "integrity": "sha512-/tYxdypPh9NKQje9r7bgBB73vAQfCQZbEPjNlxE/ml7jNKMHnRZv/D+By4xO0IPAifa37D0sJFokvYOahz1Lqw==",
       "dev": true,
       "hasInstallScript": true,
       "bin": {
@@ -9314,17 +10056,17 @@
         "node": ">=16"
       },
       "optionalDependencies": {
-        "@cloudflare/workerd-darwin-64": "1.20240129.0",
-        "@cloudflare/workerd-darwin-arm64": "1.20240129.0",
-        "@cloudflare/workerd-linux-64": "1.20240129.0",
-        "@cloudflare/workerd-linux-arm64": "1.20240129.0",
-        "@cloudflare/workerd-windows-64": "1.20240129.0"
+        "@cloudflare/workerd-darwin-64": "1.20240304.0",
+        "@cloudflare/workerd-darwin-arm64": "1.20240304.0",
+        "@cloudflare/workerd-linux-64": "1.20240304.0",
+        "@cloudflare/workerd-linux-arm64": "1.20240304.0",
+        "@cloudflare/workerd-windows-64": "1.20240304.0"
       }
     },
     "node_modules/wrangler": {
-      "version": "3.28.2",
-      "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.28.2.tgz",
-      "integrity": "sha512-hlD4f2avBZuR1+qo9Um6D1prdWrSRtGTo9h6o/AKce+bHQEJWoJgJKHeLmrpZlLtHg/gGR1Xa1xzrexhuIzeJw==",
+      "version": "3.34.2",
+      "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.34.2.tgz",
+      "integrity": "sha512-j580WXlOe0GtYdcREym7FLcaaZq9+RZEBuzOtKXx74KKUlEC8cglgf5WWa2C2OpEtJCcrAieEHsNXe7mhy9knA==",
       "dev": true,
       "dependencies": {
         "@cloudflare/kv-asset-handler": "0.3.1",
@@ -9333,7 +10075,7 @@
         "blake3-wasm": "^2.1.5",
         "chokidar": "^3.5.3",
         "esbuild": "0.17.19",
-        "miniflare": "3.20240129.2",
+        "miniflare": "3.20240304.2",
         "nanoid": "^3.3.3",
         "path-to-regexp": "^6.2.0",
         "resolve": "^1.22.8",
diff --git a/package.json b/package.json
index faedbbd..2120870 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +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",
@@ -37,6 +40,7 @@
     "@rollup/plugin-node-resolve": "^15.2.3",
     "@rollup/plugin-replace": "^5.0.5",
     "@rollup/plugin-typescript": "^11.1.6",
+    "@types/better-sqlite3": "^7.6.9",
     "@types/jest": "^27.5.2",
     "@types/node": "20.9.4",
     "@typescript-eslint/parser": "^7.0.1",
@@ -63,9 +67,11 @@
     "@tsndr/cloudflare-worker-jwt": "^2.2.1",
     "@typescript-eslint/eslint-plugin": "^7.0.1",
     "ansi-colors": "^4.1.3",
+    "better-sqlite3": "^9.4.3",
     "dotenv": "^16.4.4",
     "figlet": "^1.7.0",
     "inquirer": "^9.2.14",
+    "sqlite-vss": "^0.1.2",
     "ts-node": "^10.9.2",
     "unique-names-generator": "^4.7.1"
   }
diff --git a/scripts/concat.mjs b/scripts/concat.mjs
index f507df9..d43d702 100644
--- a/scripts/concat.mjs
+++ b/scripts/concat.mjs
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url'
 const instructions = 'The above code was taken from my codebase at https://github.com/jointhealliance/bgent.'
 
 // Patterns to ignore
-const ignorePatterns = ['evaluator', 'templates', 'test', 'data', 'types', 'relationships', 'lore', 'logger', 'goals', 'context', 'constants', 'adapters', 'database', 'template', 'database']
+const ignorePatterns = ["evaluator", "action", "utils", "template", "util", "test", "types", "constants", "agents", "relationships", "context", "provider", "logger"]
 
 // __dirname is not defined in ES module scope, so we need to create it
 const __filename = fileURLToPath(import.meta.url)
diff --git a/src/agents/simple/index.ts b/src/agents/simple/index.ts
index 5fc4416..33a50c4 100644
--- a/src/agents/simple/index.ts
+++ b/src/agents/simple/index.ts
@@ -22,18 +22,11 @@ async function handleMessage(
   state?: State,
 ) {
   const _saveRequestMessage = async (message: Message, state: State) => {
-    const { content: senderContent, senderId, userIds, room_id } = message;
-    const _senderContent = (
-      (senderContent as Content).content ?? senderContent
-    )?.trim();
-    if (_senderContent) {
+    const { content, userId, room_id } = message;
+    if (content) {
       await runtime.messageManager.createMemory({
-        user_ids: userIds!,
-        user_id: senderId!,
-        content: {
-          content: _senderContent,
-          action: (message.content as Content)?.action ?? "null",
-        },
+        user_id: userId!,
+        content,
         room_id,
         embedding: embeddingZeroVector,
       });
@@ -56,7 +49,7 @@ async function handleMessage(
   }
 
   let responseContent: Content | null = null;
-  const { senderId, room_id, userIds: user_ids, agentId } = message;
+  const { userId, room_id } = message;
 
   for (let triesLeft = 3; triesLeft > 0; triesLeft--) {
     const response = await runtime.completion({
@@ -66,10 +59,8 @@ async function handleMessage(
 
     runtime.databaseAdapter.log({
       body: { message, context, response },
-      user_id: senderId,
+      user_id: userId,
       room_id,
-      user_ids: user_ids!,
-      agent_id: agentId!,
       type: "simple_agent_main_completion",
     });
 
@@ -102,14 +93,13 @@ async function handleMessage(
     state: State,
     responseContent: Content,
   ) => {
-    const { agentId, userIds, room_id } = message;
+    const { room_id } = message;
 
     responseContent.content = responseContent.content?.trim();
 
     if (responseContent.content) {
       await runtime.messageManager.createMemory({
-        user_ids: userIds!,
-        user_id: agentId!,
+        user_id: runtime.agentId,
         content: responseContent,
         room_id,
         embedding: embeddingZeroVector,
@@ -131,13 +121,7 @@ const onMessage = async (
   runtime: BgentRuntime,
   state?: State,
 ) => {
-  const { content: senderContent, senderId, agentId } = message;
-
-  if (!message.userIds) {
-    message.userIds = [senderId!, agentId!];
-  }
-
-  if (!senderContent) {
+  if (!message.content) {
     logger.warn("Sender content null, skipping");
     return;
   }
@@ -197,19 +181,8 @@ const routes: Route[] = [
         token: env.OPENAI_API_KEY,
       });
 
-      if (!(message as Message).agentId) {
-        return new Response("agentId is required", { status: 400 });
-      }
-
-      if (!(message as Message).senderId) {
-        (message as Message).senderId = userId;
-      }
-
-      if (!(message as Message).userIds) {
-        (message as Message).userIds = [
-          (message as Message).senderId!,
-          (message as Message).agentId!,
-        ];
+      if (!(message as Message).userId) {
+        (message as Message).userId = userId;
       }
 
       try {
diff --git a/src/lib/__tests__/actions.test.ts b/src/lib/__tests__/actions.test.ts
index 70b2b55..e446deb 100644
--- a/src/lib/__tests__/actions.test.ts
+++ b/src/lib/__tests__/actions.test.ts
@@ -1,14 +1,13 @@
-import { type User } from "@supabase/supabase-js";
 import { type UUID } from "crypto";
 import dotenv from "dotenv";
 import { createRuntime } from "../../test/createRuntime";
+import { getOrCreateRelationship } from "../../test/getOrCreateRelationship";
 import { runAiTest } from "../../test/runAiTest";
 import { TEST_ACTION, TEST_ACTION_FAIL } from "../../test/testAction";
-import { zeroUuid } from "../constants";
+import { type User } from "../../test/types";
 import { composeContext } from "../context";
 import logger from "../logger";
 import { embeddingZeroVector } from "../memory";
-import { createRelationship, getRelationship } from "../relationships";
 import { type BgentRuntime } from "../runtime";
 import { messageHandlerTemplate } from "../templates";
 import { Content, State, type Message } from "../types";
@@ -20,15 +19,14 @@ async function handleMessage(
   state?: State,
 ) {
   const _saveRequestMessage = async (message: Message, state: State) => {
-    const { content: senderContent, senderId, userIds, room_id } = message;
+    const { content: senderContent, userId, room_id } = message;
 
     const _senderContent = (
       (senderContent as Content).content ?? senderContent
     )?.trim();
     if (_senderContent) {
       await runtime.messageManager.createMemory({
-        user_ids: userIds!,
-        user_id: senderId!,
+        user_id: userId!,
         content: {
           content: _senderContent,
           action: (message.content as Content)?.action ?? "null",
@@ -55,7 +53,7 @@ async function handleMessage(
   }
 
   let responseContent: Content | null = null;
-  const { senderId, room_id, userIds: user_ids, agentId } = message;
+  const { userId, room_id } = message;
 
   for (let triesLeft = 3; triesLeft > 0; triesLeft--) {
     const response = await runtime.completion({
@@ -65,10 +63,8 @@ async function handleMessage(
 
     runtime.databaseAdapter.log({
       body: { message, context, response },
-      user_id: senderId,
+      user_id: userId,
       room_id,
-      user_ids: user_ids!,
-      agent_id: agentId!,
       type: "actions_test_completion",
     });
 
@@ -101,14 +97,13 @@ async function handleMessage(
     state: State,
     responseContent: Content,
   ) => {
-    const { agentId, userIds, room_id } = message;
+    const { room_id } = message;
 
     responseContent.content = responseContent.content?.trim();
 
     if (responseContent.content) {
       await runtime.messageManager.createMemory({
-        user_ids: userIds!,
-        user_id: agentId!,
+        user_id: runtime.agentId,
         content: responseContent,
         room_id,
         embedding: embeddingZeroVector,
@@ -159,25 +154,14 @@ describe("Actions", () => {
     }
 
     // get all relationships for user
-    let data = await getRelationship({
+    const data = await getOrCreateRelationship({
       runtime,
       userA: user.id as UUID,
       userB: "00000000-0000-0000-0000-000000000000" as UUID,
     });
 
-    // if relationship does not exist, create it
     if (!data) {
-      await createRelationship({
-        runtime,
-        userA: user.id as UUID,
-        userB: "00000000-0000-0000-0000-000000000000" as UUID,
-      });
-
-      data = await getRelationship({
-        runtime,
-        userA: user.id as UUID,
-        userB: "00000000-0000-0000-0000-000000000000" as UUID,
-      });
+      throw new Error("Relationship not found");
     }
 
     room_id = data!.room_id;
@@ -190,14 +174,8 @@ describe("Actions", () => {
   });
 
   async function cleanup() {
-    await runtime.factManager.removeAllMemoriesByUserIds([
-      user?.id as UUID,
-      "00000000-0000-0000-0000-000000000000" as UUID,
-    ]);
-    await runtime.messageManager.removeAllMemoriesByUserIds([
-      user?.id as UUID,
-      "00000000-0000-0000-0000-000000000000" as UUID,
-    ]);
+    await runtime.factManager.removeAllMemories(room_id);
+    await runtime.messageManager.removeAllMemories(room_id);
   }
 
   // Test that actions are being loaded into context properly
@@ -218,9 +196,7 @@ describe("Actions", () => {
     expect(testAction).toBeDefined();
     if (testAction && testAction.validate) {
       const isValid = await testAction.validate(runtime, {
-        agentId: zeroUuid,
-        senderId: user.id as UUID,
-        userIds: [user.id as UUID, zeroUuid],
+        userId: user.id as UUID,
         content: { content: "Test message" },
         room_id: room_id,
       });
@@ -234,9 +210,7 @@ describe("Actions", () => {
 
   test("Test that actions are properly validated in state", async () => {
     const message: Message = {
-      senderId: user.id as UUID,
-      agentId: zeroUuid,
-      userIds: [user.id as UUID, zeroUuid],
+      userId: user.id as UUID,
       content: {
         content:
           "Please respond with the message 'ok' and the action TEST_ACTION",
@@ -254,12 +228,7 @@ describe("Actions", () => {
   test("Validate that TEST_ACTION is in the state", async () => {
     await runAiTest("Validate TEST_ACTION is in the state", async () => {
       const message: Message = {
-        senderId: user.id as UUID,
-        agentId: "00000000-0000-0000-0000-000000000000" as UUID,
-        userIds: [
-          user.id as UUID,
-          "00000000-0000-0000-0000-000000000000" as UUID,
-        ],
+        userId: user.id as UUID,
         content: {
           content:
             "Please respond with the message 'ok' and the action TEST_ACTION",
@@ -284,12 +253,7 @@ describe("Actions", () => {
       }
 
       const mockMessage: Message = {
-        agentId: "00000000-0000-0000-0000-000000000000" as UUID,
-        senderId: user.id as UUID,
-        userIds: [
-          user.id as UUID,
-          "00000000-0000-0000-0000-000000000000" as UUID,
-        ],
+        userId: user.id as UUID,
         content: {
           content: "Test message for TEST action",
         },
diff --git a/src/lib/__tests__/evaluation.test.ts b/src/lib/__tests__/evaluation.test.ts
index ff7e782..bcb8b58 100644
--- a/src/lib/__tests__/evaluation.test.ts
+++ b/src/lib/__tests__/evaluation.test.ts
@@ -1,16 +1,16 @@
-import { User } from "@supabase/supabase-js";
 import { UUID } from "crypto";
 import dotenv from "dotenv";
 import { createRuntime } from "../../test/createRuntime";
+import { getOrCreateRelationship } from "../../test/getOrCreateRelationship";
+import { runAiTest } from "../../test/runAiTest";
 import { TEST_EVALUATOR, TEST_EVALUATOR_FAIL } from "../../test/testEvaluator";
+import { type User } from "../../test/types";
+import { zeroUuid } from "../constants";
 import { composeContext } from "../context";
 import { evaluationTemplate } from "../evaluators";
 import fact from "../evaluators/fact";
-import { getRelationship } from "../relationships";
 import { BgentRuntime } from "../runtime";
 import { Message } from "../types";
-import { runAiTest } from "../../test/runAiTest";
-import { zeroUuid } from "../constants";
 
 dotenv.config({ path: ".dev.vars" });
 
@@ -27,17 +27,17 @@ describe("Evaluation Process", () => {
     runtime = setup.runtime;
     user = setup.session.user;
 
-    const relationship = await getRelationship({
+    const data = await getOrCreateRelationship({
       runtime,
       userA: user.id as UUID,
       userB: zeroUuid,
     });
 
-    if (!relationship) {
+    if (!data) {
       throw new Error("Relationship not found");
     }
 
-    room_id = relationship?.room_id;
+    room_id = data!.room_id;
   });
 
   test("Validate the format of the examples from the evaluator", () => {
@@ -57,9 +57,7 @@ describe("Evaluation Process", () => {
 
   test("Check if test and examples appear in state", async () => {
     const message: Message = {
-      senderId: user.id as UUID,
-      agentId: zeroUuid,
-      userIds: [user.id as UUID, zeroUuid],
+      userId: user.id as UUID,
       content: { content: "Test message for evaluation" },
       room_id,
     };
@@ -77,9 +75,7 @@ describe("Evaluation Process", () => {
 
   test("Run the TEST_EVALUATOR handler and validate output", async () => {
     const message: Message = {
-      senderId: user.id as UUID,
-      agentId: zeroUuid,
-      userIds: [user.id as UUID, zeroUuid],
+      userId: user.id as UUID,
       content: { content: "Run TEST_EVALUATOR handler" },
       room_id,
     };
@@ -91,9 +87,7 @@ describe("Evaluation Process", () => {
   test("Run the evaluation process", async () => {
     await runAiTest("Run the evaluation process", async () => {
       const message: Message = {
-        senderId: user.id as UUID,
-        agentId: zeroUuid,
-        userIds: [user.id as UUID, zeroUuid],
+        userId: user.id as UUID,
         content: {
           content:
             "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",
@@ -116,9 +110,7 @@ describe("Evaluation Process", () => {
     });
 
     const message: Message = {
-      senderId: user.id as UUID,
-      agentId: zeroUuid,
-      userIds: [user.id as UUID, zeroUuid],
+      userId: user.id as UUID,
       content: { content: "Test message for evaluation" },
       room_id,
     };
diff --git a/src/lib/__tests__/goals.test.ts b/src/lib/__tests__/goals.test.ts
index 3c538bc..d99150e 100644
--- a/src/lib/__tests__/goals.test.ts
+++ b/src/lib/__tests__/goals.test.ts
@@ -1,7 +1,8 @@
-import { type User } from "@supabase/supabase-js";
 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";
@@ -10,39 +11,28 @@ dotenv.config({ path: ".dev.vars" });
 describe("Goals", () => {
   let runtime: BgentRuntime;
   let user: User;
-
   beforeAll(async () => {
     const result = await createRuntime({
       env: process.env as Record<string, string>,
     });
     runtime = result.runtime;
     user = result.session.user;
-    await runtime.databaseAdapter.removeAllMemoriesByUserIds(
-      [user.id as UUID],
-      "goals",
-    );
+    await runtime.databaseAdapter.removeAllGoals(zeroUuid);
   });
 
   beforeEach(async () => {
-    await runtime.databaseAdapter.removeAllMemoriesByUserIds(
-      [user.id as UUID],
-      "goals",
-    );
+    await runtime.databaseAdapter.removeAllGoals(zeroUuid);
   });
 
   afterAll(async () => {
-    await runtime.databaseAdapter.removeAllMemoriesByUserIds(
-      [user.id as UUID],
-      "goals",
-    );
+    await runtime.databaseAdapter.removeAllGoals(zeroUuid);
   });
 
-  // TODO: Write goal tests here
   test("createGoal - successfully creates a new goal", async () => {
     const newGoal: Goal = {
       name: "Test Create Goal",
       status: GoalStatus.IN_PROGRESS,
-      user_ids: [user?.id as UUID],
+      room_id: zeroUuid,
       user_id: user?.id as UUID,
       objectives: [
         {
@@ -60,9 +50,11 @@ describe("Goals", () => {
     // Verify the goal is created in the database
     const goals = await getGoals({
       runtime,
-      userIds: [user?.id as UUID],
+      userId: user?.id as UUID,
+      room_id: zeroUuid,
       onlyInProgress: false,
     });
+
     const createdGoal = goals.find((goal: Goal) => goal.name === newGoal.name);
 
     expect(createdGoal).toBeDefined();
@@ -75,7 +67,7 @@ describe("Goals", () => {
     const newGoal: Goal = {
       name: "Test Create Goal",
       status: GoalStatus.IN_PROGRESS,
-      user_ids: [user?.id as UUID],
+      room_id: zeroUuid,
       user_id: user?.id as UUID,
       objectives: [
         {
@@ -93,7 +85,7 @@ describe("Goals", () => {
     // retrieve the goal from the database
     let goals = await getGoals({
       runtime,
-      userIds: [user?.id as UUID],
+      room_id: zeroUuid,
       onlyInProgress: false,
     });
     const existingGoal = goals.find(
@@ -108,7 +100,7 @@ describe("Goals", () => {
     // Verify the goal's status is updated in the database
     goals = await getGoals({
       runtime,
-      userIds: [user?.id as UUID],
+      room_id: zeroUuid,
       onlyInProgress: false,
     });
 
@@ -117,5 +109,10 @@ describe("Goals", () => {
     );
 
     expect(updatedGoalInDb?.status).toEqual(GoalStatus.DONE);
+
+    // Clean up the created goal
+    if (existingGoal?.id) {
+      await runtime.databaseAdapter.removeGoal(existingGoal.id);
+    }
   });
 });
diff --git a/src/lib/__tests__/lore.test.ts b/src/lib/__tests__/lore.test.ts
index 80351bd..e50e270 100644
--- a/src/lib/__tests__/lore.test.ts
+++ b/src/lib/__tests__/lore.test.ts
@@ -1,56 +1,66 @@
-import { type User } from "@supabase/supabase-js";
 import { type UUID } from "crypto";
 import dotenv from "dotenv";
 import { createRuntime } from "../../test/createRuntime";
+import { getOrCreateRelationship } from "../../test/getOrCreateRelationship";
+import { type User } from "../../test/types";
+import { zeroUuid } from "../constants";
 import { composeContext } from "../context";
 import { addLore, getLore } from "../lore";
 import { BgentRuntime } from "../runtime";
 import { messageHandlerTemplate } from "../templates";
-import { type Content } from "../types";
-import { zeroUuid } from "../constants";
+import { Memory, type Content } from "../types";
 
 dotenv.config({ path: ".dev.vars" });
 describe("Lore", () => {
   let runtime: BgentRuntime;
-  let user: User;
+  let room_id: UUID;
 
   beforeAll(async () => {
     const result = await createRuntime({
       env: process.env as Record<string, string>,
     });
     runtime = result.runtime;
-    user = result?.session?.user as User;
+    const user = result?.session?.user as User;
+    const data = await getOrCreateRelationship({
+      runtime,
+      userA: user?.id as UUID,
+      userB: zeroUuid,
+    });
+
+    if (!data) {
+      throw new Error("Relationship not found");
+    }
+
+    room_id = data?.room_id;
   });
 
   beforeEach(async () => {
-    await runtime.loreManager.removeAllMemoriesByUserIds([
-      user?.id as UUID,
-      zeroUuid,
-    ]);
+    await runtime.loreManager.removeAllMemories(room_id);
   });
 
   afterAll(async () => {
-    await runtime.loreManager.removeAllMemoriesByUserIds([
-      user?.id as UUID,
-      zeroUuid,
-    ]);
+    await runtime.loreManager.removeAllMemories(room_id);
   });
 
   test("Add and get lore", async () => {
     const content: Content = { content: "Test", source: "/Test.md" };
-    await addLore({
-      runtime,
-      source: "/Test.md",
-      content: { content: "Test" },
-      user_id: zeroUuid,
-      room_id: zeroUuid,
-    });
-
-    const lore = await getLore({
-      runtime,
-      message: "Test",
-    });
+    let lore: Memory[] = [];
+    try {
+      await addLore({
+        runtime,
+        source: "/Test.md",
+        content: { content: "Test" },
+        user_id: zeroUuid,
+        room_id: zeroUuid,
+      });
 
+      lore = await getLore({
+        runtime,
+        message: "Test",
+      });
+    } catch (error) {
+      console.error(error);
+    }
     expect(lore[0].content).toEqual(content);
   }, 60000);
 
@@ -66,9 +76,7 @@ describe("Lore", () => {
     });
 
     const message = {
-      senderId: zeroUuid as UUID,
-      agentId: zeroUuid,
-      userIds: [zeroUuid],
+      userId: zeroUuid as UUID,
       content: { content: "Test Lore Content" },
       room_id: zeroUuid,
     };
diff --git a/src/lib/__tests__/memory.test.ts b/src/lib/__tests__/memory.test.ts
index bf2d07c..bb6c4b1 100644
--- a/src/lib/__tests__/memory.test.ts
+++ b/src/lib/__tests__/memory.test.ts
@@ -1,19 +1,19 @@
-import { type User } from "@supabase/supabase-js";
 import { type UUID } from "crypto";
 import dotenv from "dotenv";
+import { getCachedEmbeddings, writeCachedEmbedding } from "../../test/cache";
 import { createRuntime } from "../../test/createRuntime";
+import { getOrCreateRelationship } from "../../test/getOrCreateRelationship";
+import { type User } from "../../test/types";
+import { zeroUuid } from "../constants";
 import { MemoryManager } from "../memory";
-import { getRelationship } from "../relationships";
 import { type Content, type Memory } from "../types";
-import { getCachedEmbedding, writeCachedEmbedding } from "../../test/cache";
-import { zeroUuid } from "../constants";
 
 dotenv.config({ path: ".dev.vars" });
 describe("Memory", () => {
   let memoryManager: MemoryManager;
   let runtime = null;
-  let user: User | null = null;
-  let room_id: UUID | null = null;
+  let user: User;
+  let room_id: UUID = zeroUuid;
 
   beforeAll(async () => {
     const result = await createRuntime({
@@ -22,7 +22,7 @@ describe("Memory", () => {
     runtime = result.runtime;
     user = result.session.user;
 
-    const data = await getRelationship({
+    const data = await getOrCreateRelationship({
       runtime,
       userA: user?.id as UUID,
       userB: zeroUuid,
@@ -32,7 +32,7 @@ describe("Memory", () => {
       throw new Error("Relationship not found");
     }
 
-    room_id = data?.room_id;
+    room_id = data.room_id;
 
     memoryManager = new MemoryManager({
       tableName: "messages",
@@ -41,17 +41,11 @@ describe("Memory", () => {
   });
 
   beforeEach(async () => {
-    await memoryManager.removeAllMemoriesByUserIds([
-      user?.id as UUID,
-      zeroUuid,
-    ]);
+    await memoryManager.removeAllMemories(room_id);
   });
 
   afterAll(async () => {
-    await memoryManager.removeAllMemoriesByUserIds([
-      user?.id as UUID,
-      zeroUuid,
-    ]);
+    await memoryManager.removeAllMemories(room_id);
   });
 
   test("Search memories by embedding similarity", async () => {
@@ -64,14 +58,13 @@ describe("Memory", () => {
     // Create and add embedding to the base memory
     const baseMemory = await memoryManager.runtime.embed(baseMemoryContent);
 
-    let embedding = getCachedEmbedding(similarMemoryContent);
+    let embedding = getCachedEmbeddings(similarMemoryContent);
 
     // Create and add embedding to the similar and dissimilar memories
     const similarMemory = await memoryManager.addEmbeddingToMemory({
       user_id: user?.id as UUID,
       content: { content: similarMemoryContent },
-      user_ids: [user?.id as UUID, zeroUuid],
-      room_id: room_id as UUID,
+      room_id: room_id,
       embedding,
     });
     if (!embedding) {
@@ -82,13 +75,12 @@ describe("Memory", () => {
     }
     await memoryManager.createMemory(similarMemory);
 
-    embedding = getCachedEmbedding(dissimilarMemoryContent);
+    embedding = getCachedEmbeddings(dissimilarMemoryContent);
 
     const dissimilarMemory = await memoryManager.addEmbeddingToMemory({
       user_id: user?.id as UUID,
       content: { content: dissimilarMemoryContent },
-      user_ids: [user?.id as UUID, zeroUuid],
-      room_id: room_id as UUID,
+      room_id,
       embedding,
     });
     if (!embedding) {
@@ -103,7 +95,7 @@ describe("Memory", () => {
     const searchedMemories = await memoryManager.searchMemoriesByEmbedding(
       baseMemory!,
       {
-        userIds: [user?.id as UUID, zeroUuid],
+        room_id,
         count: 1,
       },
     );
@@ -129,14 +121,13 @@ describe("Memory", () => {
     const highSimilarityContent = "High similarity content to the query memory";
     const lowSimilarityContent = "Low similarity content compared to the query";
 
-    let embedding = getCachedEmbedding(queryMemoryContent);
+    let embedding = getCachedEmbeddings(queryMemoryContent);
 
     // Create and add embedding to the query memory
     const queryMemory = await memoryManager.addEmbeddingToMemory({
       user_id: user?.id as UUID,
       content: { content: queryMemoryContent },
-      user_ids: [user?.id as UUID, zeroUuid],
-      room_id: room_id as UUID,
+      room_id,
       embedding,
     });
     if (!embedding) {
@@ -147,13 +138,12 @@ describe("Memory", () => {
     }
     await memoryManager.createMemory(queryMemory);
 
-    embedding = getCachedEmbedding(highSimilarityContent);
+    embedding = getCachedEmbeddings(highSimilarityContent);
     // Create and add embedding to the high and low similarity memories
     const highSimilarityMemory = await memoryManager.addEmbeddingToMemory({
       user_id: user?.id as UUID,
       content: { content: highSimilarityContent },
-      user_ids: [user?.id as UUID, zeroUuid],
-      room_id: room_id as UUID,
+      room_id,
       embedding,
     });
     if (!embedding) {
@@ -164,12 +154,11 @@ describe("Memory", () => {
     }
     await memoryManager.createMemory(highSimilarityMemory);
 
-    embedding = getCachedEmbedding(lowSimilarityContent);
+    embedding = getCachedEmbeddings(lowSimilarityContent);
     const lowSimilarityMemory = await memoryManager.addEmbeddingToMemory({
       user_id: user?.id as UUID,
       content: { content: lowSimilarityContent },
-      user_ids: [user?.id as UUID, zeroUuid],
-      room_id: room_id as UUID,
+      room_id,
       embedding,
     });
     if (!embedding) {
@@ -184,7 +173,7 @@ describe("Memory", () => {
     const searchedMemories = await memoryManager.searchMemoriesByEmbedding(
       queryMemory.embedding!,
       {
-        userIds: [user?.id as UUID, zeroUuid],
+        room_id,
         count: 10,
       },
     );
@@ -203,8 +192,8 @@ describe("Memory", () => {
 describe("Memory - Basic tests", () => {
   let memoryManager: MemoryManager;
   let runtime = null;
-  let user: User | null = null;
-  let room_id: UUID | null = null;
+  let user: User;
+  let room_id: UUID;
 
   // Setup before all tests
   beforeAll(async () => {
@@ -214,7 +203,7 @@ describe("Memory - Basic tests", () => {
     runtime = result.runtime;
     user = result.session.user;
 
-    const data = await getRelationship({
+    const data = await getOrCreateRelationship({
       runtime,
       userA: user?.id as UUID,
       userB: zeroUuid,
@@ -224,7 +213,7 @@ describe("Memory - Basic tests", () => {
       throw new Error("Relationship not found");
     }
 
-    room_id = data?.room_id;
+    room_id = data.room_id;
 
     memoryManager = new MemoryManager({
       tableName: "messages", // Adjust based on your actual table name
@@ -234,20 +223,16 @@ describe("Memory - Basic tests", () => {
 
   // Cleanup after all tests
   afterAll(async () => {
-    await memoryManager.removeAllMemoriesByUserIds([
-      user?.id as UUID,
-      zeroUuid,
-    ]);
+    await memoryManager.removeAllMemories(room_id);
   });
 
   test("Memory lifecycle: create, search, count, and remove", async () => {
-    const embedding = getCachedEmbedding("Test content for memory lifecycle");
+    const embedding = getCachedEmbeddings("Test content for memory lifecycle");
     // Create a test memory
     const testMemory: Memory = await memoryManager.addEmbeddingToMemory({
-      user_id: user?.id as UUID,
+      user_id: user.id as UUID,
       content: { content: "Test content for memory lifecycle" },
-      user_ids: [user?.id as UUID, zeroUuid],
-      room_id: room_id as UUID,
+      room_id: room_id,
       embedding,
     });
     if (!embedding) {
@@ -258,23 +243,20 @@ describe("Memory - Basic tests", () => {
     }
     await memoryManager.createMemory(testMemory);
 
-    const createdMemories = await memoryManager.getMemoriesByIds({
-      userIds: [user?.id as UUID, zeroUuid],
+    const createdMemories = await memoryManager.getMemories({
+      room_id,
       count: 100,
     });
 
     // Verify creation by counting memories
-    const initialCount = await memoryManager.countMemoriesByUserIds(
-      [user?.id as UUID, zeroUuid],
-      false,
-    );
+    const initialCount = await memoryManager.countMemories(room_id, false);
     expect(initialCount).toBeGreaterThan(0);
 
     // Search memories by embedding
     const searchedMemories = await memoryManager.searchMemoriesByEmbedding(
       testMemory.embedding!,
       {
-        userIds: [user?.id as UUID, zeroUuid],
+        room_id,
         count: 5,
       },
     );
@@ -282,25 +264,20 @@ describe("Memory - Basic tests", () => {
 
     // Remove a specific memory
     await memoryManager.removeMemory(createdMemories[0].id!);
-    const afterRemovalCount = await memoryManager.countMemoriesByUserIds([
-      user?.id as UUID,
-    ]);
+    const afterRemovalCount = await memoryManager.countMemories(room_id);
     expect(afterRemovalCount).toBeLessThan(initialCount);
 
     // Remove all memories for the test user
-    await memoryManager.removeAllMemoriesByUserIds([user?.id as UUID]);
-    const finalCount = await memoryManager.countMemoriesByUserIds([
-      user?.id as UUID,
-      zeroUuid,
-    ]);
+    await memoryManager.removeAllMemories(room_id);
+    const finalCount = await memoryManager.countMemories(room_id);
     expect(finalCount).toEqual(0);
   });
 });
 describe("Memory - Extended Tests", () => {
   let memoryManager: MemoryManager;
   let runtime = null;
-  let user: User | null = null;
-  let room_id: UUID | null = null;
+  let user: User;
+  let room_id: UUID;
 
   beforeAll(async () => {
     const result = await createRuntime({
@@ -309,7 +286,7 @@ describe("Memory - Extended Tests", () => {
     runtime = result.runtime;
     user = result.session.user;
 
-    const data = await getRelationship({
+    const data = await getOrCreateRelationship({
       runtime,
       userA: user.id as UUID,
       userB: zeroUuid,
@@ -319,7 +296,9 @@ describe("Memory - Extended Tests", () => {
       throw new Error("Relationship not found");
     }
 
-    room_id = data?.room_id;
+    room_id = data.room_id;
+
+    if (!room_id) throw new Error("Room not found");
 
     memoryManager = new MemoryManager({
       tableName: "messages",
@@ -328,17 +307,11 @@ describe("Memory - Extended Tests", () => {
   });
 
   beforeEach(async () => {
-    await memoryManager.removeAllMemoriesByUserIds([
-      user?.id as UUID,
-      zeroUuid,
-    ]);
+    await memoryManager.removeAllMemories(room_id);
   });
 
   afterAll(async () => {
-    await memoryManager.removeAllMemoriesByUserIds([
-      user?.id as UUID,
-      zeroUuid,
-    ]);
+    await memoryManager.removeAllMemories(room_id);
   });
 
   test("Test cosine similarity value equality", async () => {
@@ -349,14 +322,13 @@ describe("Memory - Extended Tests", () => {
     // Create and add embedding to the base memory
     const baseMemory = await memoryManager.runtime.embed(baseMemoryContent);
 
-    const embedding = getCachedEmbedding(similarMemoryContent);
+    const embedding = getCachedEmbeddings(similarMemoryContent);
 
     // Create and add embedding to the similar and dissimilar memories
     const similarMemory = await memoryManager.addEmbeddingToMemory({
       user_id: user?.id as UUID,
       content: { content: similarMemoryContent },
-      user_ids: [user?.id as UUID, zeroUuid],
-      room_id: room_id as UUID,
+      room_id,
       embedding,
     });
     if (!embedding) {
@@ -371,7 +343,7 @@ describe("Memory - Extended Tests", () => {
     const searchedMemories = await memoryManager.searchMemoriesByEmbedding(
       baseMemory!,
       {
-        userIds: [user?.id as UUID, zeroUuid],
+        room_id,
         count: 1,
       },
     );
@@ -390,14 +362,13 @@ describe("Memory - Extended Tests", () => {
     // Create and add embedding to the base memory
     const baseMemory = await memoryManager.runtime.embed(baseMemoryContent);
 
-    const embedding = getCachedEmbedding(similarMemoryContent);
+    const embedding = getCachedEmbeddings(similarMemoryContent);
 
     // Create and add embedding to the similar and dissimilar memories
     const similarMemory = await memoryManager.addEmbeddingToMemory({
       user_id: user?.id as UUID,
       content: { content: similarMemoryContent },
-      user_ids: [user?.id as UUID, zeroUuid],
-      room_id: room_id as UUID,
+      room_id: room_id,
       embedding,
     });
     if (!embedding) {
@@ -413,7 +384,7 @@ describe("Memory - Extended Tests", () => {
       baseMemory!,
       {
         match_threshold: 0.01,
-        userIds: [user?.id as UUID, zeroUuid],
+        room_id,
         count: 1,
       },
     );
@@ -430,14 +401,13 @@ describe("Memory - Extended Tests", () => {
     const memoryContent = "Cognitive security in the information age";
     const similarMemoryContent = "Cognitive security in the information age";
 
-    let embedding = getCachedEmbedding(memoryContent);
+    let embedding = getCachedEmbeddings(memoryContent);
 
     // Create and add embedding to the similar and dissimilar memories
     const newMemory = await memoryManager.addEmbeddingToMemory({
       user_id: user?.id as UUID,
       content: { content: memoryContent },
-      user_ids: [user?.id as UUID, zeroUuid],
-      room_id: room_id as UUID,
+      room_id,
       embedding,
     });
     if (!embedding) {
@@ -445,14 +415,13 @@ describe("Memory - Extended Tests", () => {
     }
     await memoryManager.createMemory(newMemory, true);
 
-    embedding = getCachedEmbedding(similarMemoryContent);
+    embedding = getCachedEmbeddings(similarMemoryContent);
 
     // Create and add embedding to the similar and dissimilar memories
     const similarMemory = await memoryManager.addEmbeddingToMemory({
       user_id: user?.id as UUID,
       content: { content: similarMemoryContent },
-      user_ids: [user?.id as UUID, zeroUuid],
-      room_id: room_id as UUID,
+      room_id,
       embedding,
     });
     if (!embedding) {
@@ -463,14 +432,8 @@ describe("Memory - Extended Tests", () => {
     }
     await memoryManager.createMemory(similarMemory, true);
 
-    const allCount = await memoryManager.countMemoriesByUserIds(
-      [user?.id as UUID, zeroUuid],
-      false,
-    );
-    const uniqueCount = await memoryManager.countMemoriesByUserIds(
-      [user?.id as UUID, zeroUuid],
-      true,
-    );
+    const allCount = await memoryManager.countMemories(room_id, false);
+    const uniqueCount = await memoryManager.countMemories(room_id, true);
 
     expect(allCount > uniqueCount).toBe(true);
   });
@@ -484,14 +447,13 @@ describe("Memory - Extended Tests", () => {
     // Create and add embedding to the base memory
     const baseMemory = await memoryManager.runtime.embed(baseMemoryContent);
 
-    let embedding = getCachedEmbedding(similarMemoryContent);
+    let embedding = getCachedEmbeddings(similarMemoryContent);
 
     // Create and add embedding to the similar and dissimilar memories
     const similarMemory = await memoryManager.addEmbeddingToMemory({
       user_id: user?.id as UUID,
       content: { content: similarMemoryContent },
-      user_ids: [user?.id as UUID, zeroUuid],
-      room_id: room_id as UUID,
+      room_id,
       embedding,
     });
     if (!embedding) {
@@ -502,14 +464,13 @@ describe("Memory - Extended Tests", () => {
     }
     await memoryManager.createMemory(similarMemory);
 
-    embedding = getCachedEmbedding(dissimilarMemoryContent);
+    embedding = getCachedEmbeddings(dissimilarMemoryContent);
 
     const dissimilarMemory = await memoryManager.addEmbeddingToMemory({
       user_id: user?.id as UUID,
       content: { content: dissimilarMemoryContent },
-      user_ids: [user?.id as UUID, zeroUuid],
-      room_id: room_id as UUID,
-      embedding: getCachedEmbedding(dissimilarMemoryContent),
+      room_id,
+      embedding: getCachedEmbeddings(dissimilarMemoryContent),
     });
     if (!embedding) {
       writeCachedEmbedding(
@@ -523,7 +484,7 @@ describe("Memory - Extended Tests", () => {
     const searchedMemories = await memoryManager.searchMemoriesByEmbedding(
       baseMemory!,
       {
-        userIds: [user?.id as UUID, zeroUuid],
+        room_id,
         count: 1,
       },
     );
@@ -549,14 +510,13 @@ describe("Memory - Extended Tests", () => {
     const highSimilarityContent = "High similarity content to the query memory";
     const lowSimilarityContent = "Low similarity, not related";
 
-    let embedding = getCachedEmbedding(queryMemoryContent);
+    let embedding = getCachedEmbeddings(queryMemoryContent);
 
     // Create and add embedding to the query memory
     const queryMemory = await memoryManager.addEmbeddingToMemory({
       user_id: user?.id as UUID,
       content: { content: queryMemoryContent },
-      user_ids: [user?.id as UUID, zeroUuid],
-      room_id: room_id as UUID,
+      room_id,
       embedding,
     });
     if (!embedding) {
@@ -567,13 +527,12 @@ describe("Memory - Extended Tests", () => {
     }
     await memoryManager.createMemory(queryMemory);
 
-    embedding = getCachedEmbedding(highSimilarityContent);
+    embedding = getCachedEmbeddings(highSimilarityContent);
     // Create and add embedding to the high and low similarity memories
     const highSimilarityMemory = await memoryManager.addEmbeddingToMemory({
       user_id: user?.id as UUID,
       content: { content: highSimilarityContent },
-      user_ids: [user?.id as UUID, zeroUuid],
-      room_id: room_id as UUID,
+      room_id,
       embedding,
     });
     if (!embedding) {
@@ -584,12 +543,11 @@ describe("Memory - Extended Tests", () => {
     }
     await memoryManager.createMemory(highSimilarityMemory);
 
-    embedding = getCachedEmbedding(lowSimilarityContent);
+    embedding = getCachedEmbeddings(lowSimilarityContent);
     const lowSimilarityMemory = await memoryManager.addEmbeddingToMemory({
       user_id: user?.id as UUID,
       content: { content: lowSimilarityContent },
-      user_ids: [user?.id as UUID, zeroUuid],
-      room_id: room_id as UUID,
+      room_id,
       embedding,
     });
     if (!embedding) {
@@ -604,7 +562,7 @@ describe("Memory - Extended Tests", () => {
     const searchedMemories = await memoryManager.searchMemoriesByEmbedding(
       queryMemory.embedding!,
       {
-        userIds: [user?.id as UUID, zeroUuid],
+        room_id,
         count: 10,
       },
     );
diff --git a/src/lib/__tests__/messages.test.ts b/src/lib/__tests__/messages.test.ts
index 444e55d..8fcd68f 100644
--- a/src/lib/__tests__/messages.test.ts
+++ b/src/lib/__tests__/messages.test.ts
@@ -1,10 +1,16 @@
-import { type User } from "@supabase/supabase-js";
 import { type UUID } from "crypto";
+import dotenv from "dotenv";
 import { createRuntime } from "../../test/createRuntime";
+import { getOrCreateRelationship } from "../../test/getOrCreateRelationship";
+import { type User } from "../../test/types";
+import { zeroUuid } from "../constants";
+import { formatFacts } from "../evaluators/fact";
 import { formatActors, formatMessages, getActorDetails } from "../messages";
+import { createRelationship } from "../relationships";
 import { type BgentRuntime } from "../runtime";
 import { type Actor, type Content, type Memory } from "../types";
-import { formatFacts } from "../evaluators/fact";
+
+dotenv.config({ path: ".dev.vars" });
 
 describe("Messages Library", () => {
   let runtime: BgentRuntime, user: User, actors: Actor[];
@@ -17,14 +23,34 @@ describe("Messages Library", () => {
     user = setup.session.user;
     actors = await getActorDetails({
       runtime,
-      userIds: [user.id as UUID, "00000000-0000-0000-0000-000000000000"],
+      room_id: "00000000-0000-0000-0000-000000000000",
     });
   });
 
-  test("getActorDetails should return actors based on given userIds", async () => {
+  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 getOrCreateRelationship({
+      runtime,
+      userA,
+      userB,
+    });
+
+    if (!relationship?.room_id) {
+      throw new Error("Room not found");
+    }
+
     const result = await getActorDetails({
       runtime,
-      userIds: [user.id as UUID, "00000000-0000-0000-0000-000000000000"],
+      room_id: relationship?.room_id as UUID,
     });
     expect(result.length).toBeGreaterThan(0);
     result.forEach((actor: Actor) => {
@@ -35,11 +61,8 @@ describe("Messages Library", () => {
   });
 
   test("formatActors should format actors into a readable string", () => {
-    console.log("*** actors", actors);
     const formattedActors = formatActors({ actors });
-    console.log("*** formattedActors", formattedActors);
     actors.forEach((actor) => {
-      console.log("*** actor.name", actor.name);
       expect(formattedActors).toContain(actor.name);
     });
   });
@@ -49,13 +72,11 @@ describe("Messages Library", () => {
       {
         content: { content: "Hello" },
         user_id: user.id as UUID,
-        user_ids: [user.id as UUID],
         room_id: "00000000-0000-0000-0000-000000000000",
       },
       {
         content: { content: "How are you?" },
         user_id: "00000000-0000-0000-0000-000000000000",
-        user_ids: [user.id as UUID],
         room_id: "00000000-0000-0000-0000-000000000000",
       },
     ];
@@ -70,13 +91,11 @@ describe("Messages Library", () => {
       {
         content: { content: "Reflecting on the day" },
         user_id: user.id as UUID,
-        user_ids: [user.id as UUID],
         room_id: "00000000-0000-0000-0000-000000000000",
       },
       {
         content: { content: "Thoughts and musings" },
         user_id: "00000000-0000-0000-0000-000000000000",
-        user_ids: [user.id as UUID],
         room_id: "00000000-0000-0000-0000-000000000000room",
       },
     ];
diff --git a/src/lib/__tests__/providers.test.ts b/src/lib/__tests__/providers.test.ts
index 01f88ff..487e16f 100644
--- a/src/lib/__tests__/providers.test.ts
+++ b/src/lib/__tests__/providers.test.ts
@@ -24,14 +24,12 @@ describe("TestProvider", () => {
       providers: [TestProvider],
     });
     runtime = setup.runtime;
-    room_id = "some-room-id" as UUID;
+    room_id = zeroUuid;
   });
 
   test("TestProvider should return 'Hello Test'", async () => {
     const message: Message = {
-      senderId: zeroUuid,
-      agentId: zeroUuid,
-      userIds: [zeroUuid, zeroUuid],
+      userId: zeroUuid,
       content: { content: "" },
       room_id: room_id,
     };
diff --git a/src/lib/__tests__/relationships.test.ts b/src/lib/__tests__/relationships.test.ts
index c1b0e05..a5ba8a0 100644
--- a/src/lib/__tests__/relationships.test.ts
+++ b/src/lib/__tests__/relationships.test.ts
@@ -1,14 +1,11 @@
-import { type User } from "@supabase/supabase-js";
 import { type UUID } from "crypto";
 import dotenv from "dotenv";
 import { createRuntime } from "../../test/createRuntime"; // Adjust the import path as needed
-import {
-  createRelationship,
-  getRelationship,
-  getRelationships,
-} from "../relationships"; // Adjust the import path as needed
-import { BgentRuntime } from "../runtime";
+import { getOrCreateRelationship } from "../../test/getOrCreateRelationship";
+import { type User } from "../../test/types";
 import { zeroUuid } from "../constants";
+import { createRelationship, getRelationships } from "../relationships"; // Adjust the import path as needed
+import { BgentRuntime } from "../runtime";
 
 dotenv.config({ path: ".dev.vars" });
 
@@ -22,18 +19,20 @@ describe("Relationships Module", () => {
     });
     runtime = setup.runtime;
     user = setup.session.user;
+    if (!user.id) {
+      throw new Error("User ID is undefined");
+    }
   });
 
   test("createRelationship creates a new relationship", async () => {
-    const userA = user?.id as UUID;
+    const userA = user.id as UUID;
     const userB = zeroUuid;
-
+    if (userA === undefined) throw new Error("userA is undefined");
     const relationship = await createRelationship({
       runtime,
       userA,
       userB,
     });
-
     expect(relationship).toBe(true);
   });
 
@@ -43,7 +42,7 @@ describe("Relationships Module", () => {
 
     await createRelationship({ runtime, userA, userB });
 
-    const relationship = await getRelationship({
+    const relationship = await getOrCreateRelationship({
       runtime,
       userA,
       userB,
diff --git a/src/lib/__tests__/runtime.test.ts b/src/lib/__tests__/runtime.test.ts
index 425b8a7..5b1ea9d 100644
--- a/src/lib/__tests__/runtime.test.ts
+++ b/src/lib/__tests__/runtime.test.ts
@@ -1,26 +1,23 @@
+import { type UUID } from "crypto";
 import dotenv from "dotenv";
+import { getCachedEmbeddings, writeCachedEmbedding } from "../../test/cache";
 import { createRuntime } from "../../test/createRuntime";
-import { type UUID } from "crypto";
-import { getRelationship } from "../relationships";
-import { getCachedEmbedding, writeCachedEmbedding } from "../../test/cache";
+import { getOrCreateRelationship } from "../../test/getOrCreateRelationship";
+import { type User } from "../../test/types";
+import { zeroUuid } from "../constants";
 import { BgentRuntime } from "../runtime";
-import { type User } from "@supabase/supabase-js";
 import { type Message } from "../types";
-import { zeroUuid } from "../constants";
 
 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() {
-    await runtime.messageManager.removeAllMemoriesByUserIds([
-      user?.id as UUID,
-      zeroUuid,
-    ]);
+    await runtime.messageManager.removeAllMemories(room_id);
   }
 
   // Helper function to create memories
@@ -34,18 +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,
-        user_ids: [user?.id as UUID, zeroUuid],
-        content,
-        room_id,
-        embedding,
-      });
-      if (!embedding) {
-        writeCachedEmbedding(content.content, memory.embedding as number[]);
+      try {
+        const embedding = getCachedEmbeddings(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);
     }
   }
 
@@ -58,7 +58,7 @@ describe("Agent Runtime", () => {
     runtime = result.runtime;
     user = result.session.user;
 
-    const data = await getRelationship({
+    const data = await getOrCreateRelationship({
       runtime,
       userA: user?.id as UUID,
       userB: zeroUuid,
@@ -67,8 +67,7 @@ describe("Agent Runtime", () => {
     if (!data) {
       throw new Error("Relationship not found");
     }
-
-    room_id = data?.room_id;
+    room_id = data.room_id;
     await clearMemories(); // Clear memories before each test
   });
 
@@ -88,12 +87,14 @@ 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);
+    }
 
     const message: Message = {
-      senderId: user.id as UUID,
-      agentId: zeroUuid,
-      userIds: [user.id as UUID, zeroUuid],
+      userId: user.id as UUID,
       content: { content: "test message" },
       room_id: room_id as UUID,
     };
@@ -103,5 +104,5 @@ describe("Agent Runtime", () => {
     expect(state.recentMessagesData.length).toBeGreaterThan(1);
 
     await clearMemories();
-  });
+  }, 60000);
 });
diff --git a/src/lib/actions/__tests__/elaborate.test.ts b/src/lib/actions/__tests__/elaborate.test.ts
index 145e437..fe4e8e7 100644
--- a/src/lib/actions/__tests__/elaborate.test.ts
+++ b/src/lib/actions/__tests__/elaborate.test.ts
@@ -1,17 +1,17 @@
-import { type User } from "@supabase/supabase-js";
 import { type UUID } from "crypto";
 import dotenv from "dotenv";
 import { createRuntime } from "../../../test/createRuntime";
 import { Goodbye1 } from "../../../test/data";
+import { getOrCreateRelationship } from "../../../test/getOrCreateRelationship";
 import { populateMemories } from "../../../test/populateMemories";
-import { getRelationship } from "../../relationships";
+import { runAiTest } from "../../../test/runAiTest";
+import { type User } from "../../../test/types";
+import { zeroUuid } from "../../constants";
 import { type BgentRuntime } from "../../runtime";
 import { Content, type Message } from "../../types";
 import action from "../elaborate";
 import ignore from "../ignore";
-import { zeroUuid } from "../../constants";
 import wait from "../wait";
-import { runAiTest } from "../../../test/runAiTest";
 
 dotenv.config({ path: ".dev.vars" });
 
@@ -45,7 +45,7 @@ const GetContinueExample1 = (_user_id: UUID) => [
 describe("User Profile", () => {
   let user: User;
   let runtime: BgentRuntime;
-  let room_id: UUID;
+  let room_id: UUID = zeroUuid;
 
   afterAll(async () => {
     await cleanup();
@@ -59,7 +59,7 @@ describe("User Profile", () => {
     user = setup.session.user;
     runtime = setup.runtime;
 
-    const data = await getRelationship({
+    const data = await getOrCreateRelationship({
       runtime,
       userA: user.id as UUID,
       userB: zeroUuid,
@@ -69,7 +69,16 @@ describe("User Profile", () => {
       throw new Error("Relationship not found");
     }
 
-    room_id = data?.room_id;
+    const rooms = await runtime.databaseAdapter.getRoomsByParticipants([
+      user.id as UUID,
+      zeroUuid,
+    ]);
+
+    if (!rooms || rooms.length === 0) {
+      throw new Error("Room not found");
+    }
+
+    room_id = rooms[0];
 
     await cleanup();
   });
@@ -79,14 +88,8 @@ describe("User Profile", () => {
   });
 
   async function cleanup() {
-    await runtime.factManager.removeAllMemoriesByUserIds([
-      user.id as UUID,
-      zeroUuid,
-    ]);
-    await runtime.messageManager.removeAllMemoriesByUserIds([
-      user.id as UUID,
-      zeroUuid,
-    ]);
+    await runtime.factManager.removeAllMemories(room_id);
+    await runtime.messageManager.removeAllMemories(room_id);
   }
 
   // test validate function response
@@ -94,9 +97,7 @@ describe("User Profile", () => {
   test("Test validate function response", async () => {
     await runAiTest("Test validate function response", async () => {
       const message: Message = {
-        senderId: user.id as UUID,
-        agentId: zeroUuid,
-        userIds: [user.id as UUID, zeroUuid],
+        userId: user.id as UUID,
         content: { content: "Hello", action: "WAIT" },
         room_id: room_id as UUID,
       };
@@ -109,9 +110,7 @@ describe("User Profile", () => {
       await populateMemories(runtime, user, room_id, [GetContinueExample1]);
 
       const message2: Message = {
-        senderId: zeroUuid as UUID,
-        agentId: zeroUuid,
-        userIds: [user.id as UUID, zeroUuid],
+        userId: zeroUuid as UUID,
         content: {
           content: "Hello",
           action: "ELABORATE",
@@ -128,15 +127,13 @@ describe("User Profile", () => {
   test("Test repetition check on elaborate", async () => {
     await runAiTest("Test repetition check on elaborate", async () => {
       const message: Message = {
-        senderId: zeroUuid as UUID,
-        agentId: zeroUuid,
-        userIds: [user?.id as UUID, zeroUuid],
+        userId: zeroUuid as UUID,
         content: {
           content:
             "Hmm, let think for a second, I was going to tell you about something...",
           action: "ELABORATE",
         },
-        room_id: room_id as UUID,
+        room_id,
       };
 
       const handler = action.handler!;
@@ -154,33 +151,29 @@ describe("User Profile", () => {
       "Test multiple elaborate messages in a conversation",
       async () => {
         const message: Message = {
-          senderId: user?.id as UUID,
-          agentId: zeroUuid,
-          userIds: [user?.id as UUID, zeroUuid],
+          userId: user?.id as UUID,
           content: {
             content:
               "Write a short story in three parts, using the ELABORATE action for each part.",
             action: "WAIT",
           },
-          room_id: room_id as UUID,
+          room_id: room_id,
         };
 
-        const initialMessageCount =
-          await runtime.messageManager.countMemoriesByUserIds(
-            [user?.id as UUID, zeroUuid],
-            false,
-          );
+        const initialMessageCount = await runtime.messageManager.countMemories(
+          room_id,
+          false,
+        );
 
         await action.handler!(runtime, message);
 
-        const finalMessageCount =
-          await runtime.messageManager.countMemoriesByUserIds(
-            [user?.id as UUID, zeroUuid],
-            false,
-          );
+        const finalMessageCount = await runtime.messageManager.countMemories(
+          room_id,
+          false,
+        );
 
-        const agentMessages = await runtime.messageManager.getMemoriesByIds({
-          userIds: [user?.id as UUID, zeroUuid],
+        const agentMessages = await runtime.messageManager.getMemories({
+          room_id,
           count: finalMessageCount - initialMessageCount,
           unique: false,
         });
@@ -197,10 +190,9 @@ describe("User Profile", () => {
 
         // Check if the agent used the ELABORATE action for each part
         const usedElaborateAction = elaborateMessages.length === 3;
-
         // 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;
@@ -211,9 +203,7 @@ describe("User Profile", () => {
   test("Test if message is added to database", async () => {
     await runAiTest("Test if message is added to database", async () => {
       const message: Message = {
-        senderId: user?.id as UUID,
-        agentId: zeroUuid,
-        userIds: [user?.id as UUID, zeroUuid],
+        userId: user?.id as UUID,
         content: {
           content: "Tell me more about your favorite food.",
           action: "WAIT",
@@ -221,19 +211,17 @@ describe("User Profile", () => {
         room_id: room_id as UUID,
       };
 
-      const initialMessageCount =
-        await runtime.messageManager.countMemoriesByUserIds(
-          [user?.id as UUID, zeroUuid],
-          false,
-        );
+      const initialMessageCount = await runtime.messageManager.countMemories(
+        room_id,
+        false,
+      );
 
       await action.handler!(runtime, message);
 
-      const finalMessageCount =
-        await runtime.messageManager.countMemoriesByUserIds(
-          [user?.id as UUID, zeroUuid],
-          false,
-        );
+      const finalMessageCount = await runtime.messageManager.countMemories(
+        room_id,
+        false,
+      );
 
       return finalMessageCount - initialMessageCount === 2;
     });
@@ -242,9 +230,7 @@ describe("User Profile", () => {
     await runAiTest("Test if not elaborate", async () => {
       // this is basically the same test as the one in ignore.test.ts
       const message: Message = {
-        senderId: user?.id as UUID,
-        agentId: zeroUuid,
-        userIds: [user?.id as UUID, zeroUuid],
+        userId: user?.id as UUID,
         content: { content: "Bye" },
         room_id: room_id as UUID,
       };
diff --git a/src/lib/actions/__tests__/ignore.test.ts b/src/lib/actions/__tests__/ignore.test.ts
index 72995fb..0826d60 100644
--- a/src/lib/actions/__tests__/ignore.test.ts
+++ b/src/lib/actions/__tests__/ignore.test.ts
@@ -1,4 +1,3 @@
-import { type User } from "@supabase/supabase-js";
 import { type UUID } from "crypto";
 import dotenv from "dotenv";
 import { createRuntime } from "../../../test/createRuntime";
@@ -7,13 +6,14 @@ import {
   GetTellMeAboutYourselfConversationTroll2,
   Goodbye1,
 } from "../../../test/data";
+import { getOrCreateRelationship } from "../../../test/getOrCreateRelationship";
 import { populateMemories } from "../../../test/populateMemories";
 import { runAiTest } from "../../../test/runAiTest";
+import { type User } from "../../../test/types";
 import { zeroUuid } from "../../constants";
 import { composeContext } from "../../context";
 import logger from "../../logger";
 import { embeddingZeroVector } from "../../memory";
-import { getRelationship } from "../../relationships";
 import { type BgentRuntime } from "../../runtime";
 import { messageHandlerTemplate } from "../../templates";
 import { Content, State, type Message } from "../../types";
@@ -26,15 +26,14 @@ async function handleMessage(
   state?: State,
 ) {
   const _saveRequestMessage = async (message: Message, state: State) => {
-    const { content: senderContent, senderId, userIds, room_id } = message;
+    const { content: senderContent, userId, room_id } = message;
 
     const _senderContent = (
       (senderContent as Content).content ?? senderContent
     )?.trim();
     if (_senderContent) {
       await runtime.messageManager.createMemory({
-        user_ids: userIds!,
-        user_id: senderId!,
+        user_id: userId!,
         content: {
           content: _senderContent,
           action: (message.content as Content)?.action ?? "null",
@@ -61,7 +60,7 @@ async function handleMessage(
   }
 
   let responseContent: Content | null = null;
-  const { senderId, room_id, userIds: user_ids, agentId } = message;
+  const { userId, room_id } = message;
 
   for (let triesLeft = 3; triesLeft > 0; triesLeft--) {
     const response = await runtime.completion({
@@ -71,10 +70,8 @@ async function handleMessage(
 
     await runtime.databaseAdapter.log({
       body: { message, context, response },
-      user_id: senderId,
+      user_id: userId,
       room_id,
-      user_ids: user_ids!,
-      agent_id: agentId!,
       type: "ignore_test_completion",
     });
 
@@ -107,14 +104,13 @@ async function handleMessage(
     state: State,
     responseContent: Content,
   ) => {
-    const { agentId, userIds, room_id } = message;
+    const { room_id } = message;
 
     responseContent.content = responseContent.content?.trim();
 
     if (responseContent.content) {
       await runtime.messageManager.createMemory({
-        user_ids: userIds!,
-        user_id: agentId!,
+        user_id: runtime.agentId,
         content: responseContent,
         room_id,
         embedding: embeddingZeroVector,
@@ -151,7 +147,7 @@ describe("Ignore action tests", () => {
     user = setup.session.user;
     runtime = setup.runtime;
 
-    const data = await getRelationship({
+    const data = await getOrCreateRelationship({
       runtime,
       userA: user?.id as UUID,
       userB: zeroUuid,
@@ -171,22 +167,14 @@ describe("Ignore action tests", () => {
   });
 
   async function cleanup() {
-    await runtime.factManager.removeAllMemoriesByUserIds([
-      user?.id as UUID,
-      zeroUuid,
-    ]);
-    await runtime.messageManager.removeAllMemoriesByUserIds([
-      user?.id as UUID,
-      zeroUuid,
-    ]);
+    await runtime.factManager.removeAllMemories(room_id);
+    await runtime.messageManager.removeAllMemories(room_id);
   }
 
   test("Test ignore action", async () => {
     await runAiTest("Test ignore action", async () => {
       const message: Message = {
-        senderId: user?.id as UUID,
-        agentId: zeroUuid,
-        userIds: [user?.id as UUID, zeroUuid],
+        userId: user?.id as UUID,
         content: { content: "Never talk to me again", action: "WAIT" },
         room_id: room_id as UUID,
       };
@@ -206,9 +194,7 @@ describe("Ignore action tests", () => {
       "Action handler test 1: response should be ignore",
       async () => {
         const message: Message = {
-          senderId: user.id as UUID,
-          agentId: zeroUuid,
-          userIds: [user?.id as UUID, zeroUuid],
+          userId: user.id as UUID,
           content: { content: "", action: "IGNORE" },
           room_id: room_id as UUID,
         };
@@ -233,9 +219,7 @@ describe("Ignore action tests", () => {
       "Action handler test 2: response should be ignore",
       async () => {
         const message: Message = {
-          senderId: user.id as UUID,
-          agentId: zeroUuid,
-          userIds: [user?.id as UUID, zeroUuid],
+          userId: user.id as UUID,
           content: { content: "", action: "IGNORE" },
           room_id: room_id as UUID,
         };
@@ -258,9 +242,7 @@ describe("Ignore action tests", () => {
   test("Expect ignore", async () => {
     await runAiTest("Expect ignore", async () => {
       const message: Message = {
-        senderId: user.id as UUID,
-        agentId: zeroUuid,
-        userIds: [user?.id as UUID, zeroUuid],
+        userId: user.id as UUID,
         content: { content: "Bye", action: "WAIT" },
         room_id: room_id as UUID,
       };
diff --git a/src/lib/actions/__tests__/wait.test.ts b/src/lib/actions/__tests__/wait.test.ts
index 3217bf8..68c7e33 100644
--- a/src/lib/actions/__tests__/wait.test.ts
+++ b/src/lib/actions/__tests__/wait.test.ts
@@ -1,15 +1,15 @@
-import { type User } from "@supabase/supabase-js";
 import { type UUID } from "crypto";
 import dotenv from "dotenv";
 import { createRuntime } from "../../../test/createRuntime";
 import { GetTellMeAboutYourselfConversation1 } from "../../../test/data";
+import { getOrCreateRelationship } from "../../../test/getOrCreateRelationship";
 import { populateMemories } from "../../../test/populateMemories";
-import { getRelationship } from "../../relationships";
+import { runAiTest } from "../../../test/runAiTest";
+import { type User } from "../../../test/types";
+import { zeroUuid } from "../../constants";
 import { type BgentRuntime } from "../../runtime";
 import { type Message } from "../../types";
 import action from "../wait"; // Import the wait action
-import { zeroUuid } from "../../constants";
-import { runAiTest } from "../../../test/runAiTest";
 
 dotenv.config({ path: ".dev.vars" });
 
@@ -34,7 +34,7 @@ describe("Wait Action Behavior", () => {
     user = setup.session.user;
     runtime = setup.runtime;
 
-    const data = await getRelationship({
+    const data = await getOrCreateRelationship({
       runtime,
       userA: user?.id as UUID,
       userB: zeroUuid,
@@ -50,22 +50,14 @@ describe("Wait Action Behavior", () => {
   });
 
   async function cleanup() {
-    await runtime.factManager.removeAllMemoriesByUserIds([
-      user?.id as UUID,
-      zeroUuid,
-    ]);
-    await runtime.messageManager.removeAllMemoriesByUserIds([
-      user?.id as UUID,
-      zeroUuid,
-    ]);
+    await runtime.factManager.removeAllMemories(room_id);
+    await runtime.messageManager.removeAllMemories(room_id);
   }
 
   test("Test wait action behavior", async () => {
     await runAiTest("Test wait action behavior", async () => {
       const message: Message = {
-        senderId: zeroUuid as UUID,
-        agentId: zeroUuid,
-        userIds: [user?.id as UUID, zeroUuid],
+        userId: zeroUuid as UUID,
         content: {
           content: "Please wait a moment, I need to think about this...",
           action: "WAIT",
diff --git a/src/lib/actions/elaborate.ts b/src/lib/actions/elaborate.ts
index e917369..9f36079 100644
--- a/src/lib/actions/elaborate.ts
+++ b/src/lib/actions/elaborate.ts
@@ -17,15 +17,17 @@ const maxContinuesInARow = 2;
 export default {
   name: "ELABORATE",
   description:
-    "ONLY use this action when the message necessitates a follow up. Do not use this when asking a question (use WAIT instead). Do not use this action when the conversation is finished or the user does not wish to speak (use IGNORE instead). If the last message action was ELABORATE, and the user has not responded, use WAIT instead. Use sparingly!",
+    "ONLY use this action when the message necessitates a follow up. Do not use this when asking a question (use WAIT instead). Do not use this action when the conversation is finished or the user does not wish to speak (use IGNORE instead). If the last message action was ELABORATE, and the user has not responded, use WAIT instead. Use sparingly! DO NOT USE WHEN ASKING A QUESTION, ALWAYS USE WAIT WHEN ASKING A QUESTION.",
   validate: async (runtime: BgentRuntime, message: Message) => {
-    const recentMessagesData = await runtime.messageManager.getMemoriesByIds({
-      userIds: message.userIds!,
-      count: 10,
-      unique: false,
-    });
+    const recentMessagesData = await runtime.messageManager.getMemories(
+      {
+        room_id: message.room_id,
+        count: 10,
+        unique: false,
+      },
+    );
     const agentMessages = recentMessagesData.filter(
-      (m) => m.user_id === message.agentId,
+      (m) => m.user_id === runtime.agentId,
     );
 
     // check if the last messages were all continues=
@@ -56,7 +58,7 @@ export default {
     }
 
     let responseContent;
-    const { senderId, room_id, userIds: user_ids, agentId } = message;
+    const { userId, room_id } = message;
 
     for (let triesLeft = 3; triesLeft > 0; triesLeft--) {
       const response = await runtime.completion({
@@ -66,10 +68,8 @@ export default {
 
       runtime.databaseAdapter.log({
         body: { message, context, response },
-        user_id: senderId,
+        user_id: userId,
         room_id,
-        user_ids: user_ids!,
-        agent_id: agentId!,
         type: "elaborate",
       });
 
@@ -88,12 +88,16 @@ export default {
       if (runtime.debugMode) {
         logger.error("No response content");
       }
-      return;
+      // TODO: Verify that this is the correct response handling
+      return {
+        content: "No response.",
+        action: "IGNORE",
+      };
     }
 
     // prevent repetition
     const messageExists = state.recentMessagesData
-      .filter((m) => m.user_id === message.agentId)
+      .filter((m) => m.user_id === runtime.agentId)
       .slice(0, maxContinuesInARow + 1)
       .some((m) => m.content === message.content);
 
@@ -107,8 +111,7 @@ export default {
       }
 
       await runtime.messageManager.createMemory({
-        user_ids: user_ids!,
-        user_id: agentId!,
+        user_id: runtime.agentId,
         content: responseContent,
         room_id,
         embedding: embeddingZeroVector,
@@ -122,14 +125,13 @@ export default {
       state: State,
       responseContent: Content,
     ) => {
-      const { agentId, userIds, room_id } = message;
+      const { room_id } = message;
 
       responseContent.content = responseContent.content?.trim();
 
       if (responseContent.content) {
         await runtime.messageManager.createMemory({
-          user_ids: userIds!,
-          user_id: agentId!,
+          user_id: runtime.agentId,
           content: responseContent,
           room_id,
           embedding: embeddingZeroVector,
@@ -146,7 +148,7 @@ export default {
     // if so, then we should change the action to WAIT
     if (responseContent.action === "ELABORATE") {
       const agentMessages = state.recentMessagesData
-        .filter((m) => m.user_id === message.agentId)
+        .filter((m) => m.user_id === runtime.agentId)
         .map((m) => (m.content as Content).action);
 
       const lastMessages = agentMessages.slice(0, maxContinuesInARow);
@@ -221,7 +223,7 @@ export default {
         user: "{{user1}}",
         content: {
           content: "That it’s more about moments than things.",
-          action: "ELABORATE",
+          action: "WAIT",
         },
       },
       {
diff --git a/src/lib/adapters/sqlite.ts b/src/lib/adapters/sqlite.ts
new file mode 100644
index 0000000..d814043
--- /dev/null
+++ b/src/lib/adapters/sqlite.ts
@@ -0,0 +1,433 @@
+// File: /src/lib/database/SqliteDatabaseAdapter.ts
+import { type UUID } from "crypto";
+import { DatabaseAdapter } from "../database";
+import {
+  Actor,
+  GoalStatus,
+  type Goal,
+  type Memory,
+  type Relationship,
+  Account,
+} from "../types";
+
+import { Database } from "better-sqlite3";
+import { load } from "./sqlite/sqlite_vss";
+import { sqliteTables } from "./sqlite/sqliteTables";
+
+export class SqliteDatabaseAdapter extends DatabaseAdapter {
+  private db: Database;
+
+  constructor(db: Database) {
+    super();
+    this.db = db;
+    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<Account | null> {
+    const sql = "SELECT * FROM accounts WHERE id = ?";
+    const accounts = this.db.prepare(sql).get(userId) as Account[];
+    const account = accounts && accounts[0];
+    if (account) {
+      if (typeof account.details === "string") {
+        account.details = JSON.parse(account.details as unknown as string);
+      }
+    }
+    return account || null;
+  }
+
+  async createAccount(account: Account): Promise<void> {
+    const sql =
+      "INSERT INTO accounts (id, name, email, avatar_url, details) VALUES (?, ?, ?, ?, ?)";
+    this.db
+      .prepare(sql)
+      .run(
+        account.id,
+        account.name,
+        account.email,
+        account.avatar_url,
+        JSON.stringify(account.details),
+      );
+  }
+
+  async getActorDetails(params: { room_id: UUID }): Promise<Actor[]> {
+    const sql = "SELECT * FROM accounts WHERE id IN (?)";
+    return this.db.prepare(sql).all(params.room_id) as Actor[];
+  }
+
+  async createMemory(
+    memory: Memory,
+    tableName: string,
+    unique = false,
+  ): Promise<void> {
+    const sql = `INSERT INTO memories (id, type, content, embedding, user_id, room_id, \`unique\`) VALUES (?, ?, ?, ?, ?, ?, ?)`;
+    this.db.prepare(sql).run(
+      crypto.randomUUID(),
+      tableName,
+      JSON.stringify(memory.content), // stringify the content field
+      JSON.stringify(memory.embedding),
+      memory.user_id,
+      memory.room_id,
+      unique ? 1 : 0,
+    );
+  }
+
+  async searchMemories(params: {
+    tableName: string;
+    room_id: UUID;
+    embedding: number[];
+    match_threshold: number;
+    match_count: number;
+    unique: boolean;
+  }): Promise<Memory[]> {
+    const sql = `
+      SELECT *, (1 - vss_distance_l2(embedding, ?)) AS similarity
+      FROM memories
+      WHERE type = ? AND room_id = ?
+      AND vss_search(embedding, ?)
+      ORDER BY similarity DESC
+      LIMIT ?
+    `;
+    const queryParams = [
+      JSON.stringify(params.embedding),
+      params.tableName,
+      params.room_id,
+      JSON.stringify(params.embedding),
+      params.match_count,
+    ];
+
+    if (params.unique) {
+      // sql += " AND `unique` = 1";
+    }
+
+    const memories = this.db.prepare(sql).all(...queryParams) as (Memory & {
+      similarity: number;
+    })[];
+    return memories.map((memory) => ({
+      ...memory,
+      content: JSON.parse(memory.content as unknown as string),
+    }));
+  }
+
+  async searchMemoriesByEmbedding(
+    embedding: number[],
+    params: {
+      match_threshold?: number;
+      count?: number;
+      room_id?: UUID;
+      unique?: boolean;
+      tableName: string;
+    },
+  ): Promise<Memory[]> {
+    let sql = `
+      SELECT *, (1 - vss_distance_l2(embedding, ?)) AS similarity
+      FROM memories
+      WHERE type = ?
+      AND vss_search(embedding, ?)
+      ORDER BY similarity DESC
+    `;
+    const queryParams = [
+      JSON.stringify(embedding),
+      params.tableName,
+      JSON.stringify(embedding),
+    ];
+
+    if (params.room_id) {
+      // sql += " AND room_id = ?";
+      // queryParams.push(params.room_id);
+    }
+
+    if (params.unique) {
+      // sql += " AND `unique` = 1";
+    }
+
+    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,
+      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 *
+      FROM memories
+      WHERE type = ?
+      AND vss_search(${opts.query_field_name}, ?)
+      ORDER BY vss_search(${opts.query_field_name}, ?) DESC
+      LIMIT ?
+    `;
+    const memories = this.db
+      .prepare(sql)
+      .all(
+        opts.query_table_name,
+        opts.query_input,
+        opts.query_input,
+        opts.query_match_count,
+      ) as Memory[];
+
+    return memories.map((memory) => ({
+      embedding: JSON.parse(memory.embedding as unknown as string),
+      levenshtein_score: 0,
+    }));
+  }
+
+  async updateGoalStatus(params: {
+    goalId: UUID;
+    status: GoalStatus;
+  }): Promise<void> {
+    const sql = "UPDATE goals SET status = ? WHERE id = ?";
+    this.db.prepare(sql).run(params.status, params.goalId);
+  }
+
+  async log(params: {
+    body: { [key: string]: unknown };
+    user_id: UUID;
+    room_id: UUID;
+    type: string;
+  }): Promise<void> {
+    const sql =
+      "INSERT INTO logs (body, user_id, room_id, type) VALUES (?, ?, ?, ?)";
+    this.db
+      .prepare(sql)
+      .run(
+        JSON.stringify(params.body),
+        params.user_id,
+        params.room_id,
+        params.type,
+      );
+  }
+
+  async getMemories(params: {
+    room_id: UUID;
+    count?: number;
+    unique?: boolean;
+    tableName: string;
+  }): Promise<Memory[]> {
+    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 = ? AND room_id = ?`;
+
+    const queryParams = [params.tableName, params.room_id];
+
+    // if (params.unique) {
+    //   sql += " AND `unique` = 1";
+    // }
+
+    if (params.count) {
+      sql += " LIMIT ?";
+      queryParams.push(params.count.toString());
+    }
+
+    const memories = this.db.prepare(sql).all(...queryParams) as Memory[];
+
+    return memories.map((memory) => ({
+      ...memory,
+      content: JSON.parse(memory.content as unknown as string),
+    }));
+  }
+
+  async removeMemory(memoryId: UUID, tableName: string): Promise<void> {
+    const sql = `DELETE FROM memories WHERE type = ? AND id = ?`;
+    this.db.prepare(sql).run(tableName, memoryId);
+  }
+
+  async removeAllMemories(room_id: UUID, tableName: string): Promise<void> {
+    const sql = `DELETE FROM memories WHERE type = ? AND room_id = ?`;
+    this.db.prepare(sql).run(tableName, room_id);
+  }
+
+  async countMemories(
+    room_id: UUID,
+    unique = true,
+    tableName = "",
+  ): Promise<number> {
+    if (!tableName) {
+      throw new Error("tableName is required");
+    }
+
+    const sql = `SELECT COUNT(*) as count FROM memories WHERE type = ? AND room_id = ?`;
+    const queryParams = [tableName, room_id] as string[];
+
+    if (unique) {
+      // TODO
+      // sql += " AND `unique` = 1";
+    }
+
+    return (this.db.prepare(sql).get(...queryParams) as { count: number })
+      .count;
+  }
+
+  async getGoals(params: {
+    room_id: UUID;
+    userId?: UUID | null;
+    onlyInProgress?: boolean;
+    count?: number;
+  }): Promise<Goal[]> {
+    let sql = "SELECT * FROM goals WHERE room_id = ?";
+    const queryParams = [params.room_id];
+
+    if (params.userId) {
+      sql += " AND user_id = ?";
+      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<void> {
+    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<void> {
+    const sql =
+      "INSERT INTO goals (id, room_id, user_id, name, status, objectives) VALUES (?, ?, ?, ?, ?, ?)";
+    this.db
+      .prepare(sql)
+      .run(
+        goal.id,
+        goal.room_id,
+        goal.user_id,
+        goal.name,
+        goal.status,
+        JSON.stringify(goal.objectives),
+      );
+  }
+
+  async removeGoal(goalId: UUID): Promise<void> {
+    const sql = "DELETE FROM goals WHERE id = ?";
+    this.db.prepare(sql).run(goalId);
+  }
+
+  async removeAllGoals(room_id: UUID): Promise<void> {
+    const sql = "DELETE FROM goals WHERE room_id = ?";
+    this.db.prepare(sql).run(room_id);
+  }
+
+  async createRoom(name: string): Promise<UUID> {
+    const roomId = crypto.randomUUID();
+    try {
+      const sql = "INSERT INTO rooms (id, name) VALUES (?, ?)";
+      this.db.prepare(sql).run(roomId, name);
+    } catch (error) {
+      console.log("Error creating room", error);
+    }
+    return roomId as UUID;
+  }
+
+  async removeRoom(roomId: UUID): Promise<void> {
+    const sql = "DELETE FROM rooms WHERE id = ?";
+    this.db.prepare(sql).run(roomId);
+  }
+
+  async getRoomsByParticipant(userId: UUID): Promise<UUID[]> {
+    const sql = "SELECT room_id FROM participants WHERE user_id = ?";
+    const rows = this.db.prepare(sql).all(userId) as { room_id: string }[];
+    return rows.map((row) => row.room_id as UUID);
+  }
+
+  async getRoomsByParticipants(userIds: UUID[]): Promise<UUID[]> {
+    // 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);
+  }
+
+  async addParticipantToRoom(userId: UUID, roomId: UUID): Promise<void> {
+    const sql = "INSERT INTO participants (user_id, room_id) VALUES (?, ?)";
+    this.db.prepare(sql).run(userId, roomId);
+  }
+
+  async removeParticipantFromRoom(userId: UUID, roomId: UUID): Promise<void> {
+    const sql = "DELETE FROM participants WHERE user_id = ? AND room_id = ?";
+    this.db.prepare(sql).run(userId, roomId);
+  }
+
+  async createRelationship(params: {
+    userA: UUID;
+    userB: UUID;
+  }): Promise<boolean> {
+    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);
+    return true;
+  }
+
+  async getRelationship(params: {
+    userA: UUID;
+    userB: UUID;
+  }): Promise<Relationship | null> {
+    const sql =
+      "SELECT * FROM relationships WHERE (user_a = ? AND user_b = ?) OR (user_a = ? AND user_b = ?)";
+    return (
+      (this.db
+        .prepare(sql)
+        .get(
+          params.userA,
+          params.userB,
+          params.userB,
+          params.userA,
+        ) as Relationship) || null
+    );
+  }
+
+  async getRelationships(params: { userId: UUID }): Promise<Relationship[]> {
+    const sql = "SELECT * FROM relationships WHERE (user_a = ? OR user_b = ?)";
+    return this.db
+      .prepare(sql)
+      .all(params.userId, params.userId) as Relationship[];
+  }
+}
diff --git a/src/lib/adapters/sqlite/sqliteTables.ts b/src/lib/adapters/sqlite/sqliteTables.ts
new file mode 100644
index 0000000..4eb1ceb
--- /dev/null
+++ b/src/lib/adapters/sqlite/sqliteTables.ts
@@ -0,0 +1,93 @@
+export const sqliteTables = `
+PRAGMA foreign_keys=OFF;
+BEGIN TRANSACTION;
+
+-- Table: accounts
+CREATE TABLE IF NOT EXISTS "accounts" (
+    "id" TEXT PRIMARY KEY,
+    "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    "name" TEXT,
+    "email" TEXT NOT NULL UNIQUE,
+    "avatar_url" TEXT,
+    "details" TEXT DEFAULT '{}' CHECK(json_valid("details")) -- Ensuring details is a valid JSON field
+);
+
+-- Table: memories
+CREATE TABLE IF NOT EXISTS "memories" (
+    "id" TEXT PRIMARY KEY,
+    "type" TEXT NOT NULL,
+    "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    "content" TEXT NOT NULL,
+    "embedding" BLOB NOT NULL, -- TODO: EMBEDDING ARRAY, CONVERT TO BEST FORMAT FOR SQLITE-VSS (JSON?)
+    "user_id" TEXT,
+    "room_id" TEXT,
+    "unique" INTEGER DEFAULT 1 NOT NULL,
+    FOREIGN KEY ("user_id") REFERENCES "accounts"("id"),
+    FOREIGN KEY ("room_id") REFERENCES "rooms"("id")
+);
+
+-- Table: goals
+CREATE TABLE IF NOT EXISTS "goals" (
+    "id" TEXT PRIMARY KEY,
+    "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    "user_id" TEXT,
+    "name" TEXT,
+    "status" TEXT,
+    "description" TEXT,
+    "room_id" TEXT,
+    "objectives" TEXT DEFAULT '[]' NOT NULL CHECK(json_valid("objectives")) -- Ensuring objectives is a valid JSON array
+);
+
+-- Table: logs
+CREATE TABLE IF NOT EXISTS "logs" (
+    "id" TEXT PRIMARY KEY,
+    "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    "user_id" TEXT NOT NULL,
+    "body" TEXT NOT NULL,
+    "type" TEXT NOT NULL,
+    "room_id" TEXT NOT NULL
+);
+
+-- Table: participants
+CREATE TABLE IF NOT EXISTS "participants" (
+    "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    "user_id" TEXT,
+    "room_id" TEXT,
+    "id" TEXT PRIMARY KEY,
+    "last_message_read" TEXT,
+    FOREIGN KEY ("user_id") REFERENCES "accounts"("id"),
+    FOREIGN KEY ("room_id") REFERENCES "rooms"("id")
+);
+
+-- Table: relationships
+CREATE TABLE IF NOT EXISTS "relationships" (
+    "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    "user_a" TEXT NOT NULL,
+    "user_b" TEXT NOT NULL,
+    "status" "text",
+    "id" TEXT PRIMARY KEY,
+    "user_id" TEXT NOT NULL,
+    FOREIGN KEY ("user_a") REFERENCES "accounts"("id"),
+    FOREIGN KEY ("user_b") REFERENCES "accounts"("id"),
+    FOREIGN KEY ("user_id") REFERENCES "accounts"("id")
+);
+
+-- Table: rooms
+CREATE TABLE IF NOT EXISTS "rooms" (
+    "id" TEXT PRIMARY KEY,
+    "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    "created_by" TEXT,
+    "name" TEXT,
+    FOREIGN KEY ("created_by") REFERENCES "accounts"("id")
+);
+
+-- Index: relationships_id_key
+CREATE UNIQUE INDEX IF NOT EXISTS "relationships_id_key" ON "relationships" ("id");
+
+-- Index: memories_id_key
+CREATE UNIQUE INDEX IF NOT EXISTS "memories_id_key" ON "memories" ("id");
+
+-- Index: participants_id_key
+CREATE UNIQUE INDEX IF NOT EXISTS "participants_id_key" ON "participants" ("id");
+
+COMMIT;`;
diff --git a/src/lib/adapters/sqlite/sqlite_vss.ts b/src/lib/adapters/sqlite/sqlite_vss.ts
new file mode 100644
index 0000000..0139a47
--- /dev/null
+++ b/src/lib/adapters/sqlite/sqlite_vss.ts
@@ -0,0 +1,94 @@
+import { statSync } from "fs";
+import { join } from "path";
+import { arch, platform } from "process";
+
+// TypeScript definitions
+export interface Database {
+  loadExtension(file: string, entrypoint?: string | undefined): void;
+}
+
+const supportedPlatforms: [string, string][] = [
+  ["darwin", "x64"],
+  ["darwin", "arm64"],
+  ["linux", "x64"],
+];
+
+function validPlatform(platform: string, arch: string): boolean {
+  return supportedPlatforms.some(([p, a]) => platform === p && arch === a);
+}
+
+function extensionSuffix(platform: string): string {
+  if (platform === "win32") return "dll";
+  if (platform === "darwin") return "dylib";
+  return "so";
+}
+
+function platformPackageName(platform: string, arch: string): string {
+  const os = platform === "win32" ? "windows" : platform;
+  return `sqlite-vss-${os}-${arch}`;
+}
+
+function loadablePathResolver(name: string): string {
+  if (!validPlatform(platform, arch)) {
+    throw new Error(
+      `Unsupported platform for sqlite-vss, on a ${platform}-${arch} machine, but not in supported platforms (${supportedPlatforms
+        .map(([p, a]) => `${p}-${a}`)
+        .join(",")}). Consult the sqlite-vss NPM package README for details.`,
+    );
+  }
+
+  const packageName = platformPackageName(platform, arch);
+  let loadablePath = join(
+    __dirname,
+    "..",
+    "..",
+    "..",
+    "..",
+    "node_modules",
+    packageName,
+    "lib",
+    `${name}.${extensionSuffix(platform)}`,
+  );
+
+  // if loadable path doesnt exist, check path2
+  if (!statSync(loadablePath, { throwIfNoEntry: false })) {
+    loadablePath = join(
+      __dirname,
+      "..",
+      "..",
+      "..",
+      packageName,
+      "lib",
+      `${name}.${extensionSuffix(platform)}`,
+    );
+  }
+
+  if (!statSync(loadablePath, { throwIfNoEntry: false })) {
+    throw new Error(
+      `Loadable extension for sqlite-vss not found. Was the ${packageName} package installed? Avoid using the --no-optional flag, as the optional dependencies for sqlite-vss are required.`,
+    );
+  }
+
+  return loadablePath;
+}
+
+export function getVectorLoadablePath(): string {
+  return loadablePathResolver("vector0");
+}
+
+export function getVssLoadablePath(): string {
+  return loadablePathResolver("vss0");
+}
+
+export function loadVector(db: Database): void {
+  db.loadExtension(getVectorLoadablePath());
+}
+
+export function loadVss(db: Database): void {
+  db.loadExtension(getVssLoadablePath());
+}
+
+export function load(db: Database): void {
+  loadVector(db);
+  loadVss(db);
+}
diff --git a/src/lib/adapters/supabase.ts b/src/lib/adapters/supabase.ts
index 6644916..23f09ea 100644
--- a/src/lib/adapters/supabase.ts
+++ b/src/lib/adapters/supabase.ts
@@ -8,7 +8,6 @@ import {
   Actor,
   GoalStatus,
   Account,
-  SimilaritySearch,
 } from "../types";
 import { DatabaseAdapter } from "../database";
 
@@ -32,45 +31,56 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter {
   }
 
   async createAccount(account: Account): Promise<void> {
-    const { error } = await this.supabase.from("accounts").insert([account]);
+    const { error } = await this.supabase.from("accounts").upsert([account]);
     if (error) {
       throw new Error(error.message);
     }
   }
 
-  async getActorDetails(params: { userIds: UUID[] }): Promise<Actor[]> {
+  async getActorDetails(params: { room_id: UUID }): Promise<Actor[]> {
     const response = await this.supabase
-      .from("accounts")
-      .select("*")
-      .in("id", params.userIds);
+      .from("rooms")
+      .select(
+        `
+        participants:participants!inner(
+          user_id:accounts(id, name, details)
+        )
+      `,
+      )
+      .eq("id", params.room_id);
+
     if (response.error) {
       console.error(response.error);
       return [];
     }
+
     const { data } = response;
-    return data.map((actor: Actor) => ({
-      name: actor.name,
-      details: actor.details,
-      id: actor.id,
-    }));
+
+    return data
+      .map((room) =>
+        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();
   }
 
   async searchMemories(params: {
     tableName: string;
-    userIds: UUID[];
+    room_id: UUID;
     embedding: number[];
     match_threshold: number;
     match_count: number;
     unique: boolean;
   }): Promise<Memory[]> {
-    console.log(
-      "searching memories",
-      params.tableName,
-      params.embedding.length,
-    );
     const result = await this.supabase.rpc("search_memories", {
       query_table_name: params.tableName,
-      query_user_ids: params.userIds,
+      query_room_id: params.room_id,
       query_embedding: params.embedding,
       query_match_threshold: params.match_threshold,
       query_match_count: params.match_count,
@@ -82,14 +92,19 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter {
     return result.data;
   }
 
-  async getMemoryByContent(opts: {
+  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<SimilaritySearch[]> {
+  }): Promise<
+    {
+      embedding: number[];
+      levenshtein_score: number;
+    }[]
+  > {
     const result = await this.supabase.rpc("get_embedding_list", opts);
     if (result.error) {
       throw new Error(JSON.stringify(result.error));
@@ -111,16 +126,12 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter {
     body: { [key: string]: unknown };
     user_id: UUID;
     room_id: UUID;
-    user_ids: UUID[];
-    agent_id: UUID;
     type: string;
   }): Promise<void> {
     const { error } = await this.supabase.from("logs").insert({
       body: params.body,
       user_id: params.user_id,
       room_id: params.room_id,
-      user_ids: params.user_ids,
-      agent_id: params.agent_id,
       type: params.type,
     });
 
@@ -130,15 +141,15 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter {
     }
   }
 
-  async getMemoriesByIds(params: {
-    userIds: UUID[];
+  async getMemories(params: {
+    room_id: UUID;
     count?: number;
     unique?: boolean;
     tableName: string;
   }): Promise<Memory[]> {
     const result = await this.supabase.rpc("get_memories", {
       query_table_name: params.tableName,
-      query_user_ids: params.userIds,
+      query_room_id: params.room_id,
       query_count: params.count,
       query_unique: !!params.unique,
     });
@@ -147,7 +158,7 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter {
     }
     if (!result.data) {
       console.warn("data was null, no memories found for", {
-        userIds: params.userIds,
+        room_id: params.room_id,
         count: params.count,
       });
       return [];
@@ -160,14 +171,14 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter {
     params: {
       match_threshold?: number;
       count?: number;
-      userIds?: UUID[];
+      room_id?: UUID;
       unique?: boolean;
       tableName: string;
     },
   ): Promise<Memory[]> {
     const result = await this.supabase.rpc("search_memories", {
       query_table_name: params.tableName,
-      query_user_ids: params.userIds,
+      query_room_id: params.room_id,
       query_embedding: embedding,
       query_match_threshold: params.match_threshold,
       query_match_count: params.count,
@@ -188,7 +199,6 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter {
       const opts = {
         query_table_name: tableName,
         query_user_id: memory.user_id,
-        query_user_ids: memory.user_ids,
         query_content: memory.content.content,
         query_room_id: memory.room_id,
         query_embedding: memory.embedding,
@@ -204,7 +214,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));
@@ -212,9 +224,9 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter {
     }
   }
 
-  async removeMemory(memoryId: UUID, tableName: string): Promise<void> {
+  async removeMemory(memoryId: UUID): Promise<void> {
     const result = await this.supabase
-      .from(tableName)
+      .from("memories")
       .delete()
       .eq("id", memoryId);
     const { error } = result;
@@ -223,13 +235,13 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter {
     }
   }
 
-  async removeAllMemoriesByUserIds(
-    userIds: UUID[],
+  async removeAllMemories(
+    room_id: UUID,
     tableName: string,
   ): Promise<void> {
     const result = await this.supabase.rpc("remove_memories", {
       query_table_name: tableName,
-      query_user_ids: userIds,
+      query_room_id: room_id,
     });
 
     if (result.error) {
@@ -237,8 +249,8 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter {
     }
   }
 
-  async countMemoriesByUserIds(
-    userIds: UUID[],
+  async countMemories(
+    room_id: UUID,
     unique = true,
     tableName: string,
   ): Promise<number> {
@@ -247,7 +259,7 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter {
     }
     const query = {
       query_table_name: tableName,
-      query_user_ids: userIds,
+      query_room_id: room_id,
       query_unique: !!unique,
     };
     const result = await this.supabase.rpc("count_memories", query);
@@ -260,21 +272,19 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter {
   }
 
   async getGoals(params: {
-    userIds: UUID[];
+    room_id: UUID;
     userId?: UUID | null;
     onlyInProgress?: boolean;
     count?: number;
   }): Promise<Goal[]> {
     const opts = {
-      query_user_ids: params.userIds,
+      query_room_id: params.room_id,
       query_user_id: params.userId,
       only_in_progress: params.onlyInProgress,
       row_count: params.count,
     };
-    const { data: goals, error } = await this.supabase.rpc(
-      "get_goals_by_user_ids",
-      opts,
-    );
+
+    const { data: goals, error } = await this.supabase.rpc("get_goals", opts);
 
     if (error) {
       throw new Error(error.message);
@@ -291,18 +301,170 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter {
     await this.supabase.from("goals").upsert(goal);
   }
 
+  async removeGoal(goalId: UUID): Promise<void> {
+    const { error } = await this.supabase
+      .from("goals")
+      .delete()
+      .eq("id", goalId);
+    if (error) {
+      throw new Error(`Error removing goal: ${error.message}`);
+    }
+  }
+
+  async removeAllGoals(room_id: UUID): Promise<void> {
+    const { error } = await this.supabase
+      .from("goals")
+      .delete()
+      .eq("room_id", room_id);
+    if (error) {
+      throw new Error(`Error removing goals: ${error.message}`);
+    }
+  }
+
+  async getRoomsByParticipant(userId: UUID): Promise<UUID[]> {
+    const { data, error } = await this.supabase
+      .from("participants")
+      .select("room_id")
+      .eq("user_id", userId);
+
+    if (error) {
+      throw new Error(`Error getting rooms by participant: ${error.message}`);
+    }
+
+    return data.map((row) => row.room_id as UUID);
+  }
+
+  async getRoomsByParticipants(userIds: UUID[]): Promise<UUID[]> {
+    const { data, error } = await this.supabase
+      .from("participants")
+      .select("room_id")
+      .in("user_id", userIds);
+
+    if (error) {
+      throw new Error(`Error getting rooms by participants: ${error.message}`);
+    }
+
+    return [...new Set(data.map((row) => row.room_id as UUID))];
+  }
+
+  async createRoom(name: string): Promise<UUID> {
+    const { data, error } = (await this.supabase
+      .from("rooms")
+      .upsert({ name })
+      .single()) as { data: { id: UUID } | null; error: Error | null };
+
+    if (error) {
+      throw new Error(`Error creating room: ${error.message}`);
+    }
+
+    if (!data) {
+      throw new Error("No data returned from room creation");
+    }
+
+    return data.id;
+  }
+
+  async removeRoom(roomId: UUID): Promise<void> {
+    const { error } = await this.supabase
+      .from("rooms")
+      .delete()
+      .eq("id", roomId);
+
+    if (error) {
+      throw new Error(`Error removing room: ${error.message}`);
+    }
+  }
+
+  async addParticipantToRoom(userId: UUID, roomId: UUID): Promise<void> {
+    const { error } = await this.supabase
+      .from("participants")
+      .insert({ user_id: userId, room_id: roomId });
+
+    if (error) {
+      throw new Error(`Error adding participant: ${error.message}`);
+    }
+  }
+
+  async removeParticipantFromRoom(userId: UUID, roomId: UUID): Promise<void> {
+    const { error } = await this.supabase
+      .from("participants")
+      .delete()
+      .eq("user_id", userId)
+      .eq("room_id", roomId);
+
+    if (error) {
+      throw new Error(`Error removing participant: ${error.message}`);
+    }
+  }
+
   async createRelationship(params: {
     userA: UUID;
     userB: UUID;
   }): Promise<boolean> {
-    const { error } = await this.supabase.from("relationships").upsert({
-      user_a: params.userA,
-      user_b: params.userB,
-      user_id: params.userA,
-    });
+    // check for room with values name: `Room for ${params.userA} and ${params.userB}`, created_by: params.userA,
+    const { data: allRoomData, error: allRoomsError } = await this.supabase
+      .from("rooms")
+      .select("id")
+      .eq("name", `Room for ${params.userA} and ${params.userB}`)
+      .eq("created_by", params.userA);
+
+    if (allRoomsError) {
+      throw new Error("All rooms error: " + allRoomsError.message);
+    }
+
+    if (!allRoomData || allRoomData.length === 0) {
+      const { error: roomsError } = await this.supabase
+        .from("rooms")
+        .insert({
+          name: `Room for ${params.userA} and ${params.userB}`,
+          created_by: params.userA,
+        })
+        .eq("name", `Room for ${params.userA} and ${params.userB}`);
+
+      if (roomsError) {
+        throw new Error("Room error: " + roomsError.message);
+      }
+    }
+
+    // get the room_id from the room creation
+    const { data, error: roomError } = await this.supabase
+      .from("rooms")
+      .select("id")
+      .eq("name", `Room for ${params.userA} and ${params.userB}`)
+      .single();
+
+    if (roomError) {
+      throw new Error("Room error: " + roomError.message);
+    }
+
+    const room_id = data.id as UUID;
+    if (!room_id) {
+      throw new Error("Room not found");
+    }
+    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,
+        status: "FRIENDS",
+      })
+      .eq("user_a", params.userA)
+      .eq("user_b", params.userB);
 
     if (error) {
-      throw new Error(error.message);
+      throw new Error("Relationship error: " + error.message);
     }
 
     return true;
diff --git a/src/lib/database.ts b/src/lib/database.ts
index b0cf143..2daf12f 100644
--- a/src/lib/database.ts
+++ b/src/lib/database.ts
@@ -1,26 +1,26 @@
 import { type UUID } from "crypto";
 import {
-  type Memory,
-  type Goal,
-  type Relationship,
+  Account,
   Actor,
   GoalStatus,
-  Account,
-  SimilaritySearch,
+  type Goal,
+  type Memory,
+  type Relationship,
 } from "./types";
 
 export abstract class DatabaseAdapter {
   abstract getAccountById(userId: UUID): Promise<Account | null>;
+
   abstract createAccount(account: Account): Promise<void>;
 
-  abstract getMemoriesByIds(params: {
-    userIds: UUID[];
+  abstract getMemories(params: {
+    room_id: UUID;
     count?: number;
     unique?: boolean;
     tableName: string;
   }): Promise<Memory[]>;
 
-  abstract getMemoryByContent({
+  abstract getCachedEmbeddings({
     query_table_name,
     query_threshold,
     query_input,
@@ -34,27 +34,31 @@ export abstract class DatabaseAdapter {
     query_field_name: string;
     query_field_sub_name: string;
     query_match_count: number;
-  }): Promise<SimilaritySearch[]>;
+  }): Promise<
+    {
+      embedding: number[];
+      levenshtein_score: number;
+    }[]
+  >;
 
   abstract log(params: {
     body: { [key: string]: unknown };
     user_id: UUID;
     room_id: UUID;
-    user_ids: UUID[];
-    agent_id: UUID;
     type: string;
   }): Promise<void>;
 
-  abstract getActorDetails(params: { userIds: UUID[] }): Promise<Actor[]>;
+  abstract getActorDetails(params: { room_id: UUID }): Promise<Actor[]>;
 
   abstract searchMemories(params: {
     tableName: string;
-    userIds: UUID[];
+    room_id: UUID;
     embedding: number[];
     match_threshold: number;
     match_count: number;
     unique: boolean;
   }): Promise<Memory[]>;
+
   abstract updateGoalStatus(params: {
     goalId: UUID;
     status: GoalStatus;
@@ -65,7 +69,7 @@ export abstract class DatabaseAdapter {
     params: {
       match_threshold?: number;
       count?: number;
-      userIds?: UUID[];
+      room_id?: UUID;
       unique?: boolean;
       tableName: string;
     },
@@ -79,19 +83,16 @@ export abstract class DatabaseAdapter {
 
   abstract removeMemory(memoryId: UUID, tableName: string): Promise<void>;
 
-  abstract removeAllMemoriesByUserIds(
-    userIds: UUID[],
-    tableName: string,
-  ): Promise<void>;
+  abstract removeAllMemories(room_id: UUID, tableName: string): Promise<void>;
 
-  abstract countMemoriesByUserIds(
-    userIds: UUID[],
+  abstract countMemories(
+    room_id: UUID,
     unique?: boolean,
     tableName?: string,
   ): Promise<number>;
 
   abstract getGoals(params: {
-    userIds: UUID[];
+    room_id: UUID;
     userId?: UUID | null;
     onlyInProgress?: boolean;
     count?: number;
@@ -101,6 +102,22 @@ export abstract class DatabaseAdapter {
 
   abstract createGoal(goal: Goal): Promise<void>;
 
+  abstract removeGoal(goalId: UUID): Promise<void>;
+
+  abstract removeAllGoals(room_id: UUID): Promise<void>;
+
+  abstract createRoom(name: string): Promise<UUID>;
+
+  abstract removeRoom(roomId: UUID): Promise<void>;
+
+  abstract getRoomsByParticipant(userId: UUID): Promise<UUID[]>;
+
+  abstract getRoomsByParticipants(userIds: UUID[]): Promise<UUID[]>;
+
+  abstract addParticipantToRoom(userId: UUID, roomId: UUID): Promise<void>;
+
+  abstract removeParticipantFromRoom(userId: UUID, roomId: UUID): Promise<void>;
+
   abstract createRelationship(params: {
     userA: UUID;
     userB: UUID;
diff --git a/src/lib/evaluators/__tests__/fact.test.ts b/src/lib/evaluators/__tests__/fact.test.ts
index a9511d8..34861af 100644
--- a/src/lib/evaluators/__tests__/fact.test.ts
+++ b/src/lib/evaluators/__tests__/fact.test.ts
@@ -1,29 +1,29 @@
-import { type User } from "@supabase/supabase-js";
 import { type UUID } from "crypto";
 import dotenv from "dotenv";
+import { getCachedEmbeddings, writeCachedEmbedding } from "../../../test/cache";
+import { createRuntime } from "../../../test/createRuntime";
 import {
   GetTellMeAboutYourselfConversation1,
   GetTellMeAboutYourselfConversation2,
   GetTellMeAboutYourselfConversation3,
   jimFacts,
 } from "../../../test/data";
+import { getOrCreateRelationship } from "../../../test/getOrCreateRelationship";
 import { populateMemories } from "../../../test/populateMemories";
-import { getRelationship } from "../../relationships";
-import { type BgentRuntime } from "../../runtime";
-import { createRuntime } from "../../../test/createRuntime";
 import { runAiTest } from "../../../test/runAiTest";
-import evaluator from "../fact";
-import { type Message } from "../../types";
-import { getCachedEmbedding, writeCachedEmbedding } from "../../../test/cache";
+import { type User } from "../../../test/types";
 import { defaultActions } from "../../actions";
 import { zeroUuid } from "../../constants";
+import { type BgentRuntime } from "../../runtime";
+import { type Message } from "../../types";
+import evaluator from "../fact";
 
 dotenv.config({ path: ".dev.vars" });
 
 describe("Facts Evaluator", () => {
   let user: User;
   let runtime: BgentRuntime;
-  let room_id: UUID;
+  let room_id = zeroUuid;
 
   beforeAll(async () => {
     const setup = await createRuntime({
@@ -34,7 +34,11 @@ describe("Facts Evaluator", () => {
     user = setup.session.user;
     runtime = setup.runtime;
 
-    const data = await getRelationship({
+    if (!user.id) {
+      throw new Error("User ID is undefined");
+    }
+
+    const data = await getOrCreateRelationship({
       runtime,
       userA: user.id as UUID,
       userB: zeroUuid,
@@ -58,9 +62,7 @@ describe("Facts Evaluator", () => {
       ]);
 
       const message: Message = {
-        senderId: user.id as UUID,
-        agentId: zeroUuid,
-        userIds: [user.id as UUID, zeroUuid],
+        userId: user.id as UUID,
         content: { content: "" },
         room_id,
       };
@@ -83,9 +85,7 @@ describe("Facts Evaluator", () => {
       await addFacts(runtime, user.id as UUID, room_id, jimFacts);
 
       const message: Message = {
-        senderId: user.id as UUID,
-        agentId: zeroUuid,
-        userIds: [user.id as UUID, zeroUuid],
+        userId: user.id as UUID,
         content: { content: "" },
         room_id,
       };
@@ -102,9 +102,9 @@ describe("Facts Evaluator", () => {
   }, 120000); // Adjust the timeout as needed for your tests
 });
 
-async function cleanup(runtime: BgentRuntime, userId: UUID) {
-  await runtime.factManager.removeAllMemoriesByUserIds([userId, zeroUuid]);
-  await runtime.messageManager.removeAllMemoriesByUserIds([userId, zeroUuid]);
+async function cleanup(runtime: BgentRuntime, room_id: UUID) {
+  await runtime.factManager.removeAllMemories(room_id);
+  await runtime.messageManager.removeAllMemories(room_id);
 }
 
 async function addFacts(
@@ -114,10 +114,9 @@ async function addFacts(
   facts: string[],
 ) {
   for (const fact of facts) {
-    const existingEmbedding = getCachedEmbedding(fact);
+    const existingEmbedding = getCachedEmbeddings(fact);
     const bakedMemory = await runtime.factManager.addEmbeddingToMemory({
       user_id: userId,
-      user_ids: [userId, zeroUuid],
       content: { content: fact },
       room_id: room_id,
       embedding: existingEmbedding,
diff --git a/src/lib/evaluators/__tests__/goal.test.ts b/src/lib/evaluators/__tests__/goal.test.ts
index ea845a5..0a7bb10 100644
--- a/src/lib/evaluators/__tests__/goal.test.ts
+++ b/src/lib/evaluators/__tests__/goal.test.ts
@@ -1,16 +1,16 @@
-import { type User } from "@supabase/supabase-js";
 import { type UUID } from "crypto";
 import dotenv from "dotenv";
 import { createRuntime } from "../../../test/createRuntime";
+import { getOrCreateRelationship } from "../../../test/getOrCreateRelationship";
 import { populateMemories } from "../../../test/populateMemories";
+import { runAiTest } from "../../../test/runAiTest";
+import { type User } from "../../../test/types";
+import { defaultActions } from "../../actions";
+import { zeroUuid } from "../../constants";
 import { createGoal, getGoals } from "../../goals";
-import { getRelationship } from "../../relationships";
 import { type BgentRuntime } from "../../runtime";
-import { Goal, GoalStatus, Objective, type Message, State } from "../../types";
+import { Goal, GoalStatus, Objective, State, type Message } from "../../types";
 import evaluator from "../goal";
-import { defaultActions } from "../../actions";
-import { zeroUuid } from "../../constants";
-import { runAiTest } from "../../../test/runAiTest";
 
 dotenv.config({ path: ".dev.vars" });
 
@@ -28,7 +28,7 @@ describe("Goals Evaluator", () => {
     user = setup.session.user;
     runtime = setup.runtime;
 
-    const data = await getRelationship({
+    const data = await getOrCreateRelationship({
       runtime,
       userA: user.id as UUID,
       userB: zeroUuid,
@@ -49,10 +49,7 @@ describe("Goals Evaluator", () => {
 
   async function cleanup() {
     // delete all goals for the user
-    await runtime.databaseAdapter.removeAllMemoriesByUserIds(
-      [user.id as UUID],
-      "goals",
-    );
+    await runtime.databaseAdapter.removeAllMemories(room_id, "goals");
   }
 
   async function createTestGoal(name: string, objectives: Objective[]) {
@@ -61,7 +58,7 @@ describe("Goals Evaluator", () => {
       goal: {
         name,
         status: GoalStatus.IN_PROGRESS,
-        user_ids: [user.id as UUID, zeroUuid],
+        room_id,
         user_id: user.id as UUID,
         objectives,
       },
@@ -98,9 +95,7 @@ describe("Goals Evaluator", () => {
 
         // Simulate a conversation indicating the completion of both objectives
         const message: Message = {
-          agentId: zeroUuid,
-          senderId: user.id as UUID,
-          userIds: [user.id as UUID, zeroUuid],
+          userId: user.id as UUID,
           content: {
             content:
               "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.",
@@ -116,7 +111,7 @@ describe("Goals Evaluator", () => {
         // Fetch the updated goal to verify the objectives and status were updated
         const updatedGoals = await getGoals({
           runtime,
-          userIds: [user.id as UUID, zeroUuid],
+          room_id,
           onlyInProgress: false,
         });
 
@@ -160,9 +155,7 @@ describe("Goals Evaluator", () => {
         await populateMemories(runtime, user, room_id, [conversation]);
 
         const message: Message = {
-          senderId: user.id as UUID,
-          agentId: zeroUuid,
-          userIds: [user.id as UUID, zeroUuid],
+          userId: user.id as UUID,
           content: { content: "I've decided to mark Goal Y as failed." },
           room_id,
         };
@@ -173,7 +166,7 @@ describe("Goals Evaluator", () => {
 
         const goals = await getGoals({
           runtime,
-          userIds: [user.id as UUID, zeroUuid],
+          room_id,
           onlyInProgress: false,
         });
 
diff --git a/src/lib/evaluators/fact.ts b/src/lib/evaluators/fact.ts
index 87d7ed9..a652b32 100644
--- a/src/lib/evaluators/fact.ts
+++ b/src/lib/evaluators/fact.ts
@@ -58,7 +58,7 @@ Response should be a JSON object array inside a JSON markdown block. Correct res
 async function handler(runtime: BgentRuntime, message: Message) {
   const state = await runtime.composeState(message);
 
-  const { userIds, agentId, room_id } = state;
+  const { agentId, room_id } = state;
 
   const context = composeContext({
     state,
@@ -110,7 +110,6 @@ async function handler(runtime: BgentRuntime, message: Message) {
 
   for (const fact of filteredFacts) {
     const factMemory = await runtime.factManager.addEmbeddingToMemory({
-      user_ids: userIds,
       user_id: agentId!,
       content: { content: fact },
       room_id,
@@ -131,8 +130,8 @@ export default {
     // eslint-disable-next-line @typescript-eslint/no-unused-vars
     message: Message,
   ): Promise<boolean> => {
-    const messageCount = (await runtime.messageManager.countMemoriesByUserIds(
-      message.userIds,
+    const messageCount = (await runtime.messageManager.countMemories(
+      message.room_id,
     )) as number;
 
     const reflectionCount = Math.ceil(runtime.getRecentMessageCount() / 2);
diff --git a/src/lib/evaluators/goal.ts b/src/lib/evaluators/goal.ts
index e1680e3..d9aaec6 100644
--- a/src/lib/evaluators/goal.ts
+++ b/src/lib/evaluators/goal.ts
@@ -50,7 +50,7 @@ async function handler(
   // get goals
   let goalsData = await getGoals({
     runtime,
-    userIds: message.userIds,
+    room_id: message.room_id,
     onlyInProgress: options.onlyInProgress as boolean,
   });
 
@@ -72,7 +72,7 @@ async function handler(
   // get goals
   goalsData = await getGoals({
     runtime,
-    userIds: message.userIds,
+    room_id: message.room_id,
     onlyInProgress: true,
   });
 
@@ -129,7 +129,7 @@ export default {
       runtime,
       count: 1,
       onlyInProgress: true,
-      userIds: message.userIds,
+      room_id: message.room_id,
     });
     return goals.length > 0;
   },
diff --git a/src/lib/goals.ts b/src/lib/goals.ts
index b3fd355..deb9a72 100644
--- a/src/lib/goals.ts
+++ b/src/lib/goals.ts
@@ -4,19 +4,19 @@ import { type Goal, type Objective } from "./types";
 
 export const getGoals = async ({
   runtime,
-  userIds,
+  room_id,
   userId,
   onlyInProgress = true,
   count = 5,
 }: {
   runtime: BgentRuntime;
-  userIds: UUID[];
+  room_id: UUID;
   userId?: UUID;
   onlyInProgress?: boolean;
   count?: number;
 }) => {
   return runtime.databaseAdapter.getGoals({
-    userIds,
+    room_id,
     userId,
     onlyInProgress,
     count,
diff --git a/src/lib/index.ts b/src/lib/index.ts
index e5b1ba5..9358746 100644
--- a/src/lib/index.ts
+++ b/src/lib/index.ts
@@ -1,33 +1,33 @@
 // Export from ./src/actions
 export {
-  defaultActions,
   composeActionExamples,
-  getFormattedActions,
+  defaultActions,
+  formatActionConditions,
   formatActionNames,
   formatActions,
-  formatActionConditions,
+  getFormattedActions,
 } from "./actions";
 
 // Export from ./src/context
-export { composeContext, addHeader } from "./context";
+export { addHeader, composeContext } from "./context";
 
 // Export from ./src/evaluators
 export {
   defaultEvaluators,
   evaluationTemplate,
-  formatEvaluatorNames,
-  formatEvaluators,
   formatEvaluatorConditions,
-  formatEvaluatorExamples,
   formatEvaluatorExampleConditions,
   formatEvaluatorExampleDescriptions,
+  formatEvaluatorExamples,
+  formatEvaluatorNames,
+  formatEvaluators,
 } from "./evaluators";
 
 // Export from ./src/goals
-export { getGoals, formatGoalsAsString, updateGoal, createGoal } from "./goals";
+export { createGoal, formatGoalsAsString, getGoals, updateGoal } from "./goals";
 
 // Export from ./src/lore
-export { addLore, getLore, formatLore } from "./lore";
+export { addLore, formatLore, getLore } from "./lore";
 
 // Export from ./src/memory
 export {
@@ -37,7 +37,7 @@ export {
 } from "./memory";
 
 // Export from ./src/messages
-export { getActorDetails, formatActors, formatMessages } from "./messages";
+export { formatActors, formatMessages, getActorDetails } from "./messages";
 
 // Export from ./src/providers
 export { defaultProviders, getProviders } from "./providers";
@@ -45,13 +45,14 @@ export { defaultProviders, getProviders } from "./providers";
 // Export from ./src/relationships
 export {
   createRelationship,
+  formatRelationships,
   getRelationship,
   getRelationships,
-  formatRelationships,
 } from "./relationships";
 
-export { DatabaseAdapter } from "./database";
 export { SupabaseDatabaseAdapter } from "./adapters/supabase";
+export { SqliteDatabaseAdapter } from "./adapters/sqlite";
+export { DatabaseAdapter } from "./database";
 
 // Export from ./src/runtime
 export { BgentRuntime } from "./runtime";
@@ -62,24 +63,25 @@ export { messageHandlerTemplate } from "./templates";
 // Export from ./src/types
 export { GoalStatus } from "./types";
 export type {
-  Content,
+  Account,
+  Action,
   ActionExample,
-  ConversationExample,
   Actor,
-  Memory,
-  Objective,
+  Content,
+  ConversationExample,
+  EvaluationExample,
+  Evaluator,
   Goal,
-  State,
+  Handler,
+  Memory,
   Message,
   MessageExample,
-  Handler,
-  Validator,
-  Action,
-  EvaluationExample,
-  Evaluator,
+  Objective,
   Provider,
   Relationship,
+  State,
+  Validator,
 } from "./types";
 
 // Export from ./src/utils
-export { parseJsonArrayFromText, parseJSONObjectFromText } from "./utils";
+export { parseJSONObjectFromText, parseJsonArrayFromText } from "./utils";
diff --git a/src/lib/lore.ts b/src/lib/lore.ts
index 43814b4..783ddaf 100644
--- a/src/lib/lore.ts
+++ b/src/lib/lore.ts
@@ -36,13 +36,17 @@ export async function addLore({
     ? await runtime.embed(embedContent.content)
     : await runtime.embed(content.content);
 
-  await loreManager.createMemory({
-    user_id,
-    user_ids: [user_id],
-    content: { content: content.content, source },
-    room_id,
-    embedding: embedding,
-  });
+  try {
+    await loreManager.createMemory({
+      user_id,
+      content: { content: content.content, source },
+      room_id,
+      embedding: embedding,
+    });
+  } catch (e) {
+    console.error("Error adding lore", e);
+    throw e;
+  }
 }
 
 /**
@@ -59,17 +63,19 @@ export async function getLore({
   runtime,
   message,
   match_threshold,
+  room_id = zeroUuid,
   count,
 }: {
   runtime: BgentRuntime;
   message: string;
   match_threshold?: number;
+  room_id?: UUID;
   count?: number;
 }) {
   const loreManager = runtime.loreManager;
   const embedding = await runtime.embed(message);
   const lore = await loreManager.searchMemoriesByEmbedding(embedding, {
-    userIds: [zeroUuid],
+    room_id,
     match_threshold,
     count,
   });
diff --git a/src/lib/memory.ts b/src/lib/memory.ts
index a781f6a..ae1196c 100644
--- a/src/lib/memory.ts
+++ b/src/lib/memory.ts
@@ -1,6 +1,6 @@
 import { type UUID } from "crypto";
 import { type BgentRuntime } from "./runtime";
-import { type Memory, type SimilaritySearch } from "./types";
+import { type Memory } from "./types";
 
 export const embeddingDimension = 1536;
 export const embeddingZeroVector = Array(embeddingDimension).fill(0);
@@ -60,22 +60,22 @@ export class MemoryManager {
   /**
    * Retrieves a list of memories by user IDs, with optional deduplication.
    * @param opts Options including user IDs, count, and uniqueness.
-   * @param opts.userIds An array of user IDs to retrieve memories for.
+   * @param opts.room_id The room ID to retrieve memories for.
    * @param opts.count The number of memories to retrieve.
    * @param opts.unique Whether to retrieve unique memories only.
    * @returns A Promise resolving to an array of Memory objects.
    */
-  async getMemoriesByIds({
-    userIds,
+  async getMemories({
+    room_id,
     count = 10,
     unique = true,
   }: {
-    userIds: UUID[];
+    room_id: UUID;
     count?: number;
     unique?: boolean;
   }): Promise<Memory[]> {
-    const result = await this.runtime.databaseAdapter.getMemoriesByIds({
-      userIds,
+    const result = await this.runtime.databaseAdapter.getMemories({
+      room_id,
       count,
       unique,
       tableName: this.tableName,
@@ -83,8 +83,13 @@ export class MemoryManager {
     return result;
   }
 
-  async getMemoryByContent(content: string): Promise<SimilaritySearch[]> {
-    const result = await this.runtime.databaseAdapter.getMemoryByContent({
+  async getCachedEmbeddings(content: string): Promise<
+    {
+      embedding: number[];
+      levenshtein_score: number;
+    }[]
+  > {
+    const result = await this.runtime.databaseAdapter.getCachedEmbeddings({
       query_table_name: this.tableName,
       query_threshold: 2,
       query_input: content,
@@ -101,7 +106,7 @@ export class MemoryManager {
    * @param opts Options including match threshold, count, user IDs, and uniqueness.
    * @param opts.match_threshold The similarity threshold for matching memories.
    * @param opts.count The maximum number of memories to retrieve.
-   * @param opts.userIds An array of user IDs to retrieve memories for.
+   * @param opts.room_id The room ID to retrieve memories for.
    * @param opts.unique Whether to retrieve unique memories only.
    * @returns A Promise resolving to an array of Memory objects that match the embedding.
    */
@@ -110,32 +115,28 @@ export class MemoryManager {
     opts: {
       match_threshold?: number;
       count?: number;
-      userIds?: UUID[];
+      room_id: UUID;
       unique?: boolean;
     },
   ): Promise<Memory[]> {
     const {
       match_threshold = defaultMatchThreshold,
       count = defaultMatchCount,
-      userIds = [],
+      room_id,
       unique,
     } = opts;
 
-    console.log("embedding length to search is", embedding.length);
-
-    console.log("opts are", opts);
-    console.log(opts);
-
-    const result = await this.runtime.databaseAdapter.searchMemories({
+    const searchOpts = {
       tableName: this.tableName,
-      userIds: userIds,
+      room_id,
       embedding: embedding,
       match_threshold: match_threshold,
       match_count: count,
       unique: !!unique,
-    });
+    };
 
-    console.log("result.embedding.length", result[0]?.embedding?.length);
+    const result =
+      await this.runtime.databaseAdapter.searchMemories(searchOpts);
 
     return result;
   }
@@ -165,28 +166,25 @@ export class MemoryManager {
 
   /**
    * Removes all memories associated with a set of user IDs.
-   * @param userIds An array of user IDs to remove memories for.
+   * @param room_id The room ID to remove memories for.
    * @returns A Promise that resolves when the operation completes.
    */
-  async removeAllMemoriesByUserIds(userIds: UUID[]): Promise<void> {
-    await this.runtime.databaseAdapter.removeAllMemoriesByUserIds(
-      userIds,
+  async removeAllMemories(room_id: UUID): Promise<void> {
+    await this.runtime.databaseAdapter.removeAllMemories(
+      room_id,
       this.tableName,
     );
   }
 
   /**
    * Counts the number of memories associated with a set of user IDs, with an option for uniqueness.
-   * @param userIds An array of user IDs to count memories for.
+   * @param room_id The room ID to count memories for.
    * @param unique Whether to count unique memories only.
    * @returns A Promise resolving to the count of memories.
    */
-  async countMemoriesByUserIds(
-    userIds: UUID[],
-    unique = true,
-  ): Promise<number> {
-    return await this.runtime.databaseAdapter.countMemoriesByUserIds(
-      userIds,
+  async countMemories(room_id: UUID, unique = true): Promise<number> {
+    return await this.runtime.databaseAdapter.countMemories(
+      room_id,
       unique,
       this.tableName,
     );
diff --git a/src/lib/messages.ts b/src/lib/messages.ts
index 49a57a6..ce0b986 100644
--- a/src/lib/messages.ts
+++ b/src/lib/messages.ts
@@ -7,12 +7,12 @@ import { type Actor, type Content, type Memory } from "./types";
  */
 export async function getActorDetails({
   runtime,
-  userIds,
+  room_id,
 }: {
   runtime: BgentRuntime;
-  userIds: UUID[];
+  room_id: UUID;
 }) {
-  const actors = await runtime.databaseAdapter.getActorDetails({ userIds });
+  const actors = await runtime.databaseAdapter.getActorDetails({ room_id });
 
   return actors as Actor[];
 }
@@ -24,7 +24,7 @@ export async function getActorDetails({
  */
 export function formatActors({ actors }: { actors: Actor[] }) {
   const actorStrings = actors.map((actor: Actor) => {
-    const header = `${actor.name}${actor.details.tagline ? ": " + actor.details.tagline : ""}${actor.details?.summary ? "\n" + actor.details?.summary : ""}`;
+    const header = `${actor.name}${actor.details?.tagline ? ": " + actor.details?.tagline : ""}${actor.details?.summary ? "\n" + actor.details?.summary : ""}`;
     return header;
   });
   const finalActorStrings = actorStrings.join("\n");
diff --git a/src/lib/providers/__tests__/time.test.ts b/src/lib/providers/__tests__/time.test.ts
index 83b8ac2..4a49ff8 100644
--- a/src/lib/providers/__tests__/time.test.ts
+++ b/src/lib/providers/__tests__/time.test.ts
@@ -3,7 +3,6 @@ import dotenv from "dotenv";
 import { createRuntime } from "../../../test/createRuntime";
 import { composeContext } from "../../context";
 import { BgentRuntime } from "../../runtime";
-
 import { type Message, type State } from "../../types";
 import timeProvider from "../time";
 import { zeroUuid } from "../../constants";
@@ -22,14 +21,12 @@ 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 () => {
     const message: Message = {
-      senderId: user.id,
-      agentId: zeroUuid,
-      userIds: [user.id, zeroUuid],
+      userId: user.id,
       content: { content: "" },
       room_id: room_id,
     };
@@ -46,9 +43,7 @@ describe("Time Provider", () => {
 
   test("Time provider should be integrated in the state and context correctly", async () => {
     const message: Message = {
-      senderId: user.id,
-      agentId: zeroUuid,
-      userIds: [user.id, zeroUuid],
+      userId: user.id,
       content: { content: "" },
       room_id: room_id,
     };
@@ -73,9 +68,7 @@ describe("Time Provider", () => {
 
   test("Time provider should work independently", async () => {
     const message: Message = {
-      senderId: user.id,
-      agentId: zeroUuid,
-      userIds: [user.id, zeroUuid],
+      userId: user.id,
       content: { content: "" },
       room_id: room_id,
     };
diff --git a/src/lib/runtime.ts b/src/lib/runtime.ts
index f9e6a1f..ef6fc72 100644
--- a/src/lib/runtime.ts
+++ b/src/lib/runtime.ts
@@ -34,6 +34,8 @@ import { formatActors, formatMessages, getActorDetails } from "./messages";
 import { defaultProviders, getProviders } from "./providers";
 import { type Actor, /*type Goal,*/ type Memory } from "./types";
 import { DatabaseAdapter } from "./database";
+import { UUID } from "crypto";
+import { zeroUuid } from "./constants";
 
 /**
  * Represents the runtime environment for an agent, handling message processing,
@@ -45,6 +47,10 @@ export class BgentRuntime {
    * @private
    */
   readonly #recentMessageCount = 32 as number;
+  /**
+   * The ID of the agent
+   */
+  agentId: UUID = zeroUuid;
   /**
    * The base URL of the server where the agent's requests are processed.
    */
@@ -134,10 +140,12 @@ export class BgentRuntime {
    * @param opts.providers - Optional context providers.
    * @param opts.model - The model to use for completion.
    * @param opts.embeddingModel - The model to use for embedding.
+   * @param opts.agentId - Optional ID of the agent.
    * @param opts.databaseAdapter - The database adapter used for interacting with the database.
    */
   constructor(opts: {
     recentMessageCount?: number; // number of messages to hold in the recent message cache
+    agentId?: UUID; // ID of the agent
     token: string; // JWT token, can be a JWT token if outside worker, or an OpenAI token if inside worker
     debugMode?: boolean; // If true, will log debug messages
     serverUrl?: string; // The URL of the worker
@@ -152,6 +160,7 @@ export class BgentRuntime {
       opts.recentMessageCount ?? this.#recentMessageCount;
     this.debugMode = opts.debugMode ?? false;
     this.databaseAdapter = opts.databaseAdapter;
+    this.agentId = opts.agentId ?? zeroUuid;
 
     if (!opts.databaseAdapter) {
       throw new Error("No database adapter provided");
@@ -285,7 +294,7 @@ export class BgentRuntime {
     const embeddingModel = this.embeddingModel;
 
     // Check if we already have the embedding in the lore
-    const cachedEmbedding = await this.retriveCachedEmbedding(input);
+    const cachedEmbedding = await this.retrieveCachedEmbedding(input);
     if (cachedEmbedding) {
       return cachedEmbedding;
     }
@@ -320,8 +329,6 @@ export class BgentRuntime {
 
       const data: OpenAIEmbeddingResponse = await response.json();
 
-      console.log("*** EMBEDDING LENGTH IS", data?.data?.[0].embedding.length);
-
       return data?.data?.[0].embedding;
     } catch (e) {
       console.error(e);
@@ -329,9 +336,9 @@ export class BgentRuntime {
     }
   }
 
-  async retriveCachedEmbedding(input: string) {
+  async retrieveCachedEmbedding(input: string) {
     const similaritySearchResult =
-      await this.messageManager.getMemoryByContent(input);
+      await this.messageManager.getCachedEmbeddings(input);
     if (similaritySearchResult.length > 0) {
       return similaritySearchResult[0].embedding;
     }
@@ -438,7 +445,7 @@ export class BgentRuntime {
    * @returns The state of the agent.
    */
   async composeState(message: Message) {
-    const { senderId, agentId, userIds, room_id } = message;
+    const { userId, room_id } = message;
 
     const recentMessageCount = this.getRecentMessageCount();
     const recentFactsCount = Math.ceil(this.getRecentMessageCount() / 2);
@@ -453,21 +460,21 @@ export class BgentRuntime {
       providers,
     ]: [Actor[], Memory[], Memory[], Goal[], Memory[], string] =
       await Promise.all([
-        getActorDetails({ runtime: this, userIds: userIds! }),
-        this.messageManager.getMemoriesByIds({
-          userIds,
+        getActorDetails({ runtime: this, room_id }),
+        this.messageManager.getMemories({
+          room_id,
           count: recentMessageCount,
           unique: false,
         }),
-        this.factManager.getMemoriesByIds({
-          userIds,
+        this.factManager.getMemories({
+          room_id,
           count: recentFactsCount,
         }),
         getGoals({
           runtime: this,
           count: 10,
           onlyInProgress: false,
-          userIds,
+          room_id,
         }),
         getLore({
           runtime: this,
@@ -487,7 +494,7 @@ export class BgentRuntime {
         await this.factManager.searchMemoriesByEmbedding(
           recentFactsData[0].embedding!,
           {
-            userIds: userIds!,
+            room_id,
             count: relevantFactsCount,
           },
         )
@@ -515,15 +522,14 @@ export class BgentRuntime {
     const lore = formatLore(loreData);
 
     const senderName = actorsData?.find(
-      (actor: Actor) => actor.id === senderId,
+      (actor: Actor) => actor.id === userId,
     )?.name;
     const agentName = actorsData?.find(
-      (actor: Actor) => actor.id === agentId,
+      (actor: Actor) => actor.id === this.agentId,
     )?.name;
 
     const initialState = {
-      userIds,
-      agentId,
+      agentId: this.agentId,
       agentName,
       senderName,
       actors: addHeader("# Actors", actors),
diff --git a/src/lib/types.ts b/src/lib/types.ts
index 8a4db31..9e8636c 100644
--- a/src/lib/types.ts
+++ b/src/lib/types.ts
@@ -45,18 +45,9 @@ export interface Memory {
   created_at?: string; // An optional timestamp indicating when the memory was created.
   content: Content; // The content of the memory, which can be a structured object or a plain string.
   embedding?: number[]; // An optional embedding vector representing the semantic content of the memory.
-  user_ids: UUID[]; // A list of user IDs associated with the memory, for group contexts.
   room_id: UUID; // The room or conversation ID associated with the memory.
 }
 
-/**
- * Represents a similarity search result, including the embedding vector and the Levenshtein score for a given search query.
- */
-export interface SimilaritySearch {
-  embedding: number[];
-  levenshtein_score: number;
-}
-
 /**
  * Represents an objective within a goal, detailing what needs to be achieved and whether it has been completed.
  */
@@ -77,7 +68,7 @@ export enum GoalStatus {
  */
 export interface Goal {
   id?: UUID; // A unique identifier for the goal.
-  user_ids: UUID[]; // A list of user IDs associated with the goal, for goals relevant to specific users or groups.
+  room_id: UUID; // A list of user IDs associated with the goal, for goals relevant to specific users or groups.
   user_id: UUID; // The user ID of the goal's owner or the user who is primarily responsible for the goal.
   name: string; // The name or title of the goal.
   status: GoalStatus; // The current status of the goal, such as "in progress" or "completed".
@@ -88,8 +79,7 @@ export interface Goal {
  * Represents the state of the conversation or context in which the agent is operating, including information about users, messages, goals, and other relevant data.
  */
 export interface State {
-  userIds: UUID[]; // A list of user IDs involved in the current conversation or context.
-  senderId?: UUID; // An optional ID of the user who sent the current message.
+  userId?: UUID; // An optional ID of the user who sent the current message.
   agentId?: UUID; // An optional ID of the agent within the current conversation or context.
   room_id: UUID; // The ID of the current room or conversation context.
   agentName?: string; // An optional name of the agent, used for referencing the agent in conversations.
@@ -117,9 +107,7 @@ export interface State {
  * Represents a message within the conversation, including its content and associated metadata such as the sender, agent, and room IDs.
  */
 export interface Message {
-  agentId: UUID; // The ID of the agent associated with the message.
-  senderId: UUID; // The ID of the user who sent the message.
-  userIds: UUID[]; // A list of user IDs involved in the message, for group contexts.
+  userId: UUID; // The ID of the user who sent the message.
   content: Content; // The content of the message, which can be a structured object or a plain string.
   room_id: UUID; // The ID of the room or conversation context in which the message was sent.
 }
@@ -211,10 +199,10 @@ export interface Relationship {
 /**
  * Represents a user, including their name, details, and a unique identifier.
  */
-export type Account = {
+export interface Account {
   id: UUID;
   name: string;
-  details?: string;
+  details?: { [key: string]: unknown };
   email?: string;
   avatar_url?: string;
-};
+}
diff --git a/src/test/cache.ts b/src/test/cache.ts
index da9bf09..b0b6f8d 100644
--- a/src/test/cache.ts
+++ b/src/test/cache.ts
@@ -1,8 +1,8 @@
 import fs from "fs";
 
-// getCachedEmbedding
+// getCachedEmbeddings
 // check cache.json for embedding where the key is a stringified version of the memory and the value is a number array
-export const getCachedEmbedding = (text: string) => {
+export const getCachedEmbeddings = (text: string) => {
   if (!fs.existsSync("./embedding-cache.json")) {
     fs.writeFileSync("./embedding-cache.json", "{}");
   }
diff --git a/src/test/createRuntime.ts b/src/test/createRuntime.ts
index e2b554c..24447bf 100644
--- a/src/test/createRuntime.ts
+++ b/src/test/createRuntime.ts
@@ -1,4 +1,5 @@
-import { Session, User, createClient } from "@supabase/supabase-js";
+import { Session, createClient } from "@supabase/supabase-js";
+import { User } from "./types";
 import { BgentRuntime } from "../lib/runtime";
 import { Action, Evaluator, Provider } from "../lib/types";
 import {
@@ -9,6 +10,9 @@ import {
 } from "./constants";
 import { DatabaseAdapter } from "../lib/database";
 import { SupabaseDatabaseAdapter } from "../lib/adapters/supabase";
+import { SqliteDatabaseAdapter } from "../lib/adapters/sqlite";
+import Database from "better-sqlite3";
+import { UUID } from "crypto";
 
 export async function createRuntime({
   env,
@@ -16,43 +20,79 @@ export async function createRuntime({
   evaluators = [],
   actions = [],
   providers = [],
-  databaseAdapter,
 }: {
   env?: Record<string, string> | NodeJS.ProcessEnv;
   recentMessageCount?: number;
   evaluators?: Evaluator[];
   actions?: Action[];
   providers?: Provider[];
-  databaseAdapter?: DatabaseAdapter;
 }) {
-  const supabase = createClient(
-    env?.SUPABASE_URL ?? SUPABASE_URL,
-    env?.SUPABASE_SERVICE_API_KEY ?? SUPABASE_ANON_KEY,
-  );
+  let adapter: DatabaseAdapter;
+  let user: User;
+  let session: Session;
 
-  const { data } = await supabase.auth.signInWithPassword({
-    email: TEST_EMAIL!,
-    password: TEST_PASSWORD!,
-  });
+  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,
+          env?.SUPABASE_SERVICE_API_KEY ?? SUPABASE_ANON_KEY,
+        );
+
+        const { data } = await supabase.auth.signInWithPassword({
+          email: TEST_EMAIL!,
+          password: TEST_PASSWORD!,
+        });
+
+        user = data.user as User;
+        session = data.session as Session;
+
+        if (!session) {
+          const response = await supabase.auth.signUp({
+            email: TEST_EMAIL!,
+            password: TEST_PASSWORD!,
+          });
+
+          console.log("response to signup", response);
+
+          // Change the name of the user
+          const { error } = await supabase
+            .from("accounts")
+            .update({ name: "Test User" })
+            .eq("id", response.data.user?.id);
 
-  let { user, session } = data;
+          if (error) {
+            throw new Error("Create runtime error: " + JSON.stringify(error));
+          }
 
-  if (!session) {
-    const response = await supabase.auth.signUp({
-      email: TEST_EMAIL!,
-      password: TEST_PASSWORD!,
-    });
-    // change the name of the user
-    const { error } = await supabase
-      .from("accounts")
-      .update({ name: "Test User" })
-      .eq("id", data?.user?.id);
+          user = response.data.user as User;
+          session = response.data.session as Session;
+        }
 
-    if (error) {
-      throw error;
-    }
-    user = response.data.user as User;
-    session = response.data.session as Session;
+        adapter = new SupabaseDatabaseAdapter(
+          env?.SUPABASE_URL ?? SUPABASE_URL,
+          env?.SUPABASE_SERVICE_API_KEY ?? SUPABASE_ANON_KEY,
+        );
+      }
+      break;
   }
 
   const runtime = new BgentRuntime({
@@ -63,12 +103,7 @@ export async function createRuntime({
     actions: actions ?? [],
     evaluators: evaluators ?? [],
     providers: providers ?? [],
-    databaseAdapter:
-      databaseAdapter ??
-      new SupabaseDatabaseAdapter(
-        env?.SUPABASE_URL ?? SUPABASE_URL,
-        env?.SUPABASE_SERVICE_API_KEY ?? SUPABASE_ANON_KEY,
-      ),
+    databaseAdapter: adapter,
   });
 
   return { user, session, runtime };
diff --git a/src/test/getOrCreateRelationship.ts b/src/test/getOrCreateRelationship.ts
new file mode 100644
index 0000000..1466ad5
--- /dev/null
+++ b/src/test/getOrCreateRelationship.ts
@@ -0,0 +1,52 @@
+import { UUID } from "crypto";
+import { BgentRuntime, Relationship, getRelationship } from "../lib";
+
+export async function getOrCreateRelationship({
+  runtime,
+  userA,
+  userB,
+}: {
+  runtime: BgentRuntime;
+  userA: UUID;
+  userB: UUID;
+}): Promise<Relationship> {
+  // Check if a relationship already exists between userA and userB
+  try {
+    let relationship = await getRelationship({ runtime, userA, userB });
+    // Check if a room already exists for the participants
+    const rooms = await runtime.databaseAdapter.getRoomsByParticipants([
+      userA,
+      userB,
+    ]);
+
+    let roomId: UUID;
+    if (!rooms || rooms.length === 0) {
+      // If no room exists, create a new room for the relationship
+      roomId = await runtime.databaseAdapter.createRoom("Direct Message");
+
+      // Add participants to the newly created room
+      await runtime.databaseAdapter.addParticipantToRoom(userA, roomId);
+      await runtime.databaseAdapter.addParticipantToRoom(userB, roomId);
+    } else {
+      // If a room already exists, use the existing room
+      roomId = rooms[0];
+    }
+
+    if (!relationship) {
+      // Create the relationship
+      await runtime.databaseAdapter.createRelationship({
+        userA,
+        userB,
+      });
+
+      relationship = await getRelationship({ runtime, userA, userB });
+
+      if (!relationship) {
+        throw new Error("Failed to fetch the created relationship");
+      }
+    }
+    return { ...relationship, room_id: roomId };
+  } catch (error) {
+    throw new Error(`Error creating relationship: ${JSON.stringify(error)}`);
+  }
+}
diff --git a/src/test/populateMemories.ts b/src/test/populateMemories.ts
index c6b3f2d..11cb2e8 100644
--- a/src/test/populateMemories.ts
+++ b/src/test/populateMemories.ts
@@ -1,9 +1,8 @@
-import { type User } from "@supabase/supabase-js";
 import { type UUID } from "crypto";
-import { zeroUuid } from "../lib/constants";
+import { type User } from "./types";
 import { type BgentRuntime } from "../lib/runtime";
 import { Content } from "../lib/types";
-import { getCachedEmbedding, writeCachedEmbedding } from "./cache";
+import { getCachedEmbeddings, writeCachedEmbedding } from "./cache";
 
 export async function populateMemories(
   runtime: BgentRuntime,
@@ -15,15 +14,14 @@ export async function populateMemories(
 ) {
   for (const conversation of conversations) {
     for (const c of conversation(user?.id as UUID)) {
-      const existingEmbedding = getCachedEmbedding(c.content.content);
+      const existingEmbedding = getCachedEmbeddings(c.content.content);
       const bakedMemory = await runtime.messageManager.addEmbeddingToMemory({
         user_id: c.user_id as UUID,
-        user_ids: [user?.id as UUID, zeroUuid],
         content: {
           content: c.content.content,
           action: c.content.action as string,
         },
-        room_id: room_id as UUID,
+        room_id,
         embedding: existingEmbedding,
       });
       await runtime.messageManager.createMemory(bakedMemory);
diff --git a/src/test/runAiTest.ts b/src/test/runAiTest.ts
index 3c1991b..a84d386 100644
--- a/src/test/runAiTest.ts
+++ b/src/test/runAiTest.ts
@@ -8,7 +8,7 @@ export async function runAiTest(
   let successful = 0;
 
   for (let i = 0; i < runs; i++) {
-    console.log("Running test", testName, " (iteration", i + ")");
+    // console.log("Running test", testName, " (iteration", i + ")");
     if (await testFunc()) successful++;
   }
 
diff --git a/src/test/types.ts b/src/test/types.ts
new file mode 100644
index 0000000..4bd7aed
--- /dev/null
+++ b/src/test/types.ts
@@ -0,0 +1,6 @@
+export interface User {
+  id: string;
+  email?: string;
+  phone?: string;
+  role?: string;
+}
diff --git a/supabase/migrations/20240225033633_remote_schema.sql b/supabase/migrations/20240225033633_remote_schema.sql
deleted file mode 100644
index 9e1542b..0000000
--- a/supabase/migrations/20240225033633_remote_schema.sql
+++ /dev/null
@@ -1,798 +0,0 @@
-
-SET statement_timeout = 0;
-SET lock_timeout = 0;
-SET idle_in_transaction_session_timeout = 0;
-SET client_encoding = 'UTF8';
-SET standard_conforming_strings = on;
-SELECT pg_catalog.set_config('search_path', '', false);
-SET check_function_bodies = false;
-SET xmloption = content;
-SET client_min_messages = warning;
-SET row_security = off;
-
-CREATE SCHEMA IF NOT EXISTS "public";
-
-ALTER SCHEMA "public" OWNER TO "pg_database_owner";
-
-
-DO $$
-BEGIN
-    IF NOT EXISTS (
-        SELECT 1
-        FROM pg_extension
-        WHERE extname = 'vector'
-    ) THEN
-        CREATE EXTENSION vector
-        SCHEMA extensions;
-    END IF;
-END $$;
-
-CREATE OR REPLACE FUNCTION "public"."check_similarity_and_insert"("query_table_name" "text", "query_user_id" "uuid", "query_user_ids" "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;
-    insert_query TEXT;
-BEGIN
-    -- Only perform the similarity check if query_embedding is not NULL
-    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 user_ids @> %L ' ||
-                'AND user_ids <@ %L ' ||
-                'AND embedding <=> %L < %L ' || -- Using cosine distance and comparing with threshold
-                'LIMIT 1' ||
-            ')',
-            query_table_name,
-            query_user_id,
-            query_user_ids,
-            query_embedding,
-            similarity_threshold
-        );
-
-        -- Execute the query to check for similarity
-        EXECUTE select_query INTO similar_found;
-    END IF;
-
-    -- 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, user_ids, content, room_id, embedding, "unique") ' ||
-        'VALUES (%L, %L, %L, %L, %L, %L)',
-        query_table_name,
-        query_user_id,
-        query_user_ids,
-        query_content,
-        query_room_id,
-        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
-    );
-
-    -- Execute the insert query
-    EXECUTE insert_query;
-END;
-$$;
-
-ALTER FUNCTION "public"."check_similarity_and_insert"("query_table_name" "text", "query_user_id" "uuid", "query_user_ids" "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_table_name" "text", "query_user_ids" "uuid"[], "query_unique" boolean DEFAULT false) RETURNS bigint
-    LANGUAGE "plpgsql"
-    AS $$
-DECLARE
-    query TEXT;
-    total BIGINT;
-BEGIN
-    -- Initialize the base query
-    query := format('SELECT COUNT(*) FROM %I WHERE TRUE', query_table_name);
-
-    -- Add condition for user_ids if not null, ensuring proper spacing
-    IF query_user_ids IS NOT NULL THEN
-        query := query || format(' AND user_ids @> %L::uuid[]', query_user_ids);
-    END IF;
-
-    -- Add condition for unique if TRUE, ensuring proper spacing
-    IF query_unique THEN
-        query := query || ' AND "unique" = TRUE';  -- Use double quotes if "unique" is a reserved keyword or potentially problematic
-    END IF;
-
-    -- Debug: Output the constructed query
-    RAISE NOTICE 'Executing query: %', query;
-
-    -- Execute the constructed query
-    EXECUTE query INTO total;
-    RETURN total;
-END;
-$$;
-
-ALTER FUNCTION "public"."count_memories"("query_table_name" "text", "query_user_ids" "uuid"[], "query_unique" boolean) OWNER TO "postgres";
-
-CREATE OR REPLACE FUNCTION "public"."create_dm_room"() RETURNS "trigger"
-    LANGUAGE "plpgsql"
-    AS $$
-DECLARE
-  new_room_id UUID;
-BEGIN
-  IF NEW.status = 'FRIENDS' AND NEW.room_id IS NULL THEN
-    INSERT INTO rooms (created_by, name)
-    VALUES (NULL, 'Direct Message')
-    RETURNING id INTO new_room_id;
-
-    UPDATE friendships
-    SET room_id = new_room_id
-    WHERE id = NEW.id;
-
-    INSERT INTO participants (user_id, room_id)
-    VALUES (NEW.user_id_1, new_room_id), (NEW.user_id_2, new_room_id);
-  END IF;
-
-  RETURN NEW;
-END;
-$$;
-
-ALTER FUNCTION "public"."create_dm_room"() OWNER TO "postgres";
-
-CREATE OR REPLACE FUNCTION "public"."create_friendship_and_room_for_user"("p_new_user_id" "uuid") RETURNS "void"
-    LANGUAGE "plpgsql"
-    AS $$
-DECLARE
-  host_agent_id UUID := '00000000-0000-0000-0000-000000000000';
-  new_room_id UUID;
-BEGIN
-  -- Create a new room for the direct message between the specified user and the host agent
-  INSERT INTO rooms (created_by, name)
-  VALUES (p_new_user_id, 'Direct Message with Host Agent')
-  RETURNING id INTO new_room_id;
-
-  -- Create a new friendship between the specified user and the host agent
-  INSERT INTO relationships (user_id_1, user_id_2, status, room_id)
-  VALUES (p_new_user_id, host_agent_id, 'FRIENDS', new_room_id);
-
-  -- Add both users as participants of the new room
-  INSERT INTO participants (user_id, room_id)
-  VALUES (p_new_user_id, new_room_id), (host_agent_id, new_room_id);
-END;
-$$;
-
-ALTER FUNCTION "public"."create_friendship_and_room_for_user"("p_new_user_id" "uuid") OWNER TO "postgres";
-
-CREATE OR REPLACE FUNCTION "public"."create_friendship_with_host_agent"() RETURNS "trigger"
-    LANGUAGE "plpgsql"
-    AS $$
-DECLARE
-  host_agent_id UUID := '00000000-0000-0000-0000-000000000000';
-  new_room_id UUID;
-BEGIN
-  -- Create a new room for the direct message between the new user and the host agent
-  INSERT INTO rooms (created_by, name)
-  VALUES (NEW.id, 'Direct Message with Host Agent')
-  RETURNING id INTO new_room_id;
-
-  -- Create a new friendship between the new user and the host agent
-  INSERT INTO relationships (user_a, user_b, user_id, status, room_id)
-  VALUES (NEW.id, host_agent_id, host_agent_id, 'FRIENDS', new_room_id);
-
-  -- Add both users as participants of the new room
-  INSERT INTO participants (user_id, room_id)
-  VALUES (NEW.id, new_room_id), (host_agent_id, new_room_id);
-
-  RETURN NEW;
-END;
-$$;
-
-ALTER FUNCTION "public"."create_friendship_with_host_agent"() OWNER TO "postgres";
-
-CREATE OR REPLACE FUNCTION "public"."delete_room_and_participants_on_friendship_delete"() RETURNS "trigger"
-    LANGUAGE "plpgsql"
-    AS $$
-BEGIN
-  DELETE FROM rooms WHERE id = OLD.room_id;
-
-  RETURN OLD;
-END;
-$$;
-
-ALTER FUNCTION "public"."delete_room_and_participants_on_friendship_delete"() OWNER TO "postgres";
-
-SET default_tablespace = '';
-
-SET default_table_access_method = "heap";
-
-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_ids" "uuid"[] DEFAULT '{}'::"uuid"[] NOT NULL,
-    "user_id" "uuid",
-    "name" "text",
-    "status" "text",
-    "description" "text",
-    "objectives" "jsonb"[] DEFAULT '{}'::"jsonb"[] NOT NULL
-);
-
-ALTER TABLE "public"."goals" OWNER TO "postgres";
-
-CREATE OR REPLACE FUNCTION "public"."get_goals_by_user_ids"("query_user_ids" "uuid"[], "query_user_id" "uuid" DEFAULT NULL::"uuid", "only_in_progress" boolean DEFAULT true, "row_count" integer DEFAULT 5) RETURNS SETOF "public"."goals"
-    LANGUAGE "plpgsql"
-    AS $$
-BEGIN
-    RETURN QUERY
-    SELECT * FROM goals
-    WHERE
-        (query_user_id IS NULL OR user_id = query_user_id)
-        AND (user_ids @> query_user_ids)
-        AND (NOT only_in_progress OR status = 'IN_PROGRESS')
-    LIMIT row_count;
-END;
-$$;
-
-ALTER FUNCTION "public"."get_goals_by_user_ids"("query_user_ids" "uuid"[], "query_user_id" "uuid", "only_in_progress" boolean, "row_count" integer) OWNER TO "postgres";
-
-CREATE OR REPLACE FUNCTION "public"."get_memories"("query_table_name" "text", "query_user_ids" "uuid"[], "query_count" integer, "query_unique" boolean DEFAULT false) RETURNS TABLE("id" "uuid", "user_id" "uuid", "content" "jsonb", "created_at" timestamp with time zone, "user_ids" "uuid"[], "room_id" "uuid", "embedding" "extensions"."vector")
-    LANGUAGE "plpgsql"
-    AS $_$
-DECLARE
-    query TEXT;
-BEGIN
-    query := format($fmt$
-        SELECT
-            id,
-            user_id,
-            content,
-            created_at,
-            user_ids,
-            room_id,
-            embedding
-        FROM %I
-        WHERE TRUE
-        %s -- Condition for user_ids
-        %s -- Additional condition for 'unique' column based on query_unique
-        ORDER BY created_at DESC
-        LIMIT %L
-        $fmt$,
-        query_table_name,
-        CASE WHEN query_user_ids IS NOT NULL THEN format(' AND user_ids @> %L', query_user_ids) ELSE '' END,
-        CASE WHEN query_unique THEN ' AND "unique" = TRUE' ELSE '' END, -- Enclose 'unique' in double quotes
-        query_count
-    );
-
-    RETURN QUERY EXECUTE query;
-END;
-$_$;
-
-ALTER FUNCTION "public"."get_memories"("query_table_name" "text", "query_user_ids" "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)
-    LANGUAGE "plpgsql"
-    AS $$BEGIN
-  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
-  WHERE p.user_id = p_user_id
-  GROUP BY p.room_id;
-END;
-$$;
-
-ALTER FUNCTION "public"."get_message_count"("p_user_id" "uuid") OWNER TO "postgres";
-
-CREATE OR REPLACE FUNCTION "public"."get_recent_rows_per_user"("query_table_name" "text", "array_of_uuid_arrays" "uuid"[], "n_rows_per_user" integer, "timestamp_column_name" "text") RETURNS TABLE("user_id" "uuid", "content" "jsonb", "timestamp_column" timestamp without time zone)
-    LANGUAGE "plpgsql"
-    AS $_$
-DECLARE
-    dynamic_query TEXT;
-    i INT;
-    uuid_array UUID[];
-BEGIN
-    -- Initialize the dynamic query with a common table expression (CTE)
-    dynamic_query := format($f$
-        WITH ranked_messages AS (
-            SELECT user_id, content, %I, ROW_NUMBER() OVER (PARTITION BY UNNEST(user_ids) ORDER BY %I DESC) AS rn
-            FROM %I
-            WHERE FALSE
-        $f$, timestamp_column_name, timestamp_column_name, query_table_name);
-
-    -- Loop through the array of UUID arrays using a FOR loop
-    FOR i IN 1..array_length(array_of_uuid_arrays, 1) LOOP
-        -- Access each UUID array by its index
-        uuid_array := array_of_uuid_arrays[i];
-
-        -- Append OR condition to check if user_ids contains all UUIDs in the current array
-        dynamic_query := dynamic_query || format($f$
-            OR user_ids @> %L::uuid[]
-        $f$, uuid_array);
-    END LOOP;
-
-    -- Complete the dynamic query by selecting rows where the rank is within the top N for each user
-    dynamic_query := dynamic_query || format($f$
-        )
-        SELECT user_id, content, %I AS timestamp_column
-        FROM ranked_messages
-        WHERE rn <= %L
-        $f$, timestamp_column_name, n_rows_per_user);
-
-    -- Execute the dynamic query and return the result set
-    RETURN QUERY EXECUTE dynamic_query;
-END;
-$_$;
-
-ALTER FUNCTION "public"."get_recent_rows_per_user"("query_table_name" "text", "array_of_uuid_arrays" "uuid"[], "n_rows_per_user" integer, "timestamp_column_name" "text") OWNER TO "postgres";
-
-CREATE TABLE IF NOT EXISTS "public"."relationships" (
-    "created_at" timestamp with time zone DEFAULT ("now"() AT TIME ZONE 'utc'::"text") NOT NULL,
-    "user_a" "uuid",
-    "user_b" "uuid",
-    "status" "text",
-    "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
-    "room_id" "uuid",
-    "user_id" "uuid" NOT NULL
-);
-
-ALTER TABLE "public"."relationships" OWNER TO "postgres";
-
-CREATE OR REPLACE FUNCTION "public"."get_relationship"("usera" "uuid", "userb" "uuid") RETURNS SETOF "public"."relationships"
-    LANGUAGE "plpgsql" STABLE
-    AS $$
-BEGIN
-  RETURN QUERY
-  SELECT *
-  FROM relationships
-  WHERE (user_a = usera AND user_b = userb)
-     OR (user_a = userb AND user_b = usera);
-END;
-$$;
-
-ALTER FUNCTION "public"."get_relationship"("usera" "uuid", "userb" "uuid") OWNER TO "postgres";
-
-CREATE OR REPLACE FUNCTION "public"."handle_new_user"() RETURNS "trigger"
-    LANGUAGE "plpgsql" SECURITY DEFINER
-    SET "search_path" TO 'public'
-    AS $$
-begin
-  insert into public.profiles (id, full_name, avatar_url)
-  values (new.id, new.raw_user_meta_data ->> 'user_name', new.raw_user_meta_data ->> 'avatar_url');
-  return new;
-end;
-$$;
-
-ALTER FUNCTION "public"."handle_new_user"() OWNER TO "postgres";
-
-CREATE OR REPLACE FUNCTION "public"."is_user_participant_in_room"("p_user_id" "uuid", "p_room_id" "uuid") RETURNS boolean
-    LANGUAGE "plpgsql"
-    AS $$
-DECLARE
-  is_participant BOOLEAN;
-BEGIN
-  SELECT EXISTS (
-    SELECT 1
-    FROM participants
-    WHERE user_id = p_user_id AND room_id = p_room_id
-  ) INTO is_participant;
-
-  RETURN is_participant;
-END;
-$$;
-
-ALTER FUNCTION "public"."is_user_participant_in_room"("p_user_id" "uuid", "p_room_id" "uuid") OWNER TO "postgres";
-
-CREATE OR REPLACE FUNCTION "public"."remove_memories"("query_table_name" "text", "query_user_ids" "uuid"[]) RETURNS "void"
-    LANGUAGE "plpgsql"
-    AS $_$DECLARE
-    dynamic_query TEXT;
-BEGIN
-    -- Construct dynamic SQL to delete memories where user_ids contains all elements of query_user_ids
-    dynamic_query := format('DELETE FROM %I WHERE user_ids @> $1', query_table_name);
-
-    -- Execute the dynamic SQL statement
-    EXECUTE dynamic_query USING query_user_ids;
-
-    -- Add any post-deletion logic here if needed
-END;
-$_$;
-
-ALTER FUNCTION "public"."remove_memories"("query_table_name" "text", "query_user_ids" "uuid"[]) OWNER TO "postgres";
-
-CREATE OR REPLACE FUNCTION "public"."search_memories"("query_table_name" "text", "query_user_ids" "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, "user_ids" "uuid"[], "room_id" "uuid", "embedding" "extensions"."vector")
-    LANGUAGE "plpgsql"
-    AS $_$
-DECLARE
-    query TEXT;
-BEGIN
-    query := format($fmt$
-        SELECT
-            id,
-            user_id,
-            content,
-            created_at,
-            1 - (embedding <=> %L) AS similarity, -- Use '<=>' for cosine distance
-            user_ids,
-            room_id,
-            embedding
-        FROM %I
-        WHERE (1 - (embedding <=> %L) > %L)
-        %s -- Condition for user_ids
-        %s -- Additional condition for 'unique' column
-        ORDER BY similarity DESC
-        LIMIT %L
-        $fmt$,
-        query_embedding,
-        query_table_name,
-        query_embedding,
-        query_match_threshold,
-        CASE WHEN query_user_ids IS NOT NULL THEN format(' AND user_ids @> %L', query_user_ids) ELSE '' END,
-        CASE WHEN query_unique THEN ' AND unique = TRUE' ELSE '' END, -- Add condition based on 'query_unique'
-        query_match_count
-    );
-
-    RETURN QUERY EXECUTE query;
-END;
-$_$;
-
-ALTER FUNCTION "public"."search_memories"("query_table_name" "text", "query_user_ids" "uuid"[], "query_embedding" "extensions"."vector", "query_match_threshold" double precision, "query_match_count" integer, "query_unique" boolean) OWNER TO "postgres";
-
-CREATE OR REPLACE FUNCTION "public"."search_messages"("query_embedding" "extensions"."vector", "similarity_threshold" double precision, "match_count" integer, "owner_id" "uuid", "chat_id" "uuid" DEFAULT NULL::"uuid") RETURNS TABLE("content" "text", "role" "text", "created_at" timestamp with time zone)
-    LANGUAGE "plpgsql"
-    AS $$
-BEGIN
-  RETURN QUERY
-  SELECT
-    messages.content,
-    messages.role,
-    messages.created_at::timestamp with time zone
-  FROM messages
-  WHERE
-    messages.owner = owner_id AND
-    (chat_id IS NULL OR messages.chat = chat_id) AND
-    1 - (messages.embedding <=> query_embedding) > similarity_threshold
-  ORDER BY
-    1 - (messages.embedding <=> query_embedding) DESC,
-    messages.created_at
-  LIMIT match_count;
-END;
-$$;
-
-ALTER FUNCTION "public"."search_messages"("query_embedding" "extensions"."vector", "similarity_threshold" double precision, "match_count" integer, "owner_id" "uuid", "chat_id" "uuid") OWNER TO "postgres";
-
-CREATE TABLE IF NOT EXISTS "public"."accounts" (
-    "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
-    "created_at" timestamp with time zone DEFAULT ("now"() AT TIME ZONE 'utc'::"text") NOT NULL,
-    "name" "text",
-    "email" "text" NOT NULL,
-    "avatar_url" "text",
-    "details" "jsonb" DEFAULT '{}'::"jsonb"
-);
-
-ALTER TABLE "public"."accounts" OWNER TO "postgres";
-
-CREATE TABLE IF NOT EXISTS "public"."descriptions" (
-    "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
-    "created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
-    "content" "jsonb" NOT NULL,
-    "embedding" "extensions"."vector" NOT NULL,
-    "user_id" "uuid",
-    "user_ids" "uuid"[],
-    "room_id" "uuid",
-    "name" "text",
-    "unique" boolean DEFAULT true NOT NULL
-);
-ALTER TABLE ONLY "public"."descriptions" ALTER COLUMN "embedding" SET STORAGE EXTENDED;
-
-ALTER TABLE "public"."descriptions" OWNER TO "postgres";
-
-CREATE TABLE IF NOT EXISTS "public"."logs" (
-    "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
-    "created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
-    "user_id" "uuid" NOT NULL,
-    "body" "jsonb" NOT NULL,
-    "type" "text" NOT NULL,
-    "room_id" "uuid" NOT NULL,
-    "user_ids" "uuid"[] NOT NULL,
-    "agent_id" "uuid" NOT NULL
-);
-
-ALTER TABLE "public"."logs" OWNER TO "postgres";
-
-CREATE TABLE IF NOT EXISTS "public"."lore" (
-    "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
-    "created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
-    "content" "jsonb" NOT NULL,
-    "embedding" "extensions"."vector" NOT NULL,
-    "user_id" "uuid",
-    "user_ids" "uuid"[],
-    "room_id" "uuid",
-    "name" "text",
-    "unique" boolean DEFAULT true NOT NULL
-);
-ALTER TABLE ONLY "public"."lore" ALTER COLUMN "embedding" SET STORAGE EXTENDED;
-
-ALTER TABLE "public"."lore" OWNER TO "postgres";
-
-CREATE TABLE IF NOT EXISTS "public"."messages" (
-    "created_at" timestamp with time zone DEFAULT ("now"() AT TIME ZONE 'utc'::"text") NOT NULL,
-    "user_id" "uuid",
-    "content" "jsonb",
-    "is_edited" boolean DEFAULT false,
-    "room_id" "uuid",
-    "updated_at" timestamp with time zone,
-    "user_ids" "uuid"[] DEFAULT '{}'::"uuid"[] NOT NULL,
-    "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
-    "embedding" "extensions"."vector",
-    "unique" boolean DEFAULT true NOT NULL
-);
-ALTER TABLE ONLY "public"."messages" ALTER COLUMN "embedding" SET STORAGE EXTENDED;
-
-ALTER TABLE "public"."messages" OWNER TO "postgres";
-
-CREATE TABLE IF NOT EXISTS "public"."participants" (
-    "created_at" timestamp with time zone DEFAULT ("now"() AT TIME ZONE 'utc'::"text") NOT NULL,
-    "user_id" "uuid",
-    "room_id" "uuid",
-    "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
-    "last_message_read" "uuid"
-);
-
-ALTER TABLE "public"."participants" OWNER TO "postgres";
-
-CREATE TABLE IF NOT EXISTS "public"."rooms" (
-    "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
-    "created_at" timestamp with time zone DEFAULT ("now"() AT TIME ZONE 'utc'::"text") NOT NULL,
-    "created_by" "uuid",
-    "name" "text"
-);
-
-ALTER TABLE "public"."rooms" OWNER TO "postgres";
-
-CREATE TABLE IF NOT EXISTS "public"."facts" (
-    "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
-    "created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
-    "content" "jsonb" NOT NULL,
-    "embedding" "extensions"."vector" NOT NULL,
-    "user_id" "uuid",
-    "user_ids" "uuid"[],
-    "room_id" "uuid",
-    "unique" boolean DEFAULT true NOT NULL
-);
-ALTER TABLE ONLY "public"."facts" ALTER COLUMN "embedding" SET STORAGE EXTENDED;
-
-ALTER TABLE "public"."facts" OWNER TO "postgres";
-
-ALTER TABLE ONLY "public"."descriptions"
-    ADD CONSTRAINT "descriptions_pkey" PRIMARY KEY ("id");
-
-ALTER TABLE ONLY "public"."relationships"
-    ADD CONSTRAINT "friendships_id_key" UNIQUE ("id");
-
-ALTER TABLE ONLY "public"."relationships"
-    ADD CONSTRAINT "friendships_pkey" PRIMARY KEY ("id");
-
-ALTER TABLE ONLY "public"."goals"
-    ADD CONSTRAINT "goals_pkey" PRIMARY KEY ("id");
-
-ALTER TABLE ONLY "public"."logs"
-    ADD CONSTRAINT "logs_pkey" PRIMARY KEY ("id");
-
-ALTER TABLE ONLY "public"."lore"
-    ADD CONSTRAINT "lore_pkey" PRIMARY KEY ("id");
-
-ALTER TABLE ONLY "public"."messages"
-    ADD CONSTRAINT "messages_id_key" UNIQUE ("id");
-
-ALTER TABLE ONLY "public"."messages"
-    ADD CONSTRAINT "messages_pkey" PRIMARY KEY ("id");
-
-ALTER TABLE ONLY "public"."participants"
-    ADD CONSTRAINT "participants_id_key" UNIQUE ("id");
-
-ALTER TABLE ONLY "public"."participants"
-    ADD CONSTRAINT "participants_pkey" PRIMARY KEY ("id");
-
-ALTER TABLE ONLY "public"."facts"
-    ADD CONSTRAINT "reflections_pkey" PRIMARY KEY ("id");
-
-ALTER TABLE ONLY "public"."rooms"
-    ADD CONSTRAINT "rooms_pkey" PRIMARY KEY ("id");
-
-ALTER TABLE ONLY "public"."accounts"
-    ADD CONSTRAINT "users_email_key" UNIQUE ("email");
-
-ALTER TABLE ONLY "public"."accounts"
-    ADD CONSTRAINT "users_pkey" PRIMARY KEY ("id");
-
-CREATE OR REPLACE TRIGGER "trigger_create_friendship_with_host_agent" AFTER INSERT ON "public"."accounts" FOR EACH ROW EXECUTE FUNCTION "public"."create_friendship_with_host_agent"();
-
-ALTER TABLE ONLY "public"."descriptions"
-    ADD CONSTRAINT "descriptions_room_id_fkey" FOREIGN KEY ("room_id") REFERENCES "public"."rooms"("id");
-
-ALTER TABLE ONLY "public"."descriptions"
-    ADD CONSTRAINT "descriptions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."accounts"("id");
-
-ALTER TABLE ONLY "public"."messages"
-    ADD CONSTRAINT "messages_room_id_fkey" FOREIGN KEY ("room_id") REFERENCES "public"."rooms"("id");
-
-ALTER TABLE ONLY "public"."messages"
-    ADD CONSTRAINT "messages_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."accounts"("id");
-
-ALTER TABLE ONLY "public"."participants"
-    ADD CONSTRAINT "participants_room_id_fkey" FOREIGN KEY ("room_id") REFERENCES "public"."rooms"("id");
-
-ALTER TABLE ONLY "public"."participants"
-    ADD CONSTRAINT "participants_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."accounts"("id");
-
-ALTER TABLE ONLY "public"."lore"
-    ADD CONSTRAINT "public_lore_room_id_fkey" FOREIGN KEY ("room_id") REFERENCES "public"."rooms"("id");
-
-ALTER TABLE ONLY "public"."lore"
-    ADD CONSTRAINT "public_lore_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."accounts"("id");
-
-ALTER TABLE ONLY "public"."facts"
-    ADD CONSTRAINT "reflections_room_id_fkey" FOREIGN KEY ("room_id") REFERENCES "public"."rooms"("id");
-
-ALTER TABLE ONLY "public"."facts"
-    ADD CONSTRAINT "reflections_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."accounts"("id");
-
-ALTER TABLE ONLY "public"."relationships"
-    ADD CONSTRAINT "relationships_room_id_fkey" FOREIGN KEY ("room_id") REFERENCES "public"."rooms"("id") ON UPDATE CASCADE ON DELETE CASCADE;
-
-ALTER TABLE ONLY "public"."relationships"
-    ADD CONSTRAINT "relationships_user_a_fkey" FOREIGN KEY ("user_a") REFERENCES "public"."accounts"("id");
-
-ALTER TABLE ONLY "public"."relationships"
-    ADD CONSTRAINT "relationships_user_b_fkey" FOREIGN KEY ("user_b") REFERENCES "public"."accounts"("id");
-
-ALTER TABLE ONLY "public"."relationships"
-    ADD CONSTRAINT "relationships_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."accounts"("id");
-
-ALTER TABLE ONLY "public"."rooms"
-    ADD CONSTRAINT "rooms_created_by_fkey" FOREIGN KEY ("created_by") REFERENCES "public"."accounts"("id");
-
-CREATE POLICY "Can select and update all data" ON "public"."accounts" USING (("auth"."uid"() = "id")) WITH CHECK (("auth"."uid"() = "id"));
-
-CREATE POLICY "Enable for authenticated users only" ON "public"."facts" TO "authenticated" USING (("auth"."uid"() = ANY ("user_ids"))) WITH CHECK (("auth"."uid"() = ANY ("user_ids")));
-
-CREATE POLICY "Enable for users based on user_id" ON "public"."descriptions" TO "authenticated" USING (("auth"."uid"() = ANY ("user_ids"))) WITH CHECK (("auth"."uid"() = ANY ("user_ids")));
-
-CREATE POLICY "Enable insert for authenticated users only" ON "public"."accounts" FOR INSERT TO "authenticated", "anon" WITH CHECK (true);
-
-CREATE POLICY "Enable insert for authenticated users only" ON "public"."logs" FOR INSERT TO "authenticated", "anon" WITH CHECK (true);
-
-CREATE POLICY "Enable insert for authenticated users only" ON "public"."messages" TO "authenticated" USING (true) WITH CHECK (true);
-
-CREATE POLICY "Enable insert for authenticated users only" ON "public"."participants" FOR INSERT TO "authenticated" WITH CHECK (true);
-
-CREATE POLICY "Enable insert for authenticated users only" ON "public"."relationships" FOR INSERT TO "authenticated" WITH CHECK ((("auth"."uid"() = "user_a") OR ("auth"."uid"() = "user_b")));
-
-CREATE POLICY "Enable insert for authenticated users only" ON "public"."rooms" FOR INSERT WITH CHECK (true);
-
-CREATE POLICY "Enable insert for self id" ON "public"."participants" USING (("auth"."uid"() = "user_id")) WITH CHECK (("auth"."uid"() = "user_id"));
-
-CREATE POLICY "Enable read access for all users" ON "public"."accounts" FOR SELECT USING (true);
-
-CREATE POLICY "Enable read access for all users" ON "public"."rooms" FOR SELECT TO "authenticated" USING (true);
-
-CREATE POLICY "Enable read access for own messages" ON "public"."messages" FOR SELECT TO "authenticated" USING ((("auth"."uid"() = ANY ("user_ids")) OR ("auth"."uid"() = "user_id")));
-
-CREATE POLICY "Enable read access for own rooms" ON "public"."participants" FOR SELECT TO "authenticated" USING (("auth"."uid"() = "user_id"));
-
-CREATE POLICY "Enable read access for user to their own relationships" ON "public"."relationships" FOR SELECT TO "authenticated" USING ((("auth"."uid"() = "user_a") OR ("auth"."uid"() = "user_b")));
-
-CREATE POLICY "Enable update for users of own id" ON "public"."rooms" FOR UPDATE USING (true) WITH CHECK (true);
-
-ALTER TABLE "public"."logs" 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 ALL ON FUNCTION "public"."count_memories"("query_table_name" "text", "query_user_ids" "uuid"[], "query_unique" boolean) TO "anon";
-GRANT ALL ON FUNCTION "public"."count_memories"("query_table_name" "text", "query_user_ids" "uuid"[], "query_unique" boolean) TO "authenticated";
-GRANT ALL ON FUNCTION "public"."count_memories"("query_table_name" "text", "query_user_ids" "uuid"[], "query_unique" boolean) TO "service_role";
-
-GRANT ALL ON FUNCTION "public"."create_dm_room"() TO "anon";
-GRANT ALL ON FUNCTION "public"."create_dm_room"() TO "authenticated";
-GRANT ALL ON FUNCTION "public"."create_dm_room"() TO "service_role";
-
-GRANT ALL ON FUNCTION "public"."create_friendship_and_room_for_user"("p_new_user_id" "uuid") TO "anon";
-GRANT ALL ON FUNCTION "public"."create_friendship_and_room_for_user"("p_new_user_id" "uuid") TO "authenticated";
-GRANT ALL ON FUNCTION "public"."create_friendship_and_room_for_user"("p_new_user_id" "uuid") TO "service_role";
-
-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"."delete_room_and_participants_on_friendship_delete"() TO "anon";
-GRANT ALL ON FUNCTION "public"."delete_room_and_participants_on_friendship_delete"() TO "authenticated";
-GRANT ALL ON FUNCTION "public"."delete_room_and_participants_on_friendship_delete"() TO "service_role";
-
-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 FUNCTION "public"."get_goals_by_user_ids"("query_user_ids" "uuid"[], "query_user_id" "uuid", "only_in_progress" boolean, "row_count" integer) TO "anon";
-GRANT ALL ON FUNCTION "public"."get_goals_by_user_ids"("query_user_ids" "uuid"[], "query_user_id" "uuid", "only_in_progress" boolean, "row_count" integer) TO "authenticated";
-GRANT ALL ON FUNCTION "public"."get_goals_by_user_ids"("query_user_ids" "uuid"[], "query_user_id" "uuid", "only_in_progress" boolean, "row_count" integer) TO "service_role";
-
-GRANT ALL ON FUNCTION "public"."get_memories"("query_table_name" "text", "query_user_ids" "uuid"[], "query_count" integer, "query_unique" boolean) TO "anon";
-GRANT ALL ON FUNCTION "public"."get_memories"("query_table_name" "text", "query_user_ids" "uuid"[], "query_count" integer, "query_unique" boolean) TO "authenticated";
-GRANT ALL ON FUNCTION "public"."get_memories"("query_table_name" "text", "query_user_ids" "uuid"[], "query_count" integer, "query_unique" boolean) TO "service_role";
-
-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_recent_rows_per_user"("query_table_name" "text", "array_of_uuid_arrays" "uuid"[], "n_rows_per_user" integer, "timestamp_column_name" "text") TO "anon";
-GRANT ALL ON FUNCTION "public"."get_recent_rows_per_user"("query_table_name" "text", "array_of_uuid_arrays" "uuid"[], "n_rows_per_user" integer, "timestamp_column_name" "text") TO "authenticated";
-GRANT ALL ON FUNCTION "public"."get_recent_rows_per_user"("query_table_name" "text", "array_of_uuid_arrays" "uuid"[], "n_rows_per_user" integer, "timestamp_column_name" "text") TO "service_role";
-
-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 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"."handle_new_user"() TO "anon";
-GRANT ALL ON FUNCTION "public"."handle_new_user"() TO "authenticated";
-GRANT ALL ON FUNCTION "public"."handle_new_user"() TO "service_role";
-
-GRANT ALL ON FUNCTION "public"."is_user_participant_in_room"("p_user_id" "uuid", "p_room_id" "uuid") TO "anon";
-GRANT ALL ON FUNCTION "public"."is_user_participant_in_room"("p_user_id" "uuid", "p_room_id" "uuid") TO "authenticated";
-GRANT ALL ON FUNCTION "public"."is_user_participant_in_room"("p_user_id" "uuid", "p_room_id" "uuid") TO "service_role";
-
-GRANT ALL ON FUNCTION "public"."remove_memories"("query_table_name" "text", "query_user_ids" "uuid"[]) TO "anon";
-GRANT ALL ON FUNCTION "public"."remove_memories"("query_table_name" "text", "query_user_ids" "uuid"[]) TO "authenticated";
-GRANT ALL ON FUNCTION "public"."remove_memories"("query_table_name" "text", "query_user_ids" "uuid"[]) TO "service_role";
-
-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 ALL ON TABLE "public"."descriptions" TO "anon";
-GRANT ALL ON TABLE "public"."descriptions" TO "authenticated";
-GRANT ALL ON TABLE "public"."descriptions" TO "service_role";
-
-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"."lore" TO "anon";
-GRANT ALL ON TABLE "public"."lore" TO "authenticated";
-GRANT ALL ON TABLE "public"."lore" TO "service_role";
-
-GRANT ALL ON TABLE "public"."messages" TO "anon";
-GRANT ALL ON TABLE "public"."messages" TO "authenticated";
-GRANT ALL ON TABLE "public"."messages" TO "service_role";
-
-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"."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"."facts" TO "anon";
-GRANT ALL ON TABLE "public"."facts" TO "authenticated";
-GRANT ALL ON TABLE "public"."facts" TO "service_role";
-
-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 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 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";
-
-RESET ALL;
diff --git a/supabase/migrations/20240225043641_remote_schema.sql b/supabase/migrations/20240225043641_remote_schema.sql
deleted file mode 100644
index c51346e..0000000
--- a/supabase/migrations/20240225043641_remote_schema.sql
+++ /dev/null
@@ -1,179 +0,0 @@
-create table "public"."credits" (
-    "id" bigint generated by default as identity not null,
-    "created_at" timestamp with time zone not null default now(),
-    "sender_id" text,
-    "receiver_id" text,
-    "amount" numeric,
-    "reason" text
-);
-
-
-alter table "public"."credits" enable row level security;
-
-alter table "public"."accounts" alter column "id" drop default;
-
-alter table "public"."accounts" enable row level security;
-
-alter table "public"."descriptions" enable row level security;
-
-alter table "public"."goals" enable row level security;
-
-alter table "public"."lore" enable row level security;
-
-alter table "public"."messages" enable row level security;
-
-alter table "public"."participants" enable row level security;
-
-alter table "public"."relationships" enable row level security;
-
-alter table "public"."rooms" enable row level security;
-
-alter table "public"."facts" enable row level security;
-
-CREATE UNIQUE INDEX credits_pkey ON public.credits USING btree (id);
-
-alter table "public"."credits" add constraint "credits_pkey" PRIMARY KEY using index "credits_pkey";
-
-set check_function_bodies = off;
-
-CREATE OR REPLACE FUNCTION public.check_similarity_and_insert(query_table_name text, query_user_id uuid, query_user_ids uuid[], query_content jsonb, query_room_id uuid, query_embedding vector, similarity_threshold double precision)
- RETURNS void
- LANGUAGE plpgsql
-AS $function$
-DECLARE
-    similar_found BOOLEAN := FALSE;
-    select_query TEXT;
-    insert_query TEXT;
-BEGIN
-    -- Only perform the similarity check if query_embedding is not NULL
-    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 user_ids @> %L ' ||  -- Assuming this is correct
-            'AND user_ids <@ %L ' ||  -- Assuming this needs to be included again
-            'AND embedding <=> %L < %L ' ||
-            'LIMIT 1' ||
-        ')',
-        query_table_name,
-        query_user_id,
-        query_user_ids,  -- First usage
-        query_user_ids,  -- Second usage (added)
-        query_embedding,
-        similarity_threshold
-    );
-
-
-        -- Execute the query to check for similarity
-        EXECUTE select_query INTO similar_found;
-    END IF;
-
-    -- 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, user_ids, content, room_id, embedding, "unique") ' ||
-        'VALUES (%L, %L, %L, %L, %L, %L)',
-        query_table_name,
-        query_user_id,
-        query_user_ids,
-        query_content,
-        query_room_id,
-        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
-    );
-
-    -- Execute the insert query
-    EXECUTE insert_query;
-END;
-$function$
-;
-
-CREATE OR REPLACE FUNCTION public.create_friendship_with_host_agent()
- RETURNS trigger
- LANGUAGE plpgsql
-AS $function$
-DECLARE
-  host_agent_id UUID := '00000000-0000-0000-0000-000000000000';
-  new_room_id UUID;
-BEGIN
-  -- Assuming NEW.id is the user ID of the newly inserted/updated row triggering this action
-  -- Create a new room for the direct message between the new user and the host agent
-  INSERT INTO rooms (created_by, name)
-  VALUES (NEW.id, 'Direct Message with Host Agent')
-  RETURNING id INTO new_room_id;
-
-  -- Create a new friendship between the new user and the host agent
-  INSERT INTO relationships (user_a, user_b, status, room_id)
-  VALUES (NEW.id, host_agent_id, 'FRIENDS', new_room_id);
-
-  -- Add both users as participants of the new room
-  INSERT INTO participants (user_id, room_id)
-  VALUES (NEW.id, new_room_id), (host_agent_id, new_room_id);
-
-  RETURN NEW; -- For AFTER triggers, or NULL for BEFORE triggers
-END;
-$function$
-;
-
-grant delete on table "public"."credits" to "anon";
-
-grant insert on table "public"."credits" to "anon";
-
-grant references on table "public"."credits" to "anon";
-
-grant select on table "public"."credits" to "anon";
-
-grant trigger on table "public"."credits" to "anon";
-
-grant truncate on table "public"."credits" to "anon";
-
-grant update on table "public"."credits" to "anon";
-
-grant delete on table "public"."credits" to "authenticated";
-
-grant insert on table "public"."credits" to "authenticated";
-
-grant references on table "public"."credits" to "authenticated";
-
-grant select on table "public"."credits" to "authenticated";
-
-grant trigger on table "public"."credits" to "authenticated";
-
-grant truncate on table "public"."credits" to "authenticated";
-
-grant update on table "public"."credits" to "authenticated";
-
-grant delete on table "public"."credits" to "service_role";
-
-grant insert on table "public"."credits" to "service_role";
-
-grant references on table "public"."credits" to "service_role";
-
-grant select on table "public"."credits" to "service_role";
-
-grant trigger on table "public"."credits" to "service_role";
-
-grant truncate on table "public"."credits" to "service_role";
-
-grant update on table "public"."credits" to "service_role";
-
-create policy "Enable insert for authenticated users only"
-on "public"."lore"
-as permissive
-for all
-to authenticated
-using (true)
-with check (true);
-
-
-create policy "Enable read access for all users"
-on "public"."lore"
-as permissive
-for select
-to authenticated
-using (true);
-
-
-
diff --git a/supabase/migrations/20240225092002_remote_schema.sql b/supabase/migrations/20240225092002_remote_schema.sql
deleted file mode 100644
index c97c94e..0000000
--- a/supabase/migrations/20240225092002_remote_schema.sql
+++ /dev/null
@@ -1,34 +0,0 @@
-create policy "Enable delete for users based on user_id"
-on "public"."goals"
-as permissive
-for delete
-to authenticated
-using ((auth.uid() = user_id));
-
-
-create policy "Enable insert for authenticated users only"
-on "public"."goals"
-as permissive
-for insert
-to authenticated
-with check (true);
-
-
-create policy "Enable read access for all users"
-on "public"."goals"
-as permissive
-for select
-to public
-using (true);
-
-
-create policy "Enable update for users based on email"
-on "public"."goals"
-as permissive
-for update
-to authenticated
-using (true)
-with check (true);
-
-
-
diff --git a/supabase/migrations/20240226185209_remote_schema.sql b/supabase/migrations/20240226185209_remote_schema.sql
deleted file mode 100644
index 0c2aefb..0000000
--- a/supabase/migrations/20240226185209_remote_schema.sql
+++ /dev/null
@@ -1,42 +0,0 @@
-alter table "public"."accounts" alter column "id" set default auth.uid();
-
-alter table "public"."descriptions" disable row level security;
-
-set check_function_bodies = off;
-
-CREATE OR REPLACE FUNCTION public.create_friendship_with_host_agent()
- RETURNS trigger
- LANGUAGE plpgsql
-AS $function$
-DECLARE
-  host_agent_id UUID := '00000000-0000-0000-0000-000000000000';
-  new_room_id UUID;
-BEGIN
-  -- Assuming NEW.id is the user ID of the newly inserted/updated row triggering this action
-  -- Create a new room for the direct message between the new user and the host agent
-  INSERT INTO rooms (created_by, name)
-  VALUES (auth.uid(), 'Direct Message with Host Agent')
-  RETURNING id INTO new_room_id;
-
-  -- Create a new friendship between the new user and the host agent
-  INSERT INTO relationships (user_a, user_b, status, room_id, user_id)
-  VALUES (auth.uid(), host_agent_id, 'FRIENDS', new_room_id, host_agent_id);
-
-  -- Add both users as participants of the new room
-  INSERT INTO participants (user_id, room_id)
-  VALUES (auth.uid(), new_room_id), (host_agent_id, new_room_id);
-
-  RETURN NEW; -- For AFTER triggers, or NULL for BEFORE triggers
-END;
-$function$
-;
-
-create policy "Enable read access for all users"
-on "public"."relationships"
-as permissive
-for select
-to authenticated
-using (true);
-
-
-
diff --git a/supabase/migrations/20240310013115_search_content_embeddings.sql b/supabase/migrations/20240310013115_search_content_embeddings.sql
deleted file mode 100644
index 46a051c..0000000
--- a/supabase/migrations/20240310013115_search_content_embeddings.sql
+++ /dev/null
@@ -1,51 +0,0 @@
-create extension if not exists "fuzzystrmatch" with schema "extensions";
-
-set check_function_bodies = off;
-
-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 vector, levenshtein_score integer)
- LANGUAGE plpgsql
-AS $function$
-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
-        QUERY := format('
-            SELECT
-                embedding
-            FROM
-                %I
-            WHERE
-                (content->>''%s'')::TEXT = $1
-            LIMIT
-                $2
-        ', query_table_name, query_field_name);
-        -- Execute the query with adjusted parameters for exact match
-        RETURN QUERY EXECUTE QUERY USING 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
-            FROM
-                %I
-            WHERE
-                levenshtein($1, (content->>''%s'')::TEXT) <= $2
-            ORDER BY
-                levenshtein_score
-            LIMIT
-                $3
-        ', query_field_name, query_table_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;
-    END IF;
-END;
-$function$
-;
\ No newline at end of file
diff --git a/supabase/migrations/20240318103238_remote_schema.sql b/supabase/migrations/20240318103238_remote_schema.sql
new file mode 100644
index 0000000..40f604e
--- /dev/null
+++ b/supabase/migrations/20240318103238_remote_schema.sql
@@ -0,0 +1,732 @@
+
+SET statement_timeout = 0;
+SET lock_timeout = 0;
+SET idle_in_transaction_session_timeout = 0;
+SET client_encoding = 'UTF8';
+SET standard_conforming_strings = on;
+SELECT pg_catalog.set_config('search_path', '', false);
+SET check_function_bodies = false;
+SET xmloption = content;
+SET client_min_messages = warning;
+SET row_security = off;
+
+CREATE SCHEMA IF NOT EXISTS "public";
+
+ALTER SCHEMA "public" OWNER TO "pg_database_owner";
+
+DO $$
+BEGIN
+    IF NOT EXISTS (
+        SELECT 1
+        FROM pg_extension
+        WHERE extname = 'vector'
+    ) THEN
+        CREATE EXTENSION vector
+        SCHEMA extensions;
+    END IF;
+END $$;
+
+CREATE TABLE IF NOT EXISTS "public"."secrets" (
+    "key" "text" PRIMARY KEY,
+    "value" "text" NOT NULL
+);
+
+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'
+    AS $$
+DECLARE
+  response RECORD; -- Define response with the expected return type
+  newuser_url TEXT;
+  token TEXT;
+BEGIN
+  -- Retrieve the newuser URL and token from the secrets table
+  SELECT value INTO newuser_url FROM secrets WHERE key = 'newuser_url';
+  SELECT value INTO token FROM secrets WHERE key = 'token';
+
+  -- Ensure newuser_url and token are both defined and not empty
+  IF newuser_url IS NOT NULL AND newuser_url <> '' AND token IS NOT NULL AND token <> '' THEN
+    -- Make the HTTP POST request to the endpoint
+    SELECT * INTO response FROM http_post(
+      newuser_url,
+      jsonb_build_object(
+        'token', token,
+        'user_id', NEW.id::text
+      )
+    );
+  END IF;
+
+  RETURN NEW;
+END;
+$$;
+
+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 $$
+DECLARE
+    similar_found BOOLEAN := FALSE;
+    select_query TEXT;
+    insert_query TEXT;
+BEGIN
+    -- Only perform the similarity check if query_embedding is not NULL
+    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 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;
+    END IF;
+
+    -- Prepare the insert query with 'unique' field set based on the presence of similar records or NULL query_embedding
+    insert_query := format(
+        '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
+    );
+
+    -- Execute the insert query
+    EXECUTE insert_query;
+END;
+$$;
+
+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_table_name" "text", "query_room_id" "uuid", "query_unique" boolean DEFAULT false) RETURNS bigint
+    LANGUAGE "plpgsql"
+    AS $$
+DECLARE
+    query TEXT;
+    total BIGINT;
+BEGIN
+    -- Initialize the base query
+    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
+        query := query || format(' AND room_id = %L', query_room_id);
+    END IF;
+
+    -- Add condition for unique if TRUE, ensuring proper spacing
+    IF query_unique THEN
+        query := query || ' AND "unique" = TRUE';  -- Use double quotes if "unique" is a reserved keyword or potentially problematic
+    END IF;
+
+    -- Debug: Output the constructed query
+    RAISE NOTICE 'Executing query: %', query;
+
+    -- Execute the constructed query
+    EXECUTE query INTO total;
+    RETURN total;
+END;
+$$;
+
+
+ALTER FUNCTION "public"."count_memories"("query_table_name" "text", "query_room_id" "uuid", "query_unique" boolean) OWNER TO "postgres";
+
+CREATE OR REPLACE FUNCTION "public"."create_friendship_with_host_agent"() RETURNS "trigger"
+    LANGUAGE "plpgsql"
+    AS $$
+DECLARE
+  host_agent_id UUID := '00000000-0000-0000-0000-000000000000';
+  new_room_id UUID;
+BEGIN
+  -- Create a new room for the direct message between the new user and the host agent
+  INSERT INTO rooms (created_by, name)
+  VALUES (NEW.id, 'Direct Message with Host Agent')
+  RETURNING id INTO new_room_id;
+
+  -- Create a new friendship between the new user and the host agent
+  INSERT INTO relationships (user_a, user_b, user_id, status, room_id)
+  VALUES (NEW.id, host_agent_id, host_agent_id, 'FRIENDS', new_room_id);
+
+  -- Add both users as participants of the new room
+  INSERT INTO participants (user_id, room_id)
+  VALUES (NEW.id, new_room_id), (host_agent_id, new_room_id);
+
+  RETURN NEW;
+END;
+$$;
+
+ALTER FUNCTION "public"."create_friendship_with_host_agent"() OWNER TO "postgres";
+
+CREATE OR REPLACE FUNCTION "public"."fn_notify_agents"() RETURNS "trigger"
+    LANGUAGE "plpgsql"
+    AS $$
+DECLARE
+  participant RECORD;
+  agent_flag BOOLEAN;
+  response RECORD;
+  payload TEXT;
+  message_url TEXT;
+  token TEXT;
+BEGIN
+  -- Retrieve the message URL and token from the secrets table
+  SELECT value INTO message_url FROM secrets WHERE key = 'message_url';
+  SELECT value INTO token FROM secrets WHERE key = 'token';
+
+  -- Iterate over the participants of the room
+  FOR participant IN (
+    SELECT p.user_id
+    FROM participants p
+    WHERE p.room_id = NEW.room_id
+  )
+  LOOP
+    -- Check if the participant is an agent
+    SELECT is_agent INTO agent_flag FROM accounts WHERE id = participant.user_id;
+
+    -- Add a condition to ensure the sender is not the agent
+    IF agent_flag AND NEW.user_id <> participant.user_id THEN
+      -- Construct the payload JSON object and explicitly cast to TEXT
+      payload := jsonb_build_object(
+        'token', token,
+        'senderId', NEW.user_id::text,
+        'content', NEW.content,
+        'room_id', NEW.room_id::text
+      )::text;
+
+      -- Make the HTTP POST request to the Cloudflare worker endpoint
+      SELECT * INTO response FROM http_post(
+        message_url,
+        payload,
+        'application/json'
+      );
+    END IF;
+  END LOOP;
+
+  RETURN NEW;
+END;
+$$;
+
+
+
+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
+    QUERY TEXT;
+BEGIN
+    -- Check the length of query_input
+    IF LENGTH(query_input) > 255 THEN
+        -- For inputs longer than 255 characters, use exact match only
+        QUERY := format('
+            SELECT
+                embedding
+            FROM
+                memories
+            WHERE
+                type = $1 AND
+                (content->>''%s'')::TEXT = $2
+            LIMIT
+                $3
+        ', query_field_name);
+        -- Execute the query with adjusted parameters for exact match
+        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($2, (content->>''%s'')::TEXT) AS levenshtein_score
+            FROM
+                memories
+            WHERE
+                type = $1 AND
+                levenshtein($2, (content->>''%s'')::TEXT) <= $3
+            ORDER BY
+                levenshtein_score
+            LIMIT
+                $4
+        ', query_field_name, query_field_name);
+        -- Execute the query with original parameters for Levenshtein distance
+        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";
+
+SET default_tablespace = '';
+
+SET default_table_access_method = "heap";
+
+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
+);
+
+ALTER TABLE "public"."goals" OWNER TO "postgres";
+
+CREATE OR REPLACE FUNCTION "public"."get_goals"("query_room_id" "uuid", "query_user_id" "uuid" DEFAULT NULL::"uuid", "only_in_progress" boolean DEFAULT true, "row_count" integer DEFAULT 5) RETURNS SETOF "public"."goals"
+    LANGUAGE "plpgsql"
+    AS $$
+BEGIN
+    RETURN QUERY
+    SELECT * FROM goals
+    WHERE
+        (query_user_id IS NULL OR user_id = query_user_id)
+        AND (room_id = query_room_id)
+        AND (NOT only_in_progress OR status = 'IN_PROGRESS')
+    LIMIT row_count;
+END;
+$$;
+
+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_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
+    query := format($fmt$
+        SELECT
+            id,
+            user_id,
+            content,
+            created_at,
+            room_id,
+            embedding
+        FROM memories
+        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_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,
+        query_count
+    );
+
+    RETURN QUERY EXECUTE query;
+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)
+    LANGUAGE "plpgsql"
+    AS $$BEGIN
+  RETURN QUERY
+  SELECT p.room_id, COALESCE(COUNT(m.id)::integer, 0) AS unread_messages_count
+  FROM participants p
+  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;
+$$;
+
+ALTER FUNCTION "public"."get_message_count"("p_user_id" "uuid") OWNER TO "postgres";
+
+CREATE TABLE IF NOT EXISTS "public"."relationships" (
+    "created_at" timestamp with time zone DEFAULT ("now"() AT TIME ZONE 'utc'::"text") NOT NULL,
+    "user_a" "uuid",
+    "user_b" "uuid",
+    "status" "text",
+    "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
+    "user_id" "uuid" NOT NULL
+);
+
+ALTER TABLE "public"."relationships" OWNER TO "postgres";
+
+CREATE OR REPLACE FUNCTION "public"."get_relationship"("usera" "uuid", "userb" "uuid") RETURNS SETOF "public"."relationships"
+    LANGUAGE "plpgsql" STABLE
+    AS $$
+BEGIN
+  RETURN QUERY
+  SELECT *
+  FROM relationships
+  WHERE (user_a = usera AND user_b = userb)
+     OR (user_a = userb AND user_b = usera);
+END;
+$$;
+
+ALTER FUNCTION "public"."get_relationship"("usera" "uuid", "userb" "uuid") OWNER TO "postgres";
+
+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_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_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
+    query := format($fmt$
+        SELECT
+            id,
+            user_id,
+            content,
+            created_at,
+            1 - (embedding <=> %L) AS similarity, -- Use '<=>' for cosine distance
+            room_id,
+            embedding
+        FROM memories
+        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_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,
+        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";
+
+CREATE TABLE IF NOT EXISTS "public"."accounts" (
+    "id" "uuid" DEFAULT "auth"."uid"() NOT NULL,
+    "created_at" timestamp with time zone DEFAULT ("now"() AT TIME ZONE 'utc'::"text") NOT NULL,
+    "name" "text",
+    "email" "text" NOT NULL,
+    "avatar_url" "text",
+    "details" "jsonb" DEFAULT '{}'::"jsonb",
+    "is_agent" boolean DEFAULT false NOT NULL,
+    "location" "text",
+    "profile_line" "text",
+    "signed_tos" boolean DEFAULT false NOT NULL
+);
+
+ALTER TABLE "public"."accounts" OWNER TO "postgres";
+
+CREATE TABLE IF NOT EXISTS "public"."logs" (
+    "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
+    "created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
+    "user_id" "uuid" NOT NULL,
+    "body" "jsonb" NOT NULL,
+    "type" "text" NOT NULL,
+    "room_id" "uuid"
+);
+
+ALTER TABLE "public"."logs" OWNER TO "postgres";
+
+CREATE TABLE IF NOT EXISTS "public"."memories" (
+    "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
+    "created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
+    "content" "jsonb" NOT NULL,
+    "embedding" "extensions"."vector" NOT NULL,
+    "user_id" "uuid",
+    "room_id" "uuid",
+    "unique" boolean DEFAULT true NOT NULL,
+    "type" "text" NOT NULL
+);
+
+ALTER TABLE "public"."memories" OWNER TO "postgres";
+
+CREATE TABLE IF NOT EXISTS "public"."participants" (
+    "created_at" timestamp with time zone DEFAULT ("now"() AT TIME ZONE 'utc'::"text") NOT NULL,
+    "user_id" "uuid",
+    "room_id" "uuid",
+    "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
+    "last_message_read" "uuid"
+);
+
+ALTER TABLE "public"."participants" OWNER TO "postgres";
+
+CREATE TABLE IF NOT EXISTS "public"."rooms" (
+    "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
+    "created_at" timestamp with time zone DEFAULT ("now"() AT TIME ZONE 'utc'::"text") NOT NULL,
+    "created_by" "uuid",
+    "name" "text"
+);
+
+ALTER TABLE "public"."rooms" OWNER TO "postgres";
+
+ALTER TABLE ONLY "public"."relationships"
+    ADD CONSTRAINT "friendships_id_key" UNIQUE ("id");
+
+ALTER TABLE ONLY "public"."relationships"
+    ADD CONSTRAINT "friendships_pkey" PRIMARY KEY ("id");
+
+ALTER TABLE ONLY "public"."goals"
+    ADD CONSTRAINT "goals_pkey" PRIMARY KEY ("id");
+
+ALTER TABLE ONLY "public"."logs"
+    ADD CONSTRAINT "logs_pkey" PRIMARY KEY ("id");
+
+ALTER TABLE ONLY "public"."participants"
+    ADD CONSTRAINT "participants_id_key" UNIQUE ("id");
+
+ALTER TABLE ONLY "public"."participants"
+    ADD CONSTRAINT "participants_pkey" PRIMARY KEY ("id");
+
+ALTER TABLE ONLY "public"."memories"
+    ADD CONSTRAINT "reflections_pkey" PRIMARY KEY ("id");
+
+ALTER TABLE ONLY "public"."rooms"
+    ADD CONSTRAINT "rooms_pkey" PRIMARY KEY ("id");
+
+ALTER TABLE ONLY "public"."accounts"
+    ADD CONSTRAINT "users_email_key" UNIQUE ("email");
+
+ALTER TABLE ONLY "public"."accounts"
+    ADD CONSTRAINT "users_pkey" PRIMARY KEY ("id");
+
+CREATE OR REPLACE TRIGGER "trigger_after_account_created" AFTER INSERT ON "public"."accounts" FOR EACH ROW EXECUTE FUNCTION "public"."after_account_created"();
+
+CREATE OR REPLACE TRIGGER "trigger_create_friendship_with_host_agent" AFTER INSERT ON "public"."accounts" FOR EACH ROW EXECUTE FUNCTION "public"."create_friendship_with_host_agent"();
+
+ALTER TABLE ONLY "public"."participants"
+    ADD CONSTRAINT "participants_room_id_fkey" FOREIGN KEY ("room_id") REFERENCES "public"."rooms"("id");
+
+ALTER TABLE ONLY "public"."participants"
+    ADD CONSTRAINT "participants_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."accounts"("id");
+
+ALTER TABLE ONLY "public"."memories"
+    ADD CONSTRAINT "reflections_room_id_fkey" FOREIGN KEY ("room_id") REFERENCES "public"."rooms"("id");
+
+ALTER TABLE ONLY "public"."memories"
+    ADD CONSTRAINT "reflections_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."accounts"("id");
+
+ALTER TABLE ONLY "public"."relationships"
+    ADD CONSTRAINT "relationships_room_id_fkey" FOREIGN KEY ("room_id") REFERENCES "public"."rooms"("id") ON UPDATE CASCADE ON DELETE CASCADE;
+
+ALTER TABLE ONLY "public"."relationships"
+    ADD CONSTRAINT "relationships_user_a_fkey" FOREIGN KEY ("user_a") REFERENCES "public"."accounts"("id");
+
+ALTER TABLE ONLY "public"."relationships"
+    ADD CONSTRAINT "relationships_user_b_fkey" FOREIGN KEY ("user_b") REFERENCES "public"."accounts"("id");
+
+ALTER TABLE ONLY "public"."relationships"
+    ADD CONSTRAINT "relationships_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."accounts"("id");
+
+ALTER TABLE ONLY "public"."rooms"
+    ADD CONSTRAINT "rooms_created_by_fkey" FOREIGN KEY ("created_by") REFERENCES "public"."accounts"("id");
+
+CREATE POLICY "Can select and update all data" ON "public"."accounts" USING (("auth"."uid"() = "id")) WITH CHECK (("auth"."uid"() = "id"));
+
+CREATE POLICY "Enable delete for users based on user_id" ON "public"."goals" FOR DELETE TO "authenticated" USING (("auth"."uid"() = "user_id"));
+
+CREATE POLICY "Enable insert for authenticated users only" ON "public"."accounts" FOR INSERT TO "authenticated", "anon", "service_role", "supabase_replication_admin", "supabase_read_only_user" WITH CHECK (true);
+
+CREATE POLICY "Enable insert for authenticated users only" ON "public"."goals" FOR INSERT TO "authenticated" WITH CHECK (true);
+
+CREATE POLICY "Enable insert for authenticated users only" ON "public"."logs" FOR INSERT TO "authenticated", "anon" WITH CHECK (true);
+
+CREATE POLICY "Enable insert for authenticated users only" ON "public"."participants" FOR INSERT TO "authenticated" WITH CHECK (true);
+
+CREATE POLICY "Enable insert for authenticated users only" ON "public"."relationships" FOR INSERT TO "authenticated" WITH CHECK ((("auth"."uid"() = "user_a") OR ("auth"."uid"() = "user_b")));
+
+CREATE POLICY "Enable insert for authenticated users only" ON "public"."rooms" FOR INSERT WITH CHECK (true);
+
+CREATE POLICY "Enable insert for self id" ON "public"."participants" USING (("auth"."uid"() = "user_id")) WITH CHECK (("auth"."uid"() = "user_id"));
+
+CREATE POLICY "Enable read access for all users" ON "public"."accounts" FOR SELECT USING (true);
+
+CREATE POLICY "Enable read access for all users" ON "public"."goals" FOR SELECT USING (true);
+
+CREATE POLICY "Enable read access for all users" ON "public"."relationships" FOR SELECT TO "authenticated" USING (true);
+
+CREATE POLICY "Enable read access for all users" ON "public"."rooms" FOR SELECT TO "authenticated" USING (true);
+
+CREATE POLICY "Enable read access for own rooms" ON "public"."participants" FOR SELECT TO "authenticated" USING (("auth"."uid"() = "user_id"));
+
+CREATE POLICY "Enable read access for user to their own relationships" ON "public"."relationships" FOR SELECT TO "authenticated" USING ((("auth"."uid"() = "user_a") OR ("auth"."uid"() = "user_b")));
+
+CREATE POLICY "Enable update for users based on email" ON "public"."goals" FOR UPDATE TO "authenticated" USING (true) WITH CHECK (true);
+
+CREATE POLICY "Enable update for users of own id" ON "public"."rooms" FOR UPDATE USING (true) WITH CHECK (true);
+
+CREATE POLICY "Enable users to delete their own relationships/friendships" ON "public"."relationships" FOR DELETE TO "authenticated" USING ((("auth"."uid"() = "user_a") OR ("auth"."uid"() = "user_b")));
+
+ALTER TABLE "public"."accounts" ENABLE ROW LEVEL SECURITY;
+
+ALTER TABLE "public"."goals" ENABLE ROW LEVEL SECURITY;
+
+ALTER TABLE "public"."logs" ENABLE ROW LEVEL SECURITY;
+
+ALTER TABLE "public"."memories" ENABLE ROW LEVEL SECURITY;
+
+ALTER TABLE "public"."participants" ENABLE ROW LEVEL SECURITY;
+
+ALTER TABLE "public"."relationships" ENABLE ROW LEVEL SECURITY;
+
+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 "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 "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 "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 "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 "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 "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 "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 "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 "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 "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 "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 "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 "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 "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 "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 "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 "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 "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 "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 "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 "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