diff --git a/.dev.vars.example b/.dev.vars.example index e2470ea..b2bc838 100644 --- a/.dev.vars.example +++ b/.dev.vars.example @@ -1,4 +1,4 @@ -SUPABASE_URL=https://.supabase.co -SUPABASE_SERVICE_API_KEY= +SUPABASE_URL=http://127.0.0.1:54321 +SUPABASE_SERVICE_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU OPENAI_API_KEY=sk- NODE_ENV=development \ No newline at end of file diff --git a/README.md b/README.md index 3480be0..9d24cd4 100644 --- a/README.md +++ b/README.md @@ -49,24 +49,38 @@ SUPABASE_SERVICE_API_KEY="your-supabase-service-api-key" OPENAI_API_KEY="your-openai-api-key" ``` +### 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). + +Once you have the CLI installed, you can run the following commands to set up a local Supabase instance: + +```bash +supabase start +``` + +You can now start the bgent project with `npm run dev` and it will connect to the local Supabase instance by default. ### Supabase Cloud Setup This library uses Supabase as a database. You can set up a free account at [supabase.io](https://supabase.io) and create a new project. -Step 1: On the Subase All Projects Dashboard, select “New Project”. -Step 2: Select the organization to store the new project in, assign a database name, password and region. -Step 3: Select “Create New Project”. -Step 4: Wait for the database to setup. This will take a few minutes as supabase setups various directories. -Step 5: Select the “SQL Editor” tab from the left navigation menu. -Step 6: Copy in your own SQL dump file or optionally use the provided file in the bgent directory at: "src/supabase/db.sql". Note: You can use the command "supabase db dump" if you have a pre-exisiting supabase database to generate the SQL dump file. -Step 7: Paste the SQL code into the SQL Editor and hit run in the bottom right. -Step 8: Select the “Databases” tab from the left navigation menu to verify all of the tables have been added properly. + +- Step 1: On the Subase All Projects Dashboard, select “New Project”. +- Step 2: Select the organization to store the new project in, assign a database name, password and region. +- Step 3: Select “Create New Project”. +- Step 4: Wait for the database to setup. This will take a few minutes as supabase setups various directories. +- Step 5: Select the “SQL Editor” tab from the left navigation menu. +- Step 6: Copy in your own SQL dump file or optionally use the provided file in the bgent directory at: "src/supabase/db.sql". Note: You can use the command "supabase db dump" if you have a pre-exisiting supabase database to generate the SQL dump file. +- Step 7: Paste the SQL code into the SQL Editor and hit run in the bottom right. +- Step 8: Select the “Databases” tab from the left navigation menu to verify all of the tables have been added properly. + +Once you've set up your Supabase project, you can find your API key by going to the "Settings" tab and then "API". You will need to set the `SUPABASE_URL` and `SUPABASE_SERVICE_API_KEY` environment variables in your `.dev.vars` file. ## Development ``` npm run dev # start the server -npm run shell:dev # start the shell in another terminal +npm run shell # start the shell in another terminal to talk to the default agent ``` ## Usage diff --git a/docs/docs/functions/createRelationship.md b/docs/docs/functions/createRelationship.md new file mode 100644 index 0000000..3f9e8f7 --- /dev/null +++ b/docs/docs/functions/createRelationship.md @@ -0,0 +1,22 @@ +--- +id: "createRelationship" +title: "Function: createRelationship" +sidebar_label: "createRelationship" +sidebar_position: 0 +custom_edit_url: null +--- + +▸ **createRelationship**(`«destructured»`): `Promise`\<`boolean`\> + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `«destructured»` | `Object` | +| › `runtime` | [`BgentRuntime`](../classes/BgentRuntime.md) | +| › `userA` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` | +| › `userB` | \`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\` | + +#### Returns + +`Promise`\<`boolean`\> diff --git a/docs/docs/functions/formatRelationships.md b/docs/docs/functions/formatRelationships.md new file mode 100644 index 0000000..f0b3609 --- /dev/null +++ b/docs/docs/functions/formatRelationships.md @@ -0,0 +1,21 @@ +--- +id: "formatRelationships" +title: "Function: formatRelationships" +sidebar_label: "formatRelationships" +sidebar_position: 0 +custom_edit_url: null +--- + +▸ **formatRelationships**(`«destructured»`): `Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]\> + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `«destructured»` | `Object` | +| › `runtime` | [`BgentRuntime`](../classes/BgentRuntime.md) | +| › `userId` | `string` | + +#### Returns + +`Promise`\<\`$\{string}-$\{string}-$\{string}-$\{string}-$\{string}\`[]\> diff --git a/docs/docs/functions/getRelationship.md b/docs/docs/functions/getRelationship.md new file mode 100644 index 0000000..fa8fe06 --- /dev/null +++ b/docs/docs/functions/getRelationship.md @@ -0,0 +1,22 @@ +--- +id: "getRelationship" +title: "Function: getRelationship" +sidebar_label: "getRelationship" +sidebar_position: 0 +custom_edit_url: null +--- + +▸ **getRelationship**(`«destructured»`): `Promise`\<`any`\> + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `«destructured»` | `Object` | +| › `runtime` | [`BgentRuntime`](../classes/BgentRuntime.md) | +| › `userA` | `string` | +| › `userB` | `string` | + +#### Returns + +`Promise`\<`any`\> diff --git a/docs/docs/functions/getRelationships.md b/docs/docs/functions/getRelationships.md new file mode 100644 index 0000000..6a5ca9d --- /dev/null +++ b/docs/docs/functions/getRelationships.md @@ -0,0 +1,21 @@ +--- +id: "getRelationships" +title: "Function: getRelationships" +sidebar_label: "getRelationships" +sidebar_position: 0 +custom_edit_url: null +--- + +▸ **getRelationships**(`«destructured»`): `Promise`\<`Relationship`[]\> + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `«destructured»` | `Object` | +| › `runtime` | [`BgentRuntime`](../classes/BgentRuntime.md) | +| › `userId` | `string` | + +#### Returns + +`Promise`\<`Relationship`[]\> diff --git a/docs/docs/index.md b/docs/docs/index.md index 347419c..6ee504b 100644 --- a/docs/docs/index.md +++ b/docs/docs/index.md @@ -73,7 +73,7 @@ Step 8: Select the “Databases” tab from the left navigation menu to verify a ``` npm run dev # start the server -npm run shell:dev # start the shell in another terminal +npm run shell # start the shell in another terminal ``` ## Usage diff --git a/docs/docs/modules.md b/docs/docs/modules.md index bf87af7..7487f59 100644 --- a/docs/docs/modules.md +++ b/docs/docs/modules.md @@ -50,6 +50,7 @@ custom_edit_url: null - [composeActionExamples](functions/composeActionExamples.md) - [composeContext](functions/composeContext.md) - [createGoal](functions/createGoal.md) +- [createRelationship](functions/createRelationship.md) - [finishGoal](functions/finishGoal.md) - [finishGoalObjective](functions/finishGoalObjective.md) - [formatActionConditions](functions/formatActionConditions.md) @@ -65,8 +66,11 @@ custom_edit_url: null - [formatGoalsAsString](functions/formatGoalsAsString.md) - [formatLore](functions/formatLore.md) - [formatMessages](functions/formatMessages.md) +- [formatRelationships](functions/formatRelationships.md) - [getActorDetails](functions/getActorDetails.md) - [getFormattedActions](functions/getFormattedActions.md) - [getGoals](functions/getGoals.md) - [getLore](functions/getLore.md) +- [getRelationship](functions/getRelationship.md) +- [getRelationships](functions/getRelationships.md) - [updateGoals](functions/updateGoals.md) diff --git a/package-lock.json b/package-lock.json index dd9951c..b4f9b28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,6 +44,7 @@ "rimraf": "^5.0.5", "rollup": "^2.79.1", "rollup-plugin-terser": "^7.0.0", + "supabase": "^1.145.4", "ts-jest": "^29.1.2", "tslib": "^2.6.2", "typescript": "^5.3.3", @@ -2640,6 +2641,18 @@ "node": ">=0.4.0" } }, + "node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2940,6 +2953,46 @@ } ] }, + "node_modules/bin-links": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.3.tgz", + "integrity": "sha512-obsRaULtJurnfox/MDwgq6Yo9kzbv1CPTk/1/s7Z/61Lezc8IKkFCOXNeVLXz0456WRzBQmSsDWlai2tIhBsfA==", + "dev": true, + "dependencies": { + "cmd-shim": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "read-cmd-shim": "^4.0.0", + "write-file-atomic": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/bin-links/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/bin-links/node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -3208,6 +3261,15 @@ "node": ">= 6" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -3364,6 +3426,15 @@ "node": ">=0.8" } }, + "node_modules/cmd-shim": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.2.tgz", + "integrity": "sha512-+FFYbB0YLaAkhkcrjkyNLYDiOsFSfRjwjY19LXk/psmMx1z00xlCv7hhQoTGXXIKi+YXHL/iiFo8NqMVQX9nOw==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -4257,6 +4328,29 @@ "bser": "2.1.1" } }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/figlet": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.7.0.tgz", @@ -4435,6 +4529,48 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4791,6 +4927,19 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "node_modules/https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -7147,6 +7296,49 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -7198,6 +7390,52 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dev": true, + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "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", @@ -7249,6 +7487,15 @@ "node": ">=0.10.0" } }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/npm-run-all": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", @@ -7946,6 +8193,15 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, + "node_modules/read-cmd-shim": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz", + "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -8809,6 +9065,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/supabase": { + "version": "1.145.4", + "resolved": "https://registry.npmjs.org/supabase/-/supabase-1.145.4.tgz", + "integrity": "sha512-j6OvAQjTNcJ8SBlqZpUTFJ7C3iXliZ8VjcleFvUBAlFLqot1EhXT8tqSLZiOP1B91Ks2DPOxT8D94cAIWYWvLQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "bin-links": "^4.0.3", + "https-proxy-agent": "^7.0.2", + "node-fetch": "^3.3.2", + "tar": "6.2.0" + }, + "bin": { + "supabase": "bin/supabase" + }, + "engines": { + "npm": ">=8" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -8848,6 +9123,38 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/tar": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "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, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/terser": { "version": "5.27.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz", @@ -9323,6 +9630,15 @@ "defaults": "^1.0.3" } }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", diff --git a/package.json b/package.json index 79a7cb6..06e12a6 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "lint": "eslint --ext .ts --ext .js . --fix", "dev": "wrangler dev -- --dev", "start:docs": "cd docs && npm run start", - "shell:dev": "node --no-warnings scripts/shell.mjs --dev", + "shell": "node --no-warnings scripts/shell.mjs --dev", "concat": "node ./scripts/concat.mjs", "shell:cloud": "node --no-warnings scripts/shell.mjs", "test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest", @@ -46,6 +46,7 @@ "rimraf": "^5.0.5", "rollup": "^2.79.1", "rollup-plugin-terser": "^7.0.0", + "supabase": "^1.145.4", "ts-jest": "^29.1.2", "tslib": "^2.6.2", "typescript": "^5.3.3", diff --git a/src/agents/cj/actions/__tests__/introduce.test.ts b/src/agents/cj/actions/__tests__/introduce.test.ts index a9ed6ea..6199e83 100644 --- a/src/agents/cj/actions/__tests__/introduce.test.ts +++ b/src/agents/cj/actions/__tests__/introduce.test.ts @@ -1,7 +1,7 @@ import dotenv from "dotenv"; import { type UUID } from "crypto"; -import { getRelationship } from "../../relationships"; +import { getRelationship } from "../../../../lib/relationships"; import { type Message } from "../../../../lib/types"; import { createRuntime } from "../../../../test/createRuntime"; import { diff --git a/src/agents/cj/actions/introduce.ts b/src/agents/cj/actions/introduce.ts index 6748e1d..16006e8 100644 --- a/src/agents/cj/actions/introduce.ts +++ b/src/agents/cj/actions/introduce.ts @@ -1,6 +1,6 @@ import { type BgentRuntime } from "../../../lib"; import { composeContext } from "../../../lib/context"; -import { createRelationship } from "../relationships"; +import { createRelationship } from "../../../lib/relationships"; import { Action, type Message, type State } from "../../../lib/types"; import { parseJSONObjectFromText } from "../../../lib/utils"; diff --git a/src/agents/cj/evaluators/__tests__/details.test.ts b/src/agents/cj/evaluators/__tests__/details.test.ts index be62368..c32df5d 100644 --- a/src/agents/cj/evaluators/__tests__/details.test.ts +++ b/src/agents/cj/evaluators/__tests__/details.test.ts @@ -1,7 +1,7 @@ import dotenv from "dotenv"; import { type UUID } from "crypto"; -import { getRelationship } from "../../relationships"; +import { getRelationship } from "../../../../lib/relationships"; import { type Message } from "../../../../lib/types"; import { createRuntime } from "../../../../test/createRuntime"; import { diff --git a/src/agents/cj/evaluators/__tests__/profile.test.ts b/src/agents/cj/evaluators/__tests__/profile.test.ts index 923c661..a71db3b 100644 --- a/src/agents/cj/evaluators/__tests__/profile.test.ts +++ b/src/agents/cj/evaluators/__tests__/profile.test.ts @@ -1,7 +1,7 @@ import dotenv from "dotenv"; import { type UUID } from "crypto"; -import { getRelationship } from "../../relationships"; +import { getRelationship } from "../../../../lib/relationships"; import { type Message } from "../../../../lib/types"; import { createRuntime } from "../../../../test/createRuntime"; import { diff --git a/src/agents/cj/evaluators/profile.ts b/src/agents/cj/evaluators/profile.ts index cc007d5..655d4df 100644 --- a/src/agents/cj/evaluators/profile.ts +++ b/src/agents/cj/evaluators/profile.ts @@ -1,6 +1,6 @@ import { type UUID } from "crypto"; import { type BgentRuntime } from "../../../lib"; -import { getRelationship } from "../relationships"; +import { getRelationship } from "../../../lib/relationships"; import { composeContext } from "../../../lib/context"; import { type Evaluator, diff --git a/src/lib/__tests__/actions.test.ts b/src/lib/__tests__/actions.test.ts index b37223c..76662bd 100644 --- a/src/lib/__tests__/actions.test.ts +++ b/src/lib/__tests__/actions.test.ts @@ -3,7 +3,7 @@ import { type UUID } from "crypto"; import dotenv from "dotenv"; import { createRuntime } from "../../test/createRuntime"; import { TEST_ACTION, TEST_ACTION_FAIL } from "../../test/testAction"; -import { getRelationship } from "../../agents/cj/relationships"; +import { getRelationship } from "../relationships"; import { type BgentRuntime } from "../runtime"; import { type Message } from "../types"; diff --git a/src/lib/__tests__/evaluation.test.ts b/src/lib/__tests__/evaluation.test.ts index 4a4e753..ab5728a 100644 --- a/src/lib/__tests__/evaluation.test.ts +++ b/src/lib/__tests__/evaluation.test.ts @@ -6,7 +6,7 @@ import { TEST_EVALUATOR, TEST_EVALUATOR_FAIL } from "../../test/testEvaluator"; import { composeContext } from "../context"; import { evaluationTemplate } from "../evaluation"; import summarization from "../evaluators/summarization"; -import { getRelationship } from "../../agents/cj/relationships"; +import { getRelationship } from "../relationships"; import { BgentRuntime } from "../runtime"; import { Message } from "../types"; diff --git a/src/lib/__tests__/memory.test.ts b/src/lib/__tests__/memory.test.ts index fbabc08..dab6035 100644 --- a/src/lib/__tests__/memory.test.ts +++ b/src/lib/__tests__/memory.test.ts @@ -3,7 +3,7 @@ import { type UUID } from "crypto"; import dotenv from "dotenv"; import { createRuntime } from "../../test/createRuntime"; import { MemoryManager } from "../memory"; -import { getRelationship } from "../../agents/cj/relationships"; +import { getRelationship } from "../relationships"; import { type Content, type Memory } from "../types"; import { getCachedEmbedding, writeCachedEmbedding } from "../../test/cache"; diff --git a/src/agents/cj/__tests__/relationships.test.ts b/src/lib/__tests__/relationships.test.ts similarity index 92% rename from src/agents/cj/__tests__/relationships.test.ts rename to src/lib/__tests__/relationships.test.ts index 025541e..684c55b 100644 --- a/src/agents/cj/__tests__/relationships.test.ts +++ b/src/lib/__tests__/relationships.test.ts @@ -1,13 +1,13 @@ 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 { 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 "../../../lib/runtime"; +import { BgentRuntime } from "../runtime"; dotenv.config(); diff --git a/src/lib/__tests__/runtime.test.ts b/src/lib/__tests__/runtime.test.ts index 42044e6..fa8c0a4 100644 --- a/src/lib/__tests__/runtime.test.ts +++ b/src/lib/__tests__/runtime.test.ts @@ -1,7 +1,7 @@ import dotenv from "dotenv"; import { createRuntime } from "../../test/createRuntime"; import { type UUID } from "crypto"; -import { getRelationship } from "../../agents/cj/relationships"; +import { getRelationship } from "../relationships"; import { getCachedEmbedding, writeCachedEmbedding } from "../../test/cache"; import { BgentRuntime } from "../runtime"; import { type User } from "@supabase/supabase-js"; diff --git a/src/lib/actions/__tests__/continue.test.ts b/src/lib/actions/__tests__/continue.test.ts index 54bfb53..bea9029 100644 --- a/src/lib/actions/__tests__/continue.test.ts +++ b/src/lib/actions/__tests__/continue.test.ts @@ -4,7 +4,7 @@ import dotenv from "dotenv"; import { createRuntime } from "../../../test/createRuntime"; import { Goodbye1 } from "../../../test/data"; import { populateMemories } from "../../../test/populateMemories"; -import { getRelationship } from "../../../agents/cj/relationships"; +import { getRelationship } from "../../relationships"; import { type BgentRuntime } from "../../runtime"; import { Content, type Message } from "../../types"; import action from "../continue"; diff --git a/src/lib/actions/__tests__/ignore.test.ts b/src/lib/actions/__tests__/ignore.test.ts index a171eb3..7851480 100644 --- a/src/lib/actions/__tests__/ignore.test.ts +++ b/src/lib/actions/__tests__/ignore.test.ts @@ -7,7 +7,7 @@ import { GetTellMeAboutYourselfConversationTroll2, Goodbye1, } from "../../../test/data"; -import { getRelationship } from "../../../agents/cj/relationships"; +import { getRelationship } from "../../relationships"; import { type BgentRuntime } from "../../runtime"; import { Content, type Message } from "../../types"; // import action from "../ignore"; diff --git a/src/lib/actions/__tests__/wait.test.ts b/src/lib/actions/__tests__/wait.test.ts index 9943bdf..e980acd 100644 --- a/src/lib/actions/__tests__/wait.test.ts +++ b/src/lib/actions/__tests__/wait.test.ts @@ -4,7 +4,7 @@ import dotenv from "dotenv"; import { createRuntime } from "../../../test/createRuntime"; import { GetTellMeAboutYourselfConversation1 } from "../../../test/data"; import { populateMemories } from "../../../test/populateMemories"; -import { getRelationship } from "../../../agents/cj/relationships"; +import { getRelationship } from "../../relationships"; import { type BgentRuntime } from "../../runtime"; import { type Message } from "../../types"; import action from "../wait"; // Import the wait action diff --git a/src/lib/evaluators/__tests__/summarization.test.ts b/src/lib/evaluators/__tests__/summarization.test.ts index a798102..b98b137 100644 --- a/src/lib/evaluators/__tests__/summarization.test.ts +++ b/src/lib/evaluators/__tests__/summarization.test.ts @@ -10,7 +10,7 @@ import { jimFacts, } from "../../../test/data"; import { populateMemories } from "../../../test/populateMemories"; -import { getRelationship } from "../../../agents/cj/relationships"; +import { getRelationship } from "../../relationships"; import { type BgentRuntime } from "../../runtime"; import { type Message } from "../../types"; import evaluator from "../summarization"; diff --git a/src/lib/index.ts b/src/lib/index.ts index bfb5a64..45dbd9f 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -7,5 +7,6 @@ export * from "./goals"; export * from "./lore"; export * from "./memory"; export * from "./messages"; +export * from "./relationships"; export * from "./runtime"; export * from "./types"; diff --git a/src/agents/cj/relationships.ts b/src/lib/relationships.ts similarity index 93% rename from src/agents/cj/relationships.ts rename to src/lib/relationships.ts index 5288a62..e360d7d 100644 --- a/src/agents/cj/relationships.ts +++ b/src/lib/relationships.ts @@ -1,6 +1,6 @@ import { type UUID } from "crypto"; -import { type BgentRuntime } from "../../lib/runtime"; -import { type Relationship } from "./types"; +import { type BgentRuntime } from "./runtime"; +import { type Relationship } from "../agents/cj/types"; export async function createRelationship({ runtime, diff --git a/src/test/createRuntime.ts b/src/test/createRuntime.ts index c7bd5fa..914921d 100644 --- a/src/test/createRuntime.ts +++ b/src/test/createRuntime.ts @@ -1,4 +1,4 @@ -import { createClient } from "@supabase/supabase-js"; +import { Session, User, createClient } from "@supabase/supabase-js"; import { BgentRuntime } from "../lib/runtime"; import { TEST_EMAIL, @@ -36,8 +36,8 @@ export async function createRuntime({ email: TEST_EMAIL!, password: TEST_PASSWORD!, }); - user = response.data.user; - session = response.data.session; + user = response.data.user as User; + session = response.data.session as Session; } const runtime = new BgentRuntime({ diff --git a/supabase/.gitignore b/supabase/.gitignore new file mode 100644 index 0000000..a3ad880 --- /dev/null +++ b/supabase/.gitignore @@ -0,0 +1,4 @@ +# Supabase +.branches +.temp +.env diff --git a/supabase/config.toml b/supabase/config.toml new file mode 100644 index 0000000..2081929 --- /dev/null +++ b/supabase/config.toml @@ -0,0 +1,159 @@ +# A string used to distinguish different Supabase projects on the same host. Defaults to the +# working directory name when running `supabase init`. +project_id = "bgent" + +[api] +enabled = true +# Port to use for the API URL. +port = 54321 +# Schemas to expose in your API. Tables, views and stored procedures in this schema will get API +# endpoints. public and storage are always included. +schemas = ["public", "storage", "graphql_public"] +# Extra schemas to add to the search_path of every request. public is always included. +extra_search_path = ["public", "extensions"] +# The maximum number of rows returns from a view, table, or stored procedure. Limits payload size +# for accidental or malicious requests. +max_rows = 1000 + +[db] +# Port to use for the local database URL. +port = 54322 +# Port used by db diff command to initialize the shadow database. +shadow_port = 54320 +# The database major version to use. This has to be the same as your remote database's. Run `SHOW +# server_version;` on the remote database to check. +major_version = 15 + +[db.pooler] +enabled = false +# Port to use for the local connection pooler. +port = 54329 +# Specifies when a server connection can be reused by other clients. +# Configure one of the supported pooler modes: `transaction`, `session`. +pool_mode = "transaction" +# How many server connections to allow per user/database pair. +default_pool_size = 20 +# Maximum number of client connections allowed. +max_client_conn = 100 + +[realtime] +enabled = true +# Bind realtime via either IPv4 or IPv6. (default: IPv6) +# ip_version = "IPv6" +# The maximum length in bytes of HTTP request headers. (default: 4096) +# max_header_length = 4096 + +[studio] +enabled = true +# Port to use for Supabase Studio. +port = 54323 +# External URL of the API server that frontend connects to. +api_url = "http://127.0.0.1" + +# Email testing server. Emails sent with the local dev setup are not actually sent - rather, they +# are monitored, and you can view the emails that would have been sent from the web interface. +[inbucket] +enabled = true +# Port to use for the email testing server web interface. +port = 54324 +# Uncomment to expose additional ports for testing user applications that send emails. +# smtp_port = 54325 +# pop3_port = 54326 + +[storage] +enabled = true +# The maximum file size allowed (e.g. "5MB", "500KB"). +file_size_limit = "50MiB" + +[auth] +enabled = true +# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used +# in emails. +site_url = "http://127.0.0.1:3000" +# A list of *exact* URLs that auth providers are permitted to redirect to post authentication. +additional_redirect_urls = ["https://127.0.0.1:3000"] +# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week). +jwt_expiry = 3600 +# If disabled, the refresh token will never expire. +enable_refresh_token_rotation = true +# Allows refresh tokens to be reused after expiry, up to the specified interval in seconds. +# Requires enable_refresh_token_rotation = true. +refresh_token_reuse_interval = 10 +# Allow/disallow new user signups to your project. +enable_signup = true +# Allow/disallow testing manual linking of accounts +enable_manual_linking = false + +[auth.email] +# Allow/disallow new user signups via email to your project. +enable_signup = true +# If enabled, a user will be required to confirm any email change on both the old, and new email +# addresses. If disabled, only the new email is required to confirm. +double_confirm_changes = true +# If enabled, users need to confirm their email address before signing in. +enable_confirmations = false + +# Uncomment to customize email template +# [auth.email.template.invite] +# subject = "You have been invited" +# content_path = "./supabase/templates/invite.html" + +[auth.sms] +# Allow/disallow new user signups via SMS to your project. +enable_signup = true +# If enabled, users need to confirm their phone number before signing in. +enable_confirmations = false +# Template for sending OTP to users +template = "Your code is {{ .Code }} ." + +# Use pre-defined map of phone number to OTP for testing. +[auth.sms.test_otp] +# 4152127777 = "123456" + +# This hook runs before a token is issued and allows you to add additional claims based on the authentication method used. +[auth.hook.custom_access_token] +# enabled = true +# uri = "pg-functions:////" + + +# Configure one of the supported SMS providers: `twilio`, `twilio_verify`, `messagebird`, `textlocal`, `vonage`. +[auth.sms.twilio] +enabled = false +account_sid = "" +message_service_sid = "" +# DO NOT commit your Twilio auth token to git. Use environment variable substitution instead: +auth_token = "env(SUPABASE_AUTH_SMS_TWILIO_AUTH_TOKEN)" + +# Use an external OAuth provider. The full list of providers are: `apple`, `azure`, `bitbucket`, +# `discord`, `facebook`, `github`, `gitlab`, `google`, `keycloak`, `linkedin_oidc`, `notion`, `twitch`, +# `twitter`, `slack`, `spotify`, `workos`, `zoom`. +[auth.external.apple] +enabled = false +client_id = "" +# DO NOT commit your OAuth provider secret to git. Use environment variable substitution instead: +secret = "env(SUPABASE_AUTH_EXTERNAL_APPLE_SECRET)" +# Overrides the default auth redirectUrl. +redirect_uri = "" +# Overrides the default auth provider URL. Used to support self-hosted gitlab, single-tenant Azure, +# or any other third-party OIDC providers. +url = "" + +[analytics] +enabled = false +port = 54327 +vector_port = 54328 +# Configure one of the supported backends: `postgres`, `bigquery`. +backend = "postgres" + +# Experimental features may be deprecated any time +[experimental] +# Configures Postgres storage engine to use OrioleDB (S3) +orioledb_version = "" +# Configures S3 bucket URL, eg. .s3-.amazonaws.com +s3_host = "env(S3_HOST)" +# Configures S3 bucket region, eg. us-east-1 +s3_region = "env(S3_REGION)" +# Configures AWS_ACCESS_KEY_ID for S3 bucket +s3_access_key = "env(S3_ACCESS_KEY)" +# Configures AWS_SECRET_ACCESS_KEY for S3 bucket +s3_secret_key = "env(S3_SECRET_KEY)" diff --git a/supabase/migrations/20240223051710_remote_schema.sql b/supabase/migrations/20240223051710_remote_schema.sql new file mode 100644 index 0000000..a2962e7 --- /dev/null +++ b/supabase/migrations/20240223051710_remote_schema.sql @@ -0,0 +1,786 @@ + +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"; + +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, is_dm) + VALUES (p_new_user_id, 'Direct Message with Host Agent', TRUE) + 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" 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", + "register_complete" boolean NOT NULL, + "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"."summarizations" ( + "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"."summarizations" ALTER COLUMN "embedding" SET STORAGE EXTENDED; + +ALTER TABLE "public"."summarizations" 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"."summarizations" + 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"."summarizations" + ADD CONSTRAINT "reflections_room_id_fkey" FOREIGN KEY ("room_id") REFERENCES "public"."rooms"("id"); + +ALTER TABLE ONLY "public"."summarizations" + 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"."summarizations" 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"."summarizations" TO "anon"; +GRANT ALL ON TABLE "public"."summarizations" TO "authenticated"; +GRANT ALL ON TABLE "public"."summarizations" 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/seed.sql b/supabase/seed.sql new file mode 100644 index 0000000..e69de29