diff options
| author | Yash <[email protected]> | 2024-04-11 04:52:44 +0000 |
|---|---|---|
| committer | Yash <[email protected]> | 2024-04-11 04:52:44 +0000 |
| commit | 6dcc7d18c9be5e3a5e0a3ff60668424ee0158b4e (patch) | |
| tree | 179aa936536510cc707368fc7c330c4c7fbdc3f8 /apps/cf-ai-backend | |
| parent | novel editor (diff) | |
| parent | save user ID with url to ensure that same website can be saved by users (diff) | |
| download | supermemory-new-ui.tar.xz supermemory-new-ui.zip | |
Merge branch 'main' of https://github.com/Dhravya/supermemory into new-uinew-ui
Diffstat (limited to 'apps/cf-ai-backend')
| -rw-r--r-- | apps/cf-ai-backend/package.json | 26 | ||||
| -rw-r--r-- | apps/cf-ai-backend/pnpm-lock.yaml | 789 | ||||
| -rw-r--r-- | apps/cf-ai-backend/src/OpenAIEmbedder.ts | 16 | ||||
| -rw-r--r-- | apps/cf-ai-backend/src/index.ts | 20 | ||||
| -rw-r--r-- | apps/cf-ai-backend/src/routes.ts | 16 | ||||
| -rw-r--r-- | apps/cf-ai-backend/src/routes/add.ts | 52 | ||||
| -rw-r--r-- | apps/cf-ai-backend/src/routes/ask.ts | 24 | ||||
| -rw-r--r-- | apps/cf-ai-backend/src/routes/chat.ts | 77 | ||||
| -rw-r--r-- | apps/cf-ai-backend/src/routes/query.ts | 58 |
9 files changed, 942 insertions, 136 deletions
diff --git a/apps/cf-ai-backend/package.json b/apps/cf-ai-backend/package.json index b60ea18b..342fb7ff 100644 --- a/apps/cf-ai-backend/package.json +++ b/apps/cf-ai-backend/package.json @@ -1,15 +1,15 @@ { - "name": "cf-ai-backend", - "version": "0.0.0", - "private": true, - "scripts": { - "deploy": "wrangler deploy", - "dev": "wrangler dev", - "start": "wrangler dev" - }, - "devDependencies": { - "@cloudflare/workers-types": "^4.20240222.0", - "typescript": "^5.0.4", - "wrangler": "^3.0.0" - } + "name": "cf-ai-backend", + "version": "0.0.0", + "private": true, + "scripts": { + "deploy": "wrangler deploy", + "dev": "wrangler dev", + "start": "wrangler dev" + }, + "devDependencies": { + "@cloudflare/workers-types": "^4.20240222.0", + "typescript": "^5.0.4", + "wrangler": "^3.0.0" + } } diff --git a/apps/cf-ai-backend/pnpm-lock.yaml b/apps/cf-ai-backend/pnpm-lock.yaml new file mode 100644 index 00000000..5c85a415 --- /dev/null +++ b/apps/cf-ai-backend/pnpm-lock.yaml @@ -0,0 +1,789 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +devDependencies: + '@cloudflare/workers-types': + specifier: ^4.20240222.0 + version: 4.20240222.0 + typescript: + specifier: ^5.0.4 + version: 5.3.3 + wrangler: + specifier: ^3.0.0 + version: 3.29.0(@cloudflare/[email protected]) + +packages: + /@cloudflare/[email protected]: + resolution: { integrity: sha512-lKN2XCfKCmpKb86a1tl4GIwsJYDy9TGuwjhDELLmpKygQhw8X2xR4dusgpC5Tg7q1pB96Eb0rBo81kxSILQMwA== } + dependencies: + mime: 3.0.0 + dev: true + + /@cloudflare/[email protected]: + resolution: { integrity: sha512-64qjsCUz6VtjXnUex5D6dWoJDuUBRw1ps2TEVH9wGJ4ubiLVUxKhj3bzkVy0RoJ8FhaCKzJWWRyTo4yc192UTA== } + engines: { node: '>=16' } + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@cloudflare/[email protected]: + resolution: { integrity: sha512-eVQrAV200LhwLY6JZLx3l2lDrjsTC86lqnvH+RSeM43bAcdneC6lVfykHnTaOTgYFvYQbqRkn9ICWxXj1V9L5g== } + engines: { node: '>=16' } + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@cloudflare/[email protected]: + resolution: { integrity: sha512-ivZ2UuCvi44j8JZ++XlQzSYajt5ptvAdwlh3WPpCcygtHXEh6SVo8QXEUOXhPbv861C0HZMYxLCaLqlpQDWB8g== } + engines: { node: '>=16' } + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@cloudflare/[email protected]: + resolution: { integrity: sha512-aLfvl9kXQKbM7aLvfL0HbOt5VEgv15mEZGyFKyDldJ8+nOXH6nYPma1ccwF8BHmu8otHc420eyPr2xPKhLSJnw== } + engines: { node: '>=16' } + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@cloudflare/[email protected]: + resolution: { integrity: sha512-Y6KMukWnorsSmPx6d82IuJ4SU8sX1+2y+w1uFJ76sucSgXqUAN1fmjG+EyzRVbcbsxRGBCD9c1Pn8T1amMLEYA== } + engines: { node: '>=16' } + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@cloudflare/[email protected]: + resolution: { integrity: sha512-luO0BdK3rLlCv3B240+cTrfqm+XSbHtpk+88aJtGwzyVK9QF/Xz8lBgE/oZZLN8nCTmOvxAZnszyxUuZ8GP8Cg== } + dev: true + + /@cspotcode/[email protected]: + resolution: { integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== } + engines: { node: '>=12' } + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: true + + /@esbuild-plugins/[email protected]([email protected]): + resolution: { integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw== } + peerDependencies: + esbuild: '*' + dependencies: + esbuild: 0.17.19 + dev: true + + /@esbuild-plugins/[email protected]([email protected]): + resolution: { integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA== } + peerDependencies: + esbuild: '*' + dependencies: + esbuild: 0.17.19 + escape-string-regexp: 4.0.0 + rollup-plugin-node-polyfills: 0.2.1 + dev: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA== } + engines: { node: '>=12' } + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A== } + engines: { node: '>=12' } + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww== } + engines: { node: '>=12' } + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg== } + engines: { node: '>=12' } + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw== } + engines: { node: '>=12' } + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ== } + engines: { node: '>=12' } + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ== } + engines: { node: '>=12' } + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg== } + engines: { node: '>=12' } + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA== } + engines: { node: '>=12' } + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ== } + engines: { node: '>=12' } + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ== } + engines: { node: '>=12' } + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A== } + engines: { node: '>=12' } + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg== } + engines: { node: '>=12' } + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA== } + engines: { node: '>=12' } + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q== } + engines: { node: '>=12' } + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw== } + engines: { node: '>=12' } + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q== } + engines: { node: '>=12' } + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g== } + engines: { node: '>=12' } + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg== } + engines: { node: '>=12' } + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag== } + engines: { node: '>=12' } + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw== } + engines: { node: '>=12' } + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/[email protected]: + resolution: { integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA== } + engines: { node: '>=12' } + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@fastify/[email protected]: + resolution: { integrity: sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA== } + engines: { node: '>=14' } + dev: true + + /@jridgewell/[email protected]: + resolution: { integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== } + engines: { node: '>=6.0.0' } + dev: true + + /@jridgewell/[email protected]: + resolution: { integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== } + dev: true + + /@jridgewell/[email protected]: + resolution: { integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== } + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@types/[email protected]: + resolution: { integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ== } + dependencies: + '@types/node': 20.11.20 + dev: true + + /@types/[email protected]: + resolution: { integrity: sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg== } + dependencies: + undici-types: 5.26.5 + dev: true + + resolution: { integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== } + engines: { node: '>=0.4.0' } + dev: true + + resolution: { integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== } + engines: { node: '>=0.4.0' } + hasBin: true + dev: true + + resolution: { integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== } + engines: { node: '>= 8' } + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + resolution: { integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ== } + dependencies: + printable-characters: 1.0.42 + dev: true + + resolution: { integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== } + engines: { node: '>=8' } + dev: true + + resolution: { integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g== } + dev: true + + resolution: { integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== } + engines: { node: '>=8' } + dependencies: + fill-range: 7.0.1 + dev: true + + resolution: { integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g== } + dependencies: + debug: 4.3.4 + tslib: 2.6.2 + transitivePeerDependencies: + - supports-color + dev: true + + resolution: { integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== } + engines: { node: '>= 8.10.0' } + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + resolution: { integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== } + engines: { node: '>= 0.6' } + dev: true + + resolution: { integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA== } + dev: true + + resolution: { integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== } + engines: { node: '>=6.0' } + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + resolution: { integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw== } + engines: { node: '>=12' } + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.17.19 + '@esbuild/android-arm64': 0.17.19 + '@esbuild/android-x64': 0.17.19 + '@esbuild/darwin-arm64': 0.17.19 + '@esbuild/darwin-x64': 0.17.19 + '@esbuild/freebsd-arm64': 0.17.19 + '@esbuild/freebsd-x64': 0.17.19 + '@esbuild/linux-arm': 0.17.19 + '@esbuild/linux-arm64': 0.17.19 + '@esbuild/linux-ia32': 0.17.19 + '@esbuild/linux-loong64': 0.17.19 + '@esbuild/linux-mips64el': 0.17.19 + '@esbuild/linux-ppc64': 0.17.19 + '@esbuild/linux-riscv64': 0.17.19 + '@esbuild/linux-s390x': 0.17.19 + '@esbuild/linux-x64': 0.17.19 + '@esbuild/netbsd-x64': 0.17.19 + '@esbuild/openbsd-x64': 0.17.19 + '@esbuild/sunos-x64': 0.17.19 + '@esbuild/win32-arm64': 0.17.19 + '@esbuild/win32-ia32': 0.17.19 + '@esbuild/win32-x64': 0.17.19 + dev: true + + resolution: { integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== } + engines: { node: '>=10' } + dev: true + + resolution: { integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== } + dev: true + + resolution: { integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw== } + engines: { node: '>=6' } + dev: true + + resolution: { integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== } + engines: { node: '>=8' } + dependencies: + to-regex-range: 5.0.1 + dev: true + + resolution: { integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + os: [darwin] + requiresBuild: true + dev: true + optional: true + + resolution: { integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== } + dev: true + + resolution: { integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w== } + dependencies: + data-uri-to-buffer: 2.0.2 + source-map: 0.6.1 + dev: true + + resolution: { integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== } + engines: { node: '>= 6' } + dependencies: + is-glob: 4.0.3 + dev: true + + resolution: { integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== } + dev: true + + resolution: { integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA== } + engines: { node: '>= 0.4' } + dependencies: + function-bind: 1.1.2 + dev: true + + resolution: { integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== } + engines: { node: '>=8' } + dependencies: + binary-extensions: 2.2.0 + dev: true + + resolution: { integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== } + dependencies: + hasown: 2.0.1 + dev: true + + resolution: { integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== } + engines: { node: '>=0.10.0' } + dev: true + + resolution: { integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== } + engines: { node: '>=0.10.0' } + dependencies: + is-extglob: 2.1.1 + dev: true + + resolution: { integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== } + engines: { node: '>=0.12.0' } + dev: true + + resolution: { integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== } + dependencies: + sourcemap-codec: 1.4.8 + dev: true + + resolution: { integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== } + engines: { node: '>=10.0.0' } + hasBin: true + dev: true + + resolution: { integrity: sha512-NnP3MQFh2pV7iETNmJzSlMBF/KhRA+XT4A7JLCfxunadQSPbTMMgbsZo9EfLloMwHMUhZGNVot3Pvh+VnT2joQ== } + engines: { node: '>=16.13' } + hasBin: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + acorn: 8.11.3 + acorn-walk: 8.3.2 + capnp-ts: 0.7.0 + exit-hook: 2.2.1 + glob-to-regexp: 0.4.1 + stoppable: 1.1.0 + undici: 5.28.3 + workerd: 1.20240208.0 + ws: 8.16.0 + youch: 3.3.3 + zod: 3.22.4 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + resolution: { integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== } + dev: true + + resolution: { integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ== } + hasBin: true + dev: true + + resolution: { integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } + hasBin: true + dev: true + + resolution: { integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== } + engines: { node: '>= 6.13.0' } + dev: true + + resolution: { integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== } + engines: { node: '>=0.10.0' } + dev: true + + resolution: { integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== } + dev: true + + resolution: { integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw== } + dev: true + + resolution: { integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== } + engines: { node: '>=8.6' } + dev: true + + resolution: { integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ== } + dev: true + + resolution: { integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== } + engines: { node: '>=8.10.0' } + dependencies: + picomatch: 2.3.1 + dev: true + + resolution: { integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== } + engines: { node: '>=10' } + dev: true + + resolution: { integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== } + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + resolution: { integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w== } + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. + dependencies: + estree-walker: 0.6.1 + magic-string: 0.25.9 + rollup-pluginutils: 2.8.2 + dev: true + + resolution: { integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA== } + dependencies: + rollup-plugin-inject: 3.0.2 + dev: true + + resolution: { integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== } + dependencies: + estree-walker: 0.6.1 + dev: true + + resolution: { integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== } + engines: { node: '>=10' } + dependencies: + '@types/node-forge': 1.3.11 + node-forge: 1.3.1 + dev: true + + resolution: { integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== } + engines: { node: '>=0.10.0' } + dev: true + + resolution: { integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== } + deprecated: Please use @jridgewell/sourcemap-codec instead + dev: true + + resolution: { integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw== } + dependencies: + as-table: 1.0.55 + get-source: 2.0.12 + dev: true + + resolution: { integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw== } + engines: { node: '>=4', npm: '>=6' } + dev: true + + resolution: { integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== } + engines: { node: '>= 0.4' } + dev: true + + resolution: { integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== } + engines: { node: '>=8.0' } + dependencies: + is-number: 7.0.0 + dev: true + + resolution: { integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== } + dev: true + + resolution: { integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== } + engines: { node: '>=14.17' } + hasBin: true + dev: true + + resolution: { integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== } + dev: true + + resolution: { integrity: sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA== } + engines: { node: '>=14.0' } + dependencies: + '@fastify/busboy': 2.1.0 + dev: true + + resolution: { integrity: sha512-edFdwHU95Ww2SmjBvBJhbc7hhVXMEo6Y7qqSWCl6W9lGScTlCMCXd4AU3f/EGJ3P++FC+CWqu+XuAywebbKF2Q== } + engines: { node: '>=16' } + hasBin: true + requiresBuild: true + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20240208.0 + '@cloudflare/workerd-darwin-arm64': 1.20240208.0 + '@cloudflare/workerd-linux-64': 1.20240208.0 + '@cloudflare/workerd-linux-arm64': 1.20240208.0 + '@cloudflare/workerd-windows-64': 1.20240208.0 + dev: true + + /[email protected](@cloudflare/[email protected]): + resolution: { integrity: sha512-VXUUltM0/fxCF20Z3tH39zpnykDJNPH2lMWI5wA0VmRpuKG0Gffjj5lU2vJaI/PfUCo3q4JErxWcgLezBGnFyA== } + engines: { node: '>=16.17.0' } + hasBin: true + peerDependencies: + '@cloudflare/workers-types': ^4.20230914.0 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + dependencies: + '@cloudflare/kv-asset-handler': 0.3.1 + '@cloudflare/workers-types': 4.20240222.0 + '@esbuild-plugins/node-globals-polyfill': 0.2.3([email protected]) + '@esbuild-plugins/node-modules-polyfill': 0.2.2([email protected]) + blake3-wasm: 2.1.5 + chokidar: 3.6.0 + esbuild: 0.17.19 + miniflare: 3.20240208.0 + nanoid: 3.3.7 + path-to-regexp: 6.2.1 + resolve: 1.22.8 + resolve.exports: 2.0.2 + selfsigned: 2.4.1 + source-map: 0.6.1 + xxhash-wasm: 1.0.2 + optionalDependencies: + fsevents: 2.3.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + resolution: { integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== } + engines: { node: '>=10.0.0' } + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + + resolution: { integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A== } + dev: true + + resolution: { integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA== } + dependencies: + cookie: 0.5.0 + mustache: 4.2.0 + stacktracey: 2.1.8 + dev: true + + resolution: { integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg== } + dev: true diff --git a/apps/cf-ai-backend/src/OpenAIEmbedder.ts b/apps/cf-ai-backend/src/OpenAIEmbedder.ts index 35c36c74..e227d1e3 100644 --- a/apps/cf-ai-backend/src/OpenAIEmbedder.ts +++ b/apps/cf-ai-backend/src/OpenAIEmbedder.ts @@ -1,4 +1,4 @@ -import { AiTextGenerationOutput } from "@cloudflare/ai/dist/ai/tasks/text-generation"; +import { AiTextGenerationOutput } from '@cloudflare/ai/dist/ai/tasks/text-generation'; interface OpenAIEmbeddingsParams { apiKey: string; @@ -15,7 +15,7 @@ export class OpenAIEmbeddings { } async embedDocuments(texts: string[]): Promise<number[][]> { - const responses = await Promise.all(texts.map(text => this.embedQuery(text))); + const responses = await Promise.all(texts.map((text) => this.embedQuery(text))); return responses; } @@ -24,18 +24,18 @@ export class OpenAIEmbeddings { method: 'POST', headers: { 'Content-Type': 'application/json', - 'Authorization': `Bearer ${this.apiKey}` + Authorization: `Bearer ${this.apiKey}`, }, body: JSON.stringify({ input: text, - model: this.modelName - }) + model: this.modelName, + }), }); - const data = await response.json() as { + const data = (await response.json()) as { data: { - embedding: number[] - }[] + embedding: number[]; + }[]; }; return data.data[0].embedding; diff --git a/apps/cf-ai-backend/src/index.ts b/apps/cf-ai-backend/src/index.ts index f55c465b..ccaf06bd 100644 --- a/apps/cf-ai-backend/src/index.ts +++ b/apps/cf-ai-backend/src/index.ts @@ -1,15 +1,9 @@ -import type { - VectorizeIndex, - Fetcher, - Request, -} from "@cloudflare/workers-types"; - -import { - CloudflareVectorizeStore, -} from "@langchain/cloudflare"; -import { OpenAIEmbeddings } from "./OpenAIEmbedder"; -import { GoogleGenerativeAI } from "@google/generative-ai"; -import routeMap from "./routes"; +import type { VectorizeIndex, Fetcher, Request } from '@cloudflare/workers-types'; + +import { CloudflareVectorizeStore } from '@langchain/cloudflare'; +import { OpenAIEmbeddings } from './OpenAIEmbedder'; +import { GoogleGenerativeAI } from '@google/generative-ai'; +import routeMap from './routes'; function isAuthorized(request: Request, env: Env): boolean { return request.headers.get('X-Custom-Auth-Key') === env.SECURITY_KEY; @@ -32,7 +26,7 @@ export default { const genAI = new GoogleGenerativeAI(env.GOOGLE_AI_API_KEY); - const model = genAI.getGenerativeModel({ model: "gemini-pro" }); + const model = genAI.getGenerativeModel({ model: 'gemini-pro' }); const url = new URL(request.url); const path = url.pathname; diff --git a/apps/cf-ai-backend/src/routes.ts b/apps/cf-ai-backend/src/routes.ts index 841f107a..a8a3249a 100644 --- a/apps/cf-ai-backend/src/routes.ts +++ b/apps/cf-ai-backend/src/routes.ts @@ -1,14 +1,20 @@ import { CloudflareVectorizeStore } from '@langchain/cloudflare'; import * as apiAdd from './routes/add'; -import * as apiQuery from "./routes/query" -import * as apiAsk from "./routes/ask" -import * as apiChat from "./routes/chat" +import * as apiQuery from './routes/query'; +import * as apiAsk from './routes/ask'; +import * as apiChat from './routes/chat'; import { OpenAIEmbeddings } from './OpenAIEmbedder'; import { GenerativeModel } from '@google/generative-ai'; import { Request } from '@cloudflare/workers-types'; - -type RouteHandler = (request: Request, store: CloudflareVectorizeStore, embeddings: OpenAIEmbeddings, model: GenerativeModel, env: Env, ctx?: ExecutionContext) => Promise<Response>; +type RouteHandler = ( + request: Request, + store: CloudflareVectorizeStore, + embeddings: OpenAIEmbeddings, + model: GenerativeModel, + env: Env, + ctx?: ExecutionContext, +) => Promise<Response>; const routeMap = new Map<string, Record<string, RouteHandler>>(); diff --git a/apps/cf-ai-backend/src/routes/add.ts b/apps/cf-ai-backend/src/routes/add.ts index 9b05e9f0..b9a6da8f 100644 --- a/apps/cf-ai-backend/src/routes/add.ts +++ b/apps/cf-ai-backend/src/routes/add.ts @@ -1,36 +1,38 @@ -import { Request } from "@cloudflare/workers-types"; -import { type CloudflareVectorizeStore } from "@langchain/cloudflare"; +import { Request } from '@cloudflare/workers-types'; +import { type CloudflareVectorizeStore } from '@langchain/cloudflare'; export async function POST(request: Request, store: CloudflareVectorizeStore) { - const body = await request.json() as { - pageContent: string, - title?: string, - description?: string, - space?: string, - url: string, - user: string + const body = (await request.json()) as { + pageContent: string; + title?: string; + description?: string; + space?: string; + url: string; + user: string; }; if (!body.pageContent || !body.url) { - return new Response(JSON.stringify({ message: "Invalid Page Content" }), { status: 400 }); + return new Response(JSON.stringify({ message: 'Invalid Page Content' }), { status: 400 }); } - const newPageContent = `Title: ${body.title}\nDescription: ${body.description}\nURL: ${body.url}\nContent: ${body.pageContent}` + const newPageContent = `Title: ${body.title}\nDescription: ${body.description}\nURL: ${body.url}\nContent: ${body.pageContent}`; - - await store.addDocuments([ - { - pageContent: newPageContent, - metadata: { - title: body.title ?? "", - description: body.description ?? "", - space: body.space ?? "", - url: body.url, - user: body.user, + await store.addDocuments( + [ + { + pageContent: newPageContent, + metadata: { + title: body.title ?? '', + description: body.description ?? '', + space: body.space ?? '', + url: body.url, + user: body.user, + }, }, + ], + { + ids: [`${body.url}-${body.user}`], }, - ], { - ids: [`${body.url}`] - }) + ); - return new Response(JSON.stringify({ message: "Document Added" }), { status: 200 }); + return new Response(JSON.stringify({ message: 'Document Added' }), { status: 200 }); } diff --git a/apps/cf-ai-backend/src/routes/ask.ts b/apps/cf-ai-backend/src/routes/ask.ts index 1c48dde8..267c1513 100644 --- a/apps/cf-ai-backend/src/routes/ask.ts +++ b/apps/cf-ai-backend/src/routes/ask.ts @@ -1,18 +1,18 @@ -import { GenerativeModel } from "@google/generative-ai"; -import { OpenAIEmbeddings } from "../OpenAIEmbedder"; -import { CloudflareVectorizeStore } from "@langchain/cloudflare"; -import { Request } from "@cloudflare/workers-types"; +import { GenerativeModel } from '@google/generative-ai'; +import { OpenAIEmbeddings } from '../OpenAIEmbedder'; +import { CloudflareVectorizeStore } from '@langchain/cloudflare'; +import { Request } from '@cloudflare/workers-types'; export async function POST(request: Request, _: CloudflareVectorizeStore, embeddings: OpenAIEmbeddings, model: GenerativeModel, env?: Env) { - const body = await request.json() as { - query: string + const body = (await request.json()) as { + query: string; }; if (!body.query) { - return new Response(JSON.stringify({ message: "Invalid Page Content" }), { status: 400 }); + return new Response(JSON.stringify({ message: 'Invalid Page Content' }), { status: 400 }); } - const prompt = `You are an agent that answers a question based on the query. don't say 'based on the context'.\n\n Context:\n${body.query} \nAnswer this question based on the context. Question: ${body.query}\nAnswer:` + const prompt = `You are an agent that answers a question based on the query. don't say 'based on the context'.\n\n Context:\n${body.query} \nAnswer this question based on the context. Question: ${body.query}\nAnswer:`; const output = await model.generateContentStream(prompt); const response = new Response( @@ -22,14 +22,14 @@ export async function POST(request: Request, _: CloudflareVectorizeStore, embedd for await (const chunk of output.stream) { const chunkText = await chunk.text(); console.log(chunkText); - const encodedChunk = converter.encode("data: " + JSON.stringify({ "response": chunkText }) + "\n\n"); + const encodedChunk = converter.encode('data: ' + JSON.stringify({ response: chunkText }) + '\n\n'); controller.enqueue(encodedChunk); } - const doneChunk = converter.encode("data: [DONE]"); + const doneChunk = converter.encode('data: [DONE]'); controller.enqueue(doneChunk); controller.close(); - } - }) + }, + }), ); return response; } diff --git a/apps/cf-ai-backend/src/routes/chat.ts b/apps/cf-ai-backend/src/routes/chat.ts index 95788d03..75e298b8 100644 --- a/apps/cf-ai-backend/src/routes/chat.ts +++ b/apps/cf-ai-backend/src/routes/chat.ts @@ -1,28 +1,28 @@ -import { Content, GenerativeModel } from "@google/generative-ai"; -import { OpenAIEmbeddings } from "../OpenAIEmbedder"; -import { CloudflareVectorizeStore } from "@langchain/cloudflare"; -import { Request } from "@cloudflare/workers-types"; +import { Content, GenerativeModel } from '@google/generative-ai'; +import { OpenAIEmbeddings } from '../OpenAIEmbedder'; +import { CloudflareVectorizeStore } from '@langchain/cloudflare'; +import { Request } from '@cloudflare/workers-types'; export async function POST(request: Request, _: CloudflareVectorizeStore, embeddings: OpenAIEmbeddings, model: GenerativeModel, env?: Env) { const queryparams = new URL(request.url).searchParams; - const query = queryparams.get("q"); - const topK = parseInt(queryparams.get("topK") ?? "5"); - const user = queryparams.get("user") - const spaces = queryparams.get("spaces") - const spacesArray = spaces ? spaces.split(",") : undefined + const query = queryparams.get('q'); + const topK = parseInt(queryparams.get('topK') ?? '5'); + const user = queryparams.get('user'); + const spaces = queryparams.get('spaces'); + const spacesArray = spaces ? spaces.split(',') : undefined; - const sourcesOnly = (queryparams.get("sourcesOnly") ?? "false") + const sourcesOnly = queryparams.get('sourcesOnly') ?? 'false'; if (!user) { - return new Response(JSON.stringify({ message: "Invalid User" }), { status: 400 }); + return new Response(JSON.stringify({ message: 'Invalid User' }), { status: 400 }); } if (!query) { - return new Response(JSON.stringify({ message: "Invalid Query" }), { status: 400 }); + return new Response(JSON.stringify({ message: 'Invalid Query' }), { status: 400 }); } const filter: VectorizeVectorMetadataFilter = { - user - } + user, + }; const responses: VectorizeMatches = { matches: [], count: 0 }; @@ -34,12 +34,12 @@ export async function POST(request: Request, _: CloudflareVectorizeStore, embedd const resp = await env!.VECTORIZE_INDEX.query(queryAsVector, { topK, - filter + filter, }); if (resp.count > 0) { - responses.matches.push(...resp.matches) - responses.count += resp.count + responses.matches.push(...resp.matches); + responses.count += resp.count; } } } else { @@ -47,13 +47,13 @@ export async function POST(request: Request, _: CloudflareVectorizeStore, embedd const resp = await env!.VECTORIZE_INDEX.query(queryAsVector, { topK, filter: { - user - } + user, + }, }); if (resp.count > 0) { - responses.matches.push(...resp.matches) - responses.count += resp.count + responses.matches.push(...resp.matches); + responses.count += resp.count; } } @@ -61,27 +61,36 @@ export async function POST(request: Request, _: CloudflareVectorizeStore, embedd // return new Response(JSON.stringify({ message: "No Results Found" }), { status: 404 }); // } - const highScoreIds = responses.matches.filter(({ score }) => score > 0.35).map(({ id }) => id) + const highScoreIds = responses.matches.filter(({ score }) => score > 0.35).map(({ id }) => id); - if (sourcesOnly === "true") { + if (sourcesOnly === 'true') { return new Response(JSON.stringify({ ids: highScoreIds }), { status: 200 }); } - const vec = await env!.VECTORIZE_INDEX.getByIds(highScoreIds) + const vec = await env!.VECTORIZE_INDEX.getByIds(highScoreIds); - const preparedContext = vec.map(({ metadata }) => `Website title: ${metadata!.title}\nDescription: ${metadata!.description}\nURL: ${metadata!.url}\nContent: ${metadata!.text}`).join("\n\n"); + const preparedContext = vec + .map( + ({ metadata }) => + `Website title: ${metadata!.title}\nDescription: ${metadata!.description}\nURL: ${metadata!.url}\nContent: ${metadata!.text}`, + ) + .join('\n\n'); - const body = await request.json() as { - chatHistory?: Content[] + const body = (await request.json()) as { + chatHistory?: Content[]; }; const defaultHistory = [ { - role: "user", - parts: [{ text: `You are an agent that summarizes a page based on the query. don't say 'based on the context'. I expect you to be like a 'Second Brain'. you will be provided with the context (old saved posts) and questions. Answer accordingly. Answer in markdown format` }], + role: 'user', + parts: [ + { + text: `You are an agent that summarizes a page based on the query. don't say 'based on the context'. I expect you to be like a 'Second Brain'. you will be provided with the context (old saved posts) and questions. Answer accordingly. Answer in markdown format`, + }, + ], }, { - role: "model", + role: 'model', parts: [{ text: "Ok, I am a personal assistant, and will act as a second brain to help with user's queries." }], }, ] as Content[]; @@ -100,14 +109,14 @@ export async function POST(request: Request, _: CloudflareVectorizeStore, embedd const converter = new TextEncoder(); for await (const chunk of output.stream) { const chunkText = await chunk.text(); - const encodedChunk = converter.encode("data: " + JSON.stringify({ "response": chunkText }) + "\n\n"); + const encodedChunk = converter.encode('data: ' + JSON.stringify({ response: chunkText }) + '\n\n'); controller.enqueue(encodedChunk); } - const doneChunk = converter.encode("data: [DONE]"); + const doneChunk = converter.encode('data: [DONE]'); controller.enqueue(doneChunk); controller.close(); - } - }) + }, + }), ); return response; } diff --git a/apps/cf-ai-backend/src/routes/query.ts b/apps/cf-ai-backend/src/routes/query.ts index be237d7d..cd5295c5 100644 --- a/apps/cf-ai-backend/src/routes/query.ts +++ b/apps/cf-ai-backend/src/routes/query.ts @@ -1,59 +1,65 @@ -import { GenerativeModel } from "@google/generative-ai"; -import { OpenAIEmbeddings } from "../OpenAIEmbedder"; -import { CloudflareVectorizeStore } from "@langchain/cloudflare"; -import { Request } from "@cloudflare/workers-types"; +import { GenerativeModel } from '@google/generative-ai'; +import { OpenAIEmbeddings } from '../OpenAIEmbedder'; +import { CloudflareVectorizeStore } from '@langchain/cloudflare'; +import { Request } from '@cloudflare/workers-types'; export async function GET(request: Request, _: CloudflareVectorizeStore, embeddings: OpenAIEmbeddings, model: GenerativeModel, env?: Env) { const queryparams = new URL(request.url).searchParams; - const query = queryparams.get("q"); - const topK = parseInt(queryparams.get("topK") ?? "5"); - const user = queryparams.get("user") - const space = queryparams.get("space") + const query = queryparams.get('q'); + const topK = parseInt(queryparams.get('topK') ?? '5'); + const user = queryparams.get('user'); + const space = queryparams.get('space'); - const sourcesOnly = (queryparams.get("sourcesOnly") ?? "false") + const sourcesOnly = queryparams.get('sourcesOnly') ?? 'false'; if (!user) { - return new Response(JSON.stringify({ message: "Invalid User" }), { status: 400 }); + return new Response(JSON.stringify({ message: 'Invalid User' }), { status: 400 }); } if (!query) { - return new Response(JSON.stringify({ message: "Invalid Query" }), { status: 400 }); + return new Response(JSON.stringify({ message: 'Invalid Query' }), { status: 400 }); } const filter: VectorizeVectorMetadataFilter = { - user - } + user, + }; if (space) { - filter.space + filter.space; } const queryAsVector = await embeddings.embedQuery(query); const resp = await env!.VECTORIZE_INDEX.query(queryAsVector, { topK, - filter + filter, }); if (resp.count === 0) { - return new Response(JSON.stringify({ message: "No Results Found" }), { status: 404 }); + return new Response(JSON.stringify({ message: 'No Results Found' }), { status: 404 }); } - const highScoreIds = resp.matches.filter(({ score }) => score > 0.3).map(({ id }) => id) + const highScoreIds = resp.matches.filter(({ score }) => score > 0.3).map(({ id }) => id); - if (sourcesOnly === "true") { + if (sourcesOnly === 'true') { return new Response(JSON.stringify({ ids: highScoreIds }), { status: 200 }); } - const vec = await env!.VECTORIZE_INDEX.getByIds(highScoreIds) + const vec = await env!.VECTORIZE_INDEX.getByIds(highScoreIds); if (vec.length === 0 || !vec[0].metadata) { - return new Response(JSON.stringify({ message: "No Results Found" }), { status: 400 }); + return new Response(JSON.stringify({ message: 'No Results Found' }), { status: 400 }); } - const preparedContext = vec.slice(0, 3).map(({ metadata }) => `Website title: ${metadata!.title}\nDescription: ${metadata!.description}\nURL: ${metadata!.url}\nContent: ${metadata!.text}`).join("\n\n"); + const preparedContext = vec + .slice(0, 3) + .map( + ({ metadata }) => + `Website title: ${metadata!.title}\nDescription: ${metadata!.description}\nURL: ${metadata!.url}\nContent: ${metadata!.text}`, + ) + .join('\n\n'); - const prompt = `You are an agent that summarizes a page based on the query. Be direct and concise, don't say 'based on the context'.\n\n Context:\n${preparedContext} \nAnswer this question based on the context. Question: ${query}\nAnswer:` + const prompt = `You are an agent that summarizes a page based on the query. Be direct and concise, don't say 'based on the context'.\n\n Context:\n${preparedContext} \nAnswer this question based on the context. Question: ${query}\nAnswer:`; const output = await model.generateContentStream(prompt); const response = new Response( @@ -62,14 +68,14 @@ export async function GET(request: Request, _: CloudflareVectorizeStore, embeddi const converter = new TextEncoder(); for await (const chunk of output.stream) { const chunkText = await chunk.text(); - const encodedChunk = converter.encode("data: " + JSON.stringify({ "response": chunkText }) + "\n\n"); + const encodedChunk = converter.encode('data: ' + JSON.stringify({ response: chunkText }) + '\n\n'); controller.enqueue(encodedChunk); } - const doneChunk = converter.encode("data: [DONE]"); + const doneChunk = converter.encode('data: [DONE]'); controller.enqueue(doneChunk); controller.close(); - } - }) + }, + }), ); return response; } |