add a profile photo for chatbot, styling fixes, add button to reset session, load an epub instead of our github vector embeddings

This commit is contained in:
silentsilas 2024-09-22 00:19:37 -04:00
parent 8f3d476a38
commit 2c3a4be48c
Signed by: silentsilas
GPG Key ID: 113DFB380F724A81
10 changed files with 355 additions and 62 deletions

267
package-lock.json generated
View File

@ -11,6 +11,7 @@
"@dimforge/rapier3d-compat": "^0.11.2",
"@langchain/anthropic": "^0.3.1",
"@langchain/community": "^0.3.1",
"@langchain/core": "^0.2.34",
"@langchain/openai": "^0.3.0",
"@langchain/textsplitters": "^0.1.0",
"@tensorflow-models/universal-sentence-encoder": "^1.3.3",
@ -18,7 +19,9 @@
"@threlte/core": "^7.3.1",
"@threlte/extras": "^8.11.5",
"@threlte/rapier": "^2.0.1",
"epub2": "^3.0.2",
"fuse.js": "^7.0.0",
"html-to-text": "^9.0.5",
"marked": "^12.0.2",
"mdsvex": "^0.11.2",
"three": "^0.159.0"
@ -1239,16 +1242,15 @@
}
},
"node_modules/@langchain/core": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@langchain/core/-/core-0.3.3.tgz",
"integrity": "sha512-WAtkmhbdl2T41qzimTzhb3pXCHQxO4onqxzPxgdf3KftQdTwLq0YYBDhozRMZLNAd/+cfH0ymZGaZSsnc9Ogsg==",
"peer": true,
"version": "0.2.34",
"resolved": "https://registry.npmjs.org/@langchain/core/-/core-0.2.34.tgz",
"integrity": "sha512-Hkveq1UcOjUj1DVn5erbqElyRj1t04NORSuSIZAJCtPO7EDkIqomjAarJ5+I5NUpQeIONgbOdnY9TkJ6cKUSVA==",
"dependencies": {
"ansi-styles": "^5.0.0",
"camelcase": "6",
"decamelize": "1.2.0",
"js-tiktoken": "^1.0.12",
"langsmith": "^0.1.56",
"langsmith": "^0.1.56-rc.1",
"mustache": "^4.2.0",
"p-queue": "^6.6.2",
"p-retry": "4",
@ -1264,7 +1266,6 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"peer": true,
"engines": {
"node": ">=10"
},
@ -1751,6 +1752,18 @@
"win32"
]
},
"node_modules/@selderee/plugin-htmlparser2": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz",
"integrity": "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==",
"dependencies": {
"domhandler": "^5.0.3",
"selderee": "^0.11.0"
},
"funding": {
"url": "https://ko-fi.com/killymxi"
}
},
"node_modules/@sinclair/typebox": {
"version": "0.27.8",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
@ -2722,6 +2735,26 @@
"node": ">= 0.4"
}
},
"node_modules/array-hyper-unique": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/array-hyper-unique/-/array-hyper-unique-2.1.6.tgz",
"integrity": "sha512-BdlHRqjKSYs88WFaVNVEc6Kv8ln/FdzCKPbcDPuWs4/EXkQFhnjc8TyR7hnPxRjcjo5LKOhUMGUWpAqRgeJvpA==",
"dependencies": {
"deep-eql": "= 4.0.0",
"lodash": "^4.17.21"
}
},
"node_modules/array-hyper-unique/node_modules/deep-eql": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.0.0.tgz",
"integrity": "sha512-GxJC5MOg2KyQlv6WiUF/VAnMj4MWnYiXo4oLgeptOELVoknyErb4Z8+5F/IM/K4g9/80YzzatxmWcyRwUseH0A==",
"dependencies": {
"type-detect": "^4.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/array-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@ -2855,6 +2888,11 @@
"readable-stream": "^3.4.0"
}
},
"node_modules/bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
},
"node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
@ -2976,7 +3014,6 @@
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
"peer": true,
"engines": {
"node": ">=10"
},
@ -3251,6 +3288,14 @@
"url": "https://opencollective.com/core-js"
}
},
"node_modules/crlf-normalize": {
"version": "1.0.20",
"resolved": "https://registry.npmjs.org/crlf-normalize/-/crlf-normalize-1.0.20.tgz",
"integrity": "sha512-h/rBerTd3YHQGfv7tNT25mfhWvRq2BBLCZZ80GFarFxf6HQGbpW6iqDL3N+HBLpjLfAdcBXfWAzVlLfHkRUQBQ==",
"dependencies": {
"ts-type": ">=2"
}
},
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@ -3347,7 +3392,6 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@ -3400,7 +3444,6 @@
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@ -3491,6 +3534,57 @@
"node": ">=6.0.0"
}
},
"node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
]
},
"node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/domutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/earcut": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz",
@ -3524,6 +3618,30 @@
"once": "^1.4.0"
}
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/epub2": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/epub2/-/epub2-3.0.2.tgz",
"integrity": "sha512-rhvpt27CV5MZfRetfNtdNwi3XcNg1Am0TwfveJkK8YWeHItHepQ8Js9J06v8XRIjuTrCW/NSGYMTy55Of7BfNQ==",
"dependencies": {
"adm-zip": "^0.5.10",
"array-hyper-unique": "^2.1.4",
"bluebird": "^3.7.2",
"crlf-normalize": "^1.0.19",
"tslib": "^2.6.2",
"xml2js": "^0.6.2"
}
},
"node_modules/es6-promise": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
@ -4471,6 +4589,39 @@
"node": ">= 0.4"
}
},
"node_modules/html-to-text": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz",
"integrity": "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==",
"dependencies": {
"@selderee/plugin-htmlparser2": "^0.11.0",
"deepmerge": "^4.3.1",
"dom-serializer": "^2.0.0",
"htmlparser2": "^8.0.2",
"selderee": "^0.11.0"
},
"engines": {
"node": ">=14"
}
},
"node_modules/htmlparser2": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
"integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
"funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3",
"domutils": "^3.0.1",
"entities": "^4.4.0"
}
},
"node_modules/https-proxy-agent": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
@ -4952,6 +5103,14 @@
"node": ">=14"
}
},
"node_modules/leac": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz",
"integrity": "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==",
"funding": {
"url": "https://ko-fi.com/killymxi"
}
},
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -5016,6 +5175,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
@ -5334,7 +5498,6 @@
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
"integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==",
"peer": true,
"bin": {
"mustache": "bin/mustache"
}
@ -5709,6 +5872,18 @@
"node": ">=6"
}
},
"node_modules/parseley": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz",
"integrity": "sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==",
"dependencies": {
"leac": "^0.6.0",
"peberminta": "^0.9.0"
},
"funding": {
"url": "https://ko-fi.com/killymxi"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@ -5781,6 +5956,14 @@
"node": "*"
}
},
"node_modules/peberminta": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz",
"integrity": "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==",
"funding": {
"url": "https://ko-fi.com/killymxi"
}
},
"node_modules/periscopic": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz",
@ -6490,11 +6673,27 @@
"integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==",
"dev": true
},
"node_modules/sax": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
},
"node_modules/seedrandom": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
"integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="
},
"node_modules/selderee": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz",
"integrity": "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==",
"dependencies": {
"parseley": "^0.12.0"
},
"funding": {
"url": "https://ko-fi.com/killymxi"
}
},
"node_modules/semver": {
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
@ -7398,11 +7597,29 @@
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
"dev": true
},
"node_modules/ts-toolbelt": {
"version": "9.6.0",
"resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz",
"integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==",
"peer": true
},
"node_modules/ts-type": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/ts-type/-/ts-type-3.0.1.tgz",
"integrity": "sha512-cleRydCkBGBFQ4KAvLH0ARIkciduS745prkGVVxPGvcRGhMMoSJUB7gNR1ByKhFTEYrYRg2CsMRGYnqp+6op+g==",
"dependencies": {
"@types/node": "*",
"tslib": ">=2",
"typedarray-dts": "^1.0.0"
},
"peerDependencies": {
"ts-toolbelt": "^9.6.0"
}
},
"node_modules/tslib": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
"dev": true
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="
},
"node_modules/tunnel-agent": {
"version": "0.6.0",
@ -7441,7 +7658,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
"integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
"dev": true,
"engines": {
"node": ">=4"
}
@ -7458,6 +7674,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/typedarray-dts": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/typedarray-dts/-/typedarray-dts-1.0.0.tgz",
"integrity": "sha512-Ka0DBegjuV9IPYFT1h0Qqk5U4pccebNIJCGl8C5uU7xtOs+jpJvKGAY4fHGK25hTmXZOEUl9Cnsg5cS6K/b5DA=="
},
"node_modules/typescript": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz",
@ -7924,6 +8145,26 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"node_modules/xml2js": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
"integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
"dependencies": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/xmlbuilder": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
"engines": {
"node": ">=4.0"
}
},
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",

View File

@ -50,6 +50,7 @@
"@dimforge/rapier3d-compat": "^0.11.2",
"@langchain/anthropic": "^0.3.1",
"@langchain/community": "^0.3.1",
"@langchain/core": "^0.2.34",
"@langchain/openai": "^0.3.0",
"@langchain/textsplitters": "^0.1.0",
"@tensorflow-models/universal-sentence-encoder": "^1.3.3",
@ -57,7 +58,9 @@
"@threlte/core": "^7.3.1",
"@threlte/extras": "^8.11.5",
"@threlte/rapier": "^2.0.1",
"epub2": "^3.0.2",
"fuse.js": "^7.0.0",
"html-to-text": "^9.0.5",
"marked": "^12.0.2",
"mdsvex": "^0.11.2",
"three": "^0.159.0"

6
src/app.d.ts vendored
View File

@ -3,11 +3,13 @@
declare global {
namespace App {
// interface Error {}
// interface Locals {}
interface Locals {
sessionId: string;
}
// interface PageData {}
// interface PageState {}
// interface Platform {}
}
}
export {};
export { };

View File

@ -1,5 +1,26 @@
import { writable } from 'svelte/store';
import type { SearchResult } from './utils/search';
import type { HumanMessage, AIMessage, SystemMessage } from '@langchain/core/messages';
const initArray: SearchResult[] = [];
export const searchResults = writable(initArray);
export type ChatHistory = (HumanMessage | AIMessage | SystemMessage)[];
const chatHistories: Record<string, ChatHistory> = {};
export const chatStore = writable(chatHistories);
export function getChatHistory(sessionId: string): ChatHistory {
return chatHistories[sessionId] || [];
}
export function setChatHistory(sessionId: string, history: ChatHistory): void {
chatHistories[sessionId] = history;
chatStore.set(chatHistories);
}
export function clearChatHistory(sessionId: string): void {
chatHistories[sessionId] = [];
chatStore.set(chatHistories);
}

View File

@ -1,11 +1,10 @@
<script lang="ts">
import '../../app.css';
import type { SearchResult } from '$lib/utils/search';
import { searchResults } from '$lib/store';
import { searchResults, type ChatHistory } from '$lib/store';
import { onMount } from 'svelte';
import { marked } from 'marked';
import { HumanMessage, AIMessage } from '@langchain/core/messages';
import type { ChatHistory } from '../api/ai/+server';
import { PUBLIC_LOAD_DUMMY_HISTORY } from '$env/static/public';
let searchResultsValue: SearchResult[] = [];
@ -86,6 +85,22 @@
loading = false;
}
}
async function handleNewSession() {
try {
const response = await fetch('/api/ai/new-session', { method: 'POST' });
if (response.ok) {
const historyResponse = await fetch('/api/ai');
const data = await historyResponse.json();
chatHistory = data.chatHistory || [];
query = '';
} else {
console.error('Failed to start new session');
}
} catch (error) {
console.error('Error starting new session:', error);
}
}
</script>
<svelte:head>
@ -93,13 +108,29 @@
</svelte:head>
{#if searchResultsValue.length === 0}
<div class="flex-grow flex-col overflow-auto p-4">
<div class="flex-grow flex-col overflow-auto p-4 my-2 bg-base-200">
<div class="flex flex-col items-center gap-4">
<div class="avatar">
<div class="ring-primary ring-offset-base-100 w-64 rounded-full ring ring-offset-2">
<img src="/imgs/ai/profile.jpg" alt="Portrait of an orange tabby cat reading a book" />
</div>
</div>
<span>
This lil guy just finished reading <a
class="link link-primary"
href="https://bookshop.org/p/books/a-history-of-tea-the-life-and-times-of-the-world-s-favorite-beverage-laura-c-martin/11044690"
target="_blank"
>
A History of Tea
</a>, so ask 'em anything about the book.
</span>
</div>
<div class="space-y-4">
{#each chatHistory as message}
{@const { role, content } = getRoleAndContent(message)}
{#if role === 'human'}
<div class="chat chat-end">
<div class="chat-bubble chat-bubble-primary">
<div class="chat-bubble chat-bubble-primary prose">
{@html renderMarkdown(content)}
</div>
</div>
@ -112,30 +143,29 @@
</div>
{#if loading}
<div class="mt-4">
<div class="mt-4 flex flex-col items-center justify-center">
<span class="loading loading-dots loading-lg"></span>
<span>This may take a minute; streaming is still a work in progress.</span>
</div>
{/if}
<form on:submit|preventDefault={handleSubmit} class="mt-4 flex-col">
<label class="form-control">
<div class="label">
<span class="label-text">
Querying the Authenticator <a
href="https://git.silentsilas.com/silentsilas/Authenticator"
target="_blank"
class="link-primary">repository</a
>
</span>
</div>
<textarea
bind:value={query}
class="textarea textarea-bordered h-24"
placeholder="Type your message here..."
></textarea>
</label>
<button type="submit" class="btn btn-block btn-primary mt-2" disabled={loading}>
<button type="submit" class="btn btn-block btn-primary mt-4" disabled={loading}>
Send
</button>
<button
type="button"
class="btn btn-block btn-error btn-outline mt-2"
on:click={handleNewSession}
>
New Session
</button>
</form>
</div>
{/if}

View File

@ -1,47 +1,34 @@
import { json } from '@sveltejs/kit';
import { FaissStore } from '@langchain/community/vectorstores/faiss';
import { OpenAIEmbeddings } from '@langchain/openai';
import { ChatAnthropic } from '@langchain/anthropic';
import { RunnableSequence, RunnablePassthrough } from '@langchain/core/runnables';
import { StringOutputParser } from '@langchain/core/output_parsers';
import { ChatPromptTemplate } from '@langchain/core/prompts';
import { join } from 'path';
import { HumanMessage, AIMessage, SystemMessage } from '@langchain/core/messages';
import { HumanMessage, AIMessage } from '@langchain/core/messages';
import type { RequestEvent } from '@sveltejs/kit';
const chatHistories: Record<string, ChatHistory> = {};
type VectorDocument = {
pageContent: string;
};
const formatDocumentsAsString = (documents: VectorDocument[]) => {
return documents.map((doc) => doc.pageContent).join('\n\n');
};
export type ChatHistory = HumanMessage[] | AIMessage[] | SystemMessage[];
import { EPubLoader } from "@langchain/community/document_loaders/fs/epub";
import { join } from 'path';
import { getChatHistory, setChatHistory } from '$lib/store';
export async function POST({ request, locals }: RequestEvent): Promise<Response> {
const { query } = await request.json();
const sessionId = locals.sessionId;
if (!chatHistories[sessionId]) {
chatHistories[sessionId] = [];
}
const chatHistory = chatHistories[sessionId];
const chatHistory = getChatHistory(sessionId);
const directory = join(process.cwd(), 'vectorstore');
const embeddings = new OpenAIEmbeddings();
const vectorStore = await FaissStore.load(directory, embeddings);
const vectorStoreRetriever = vectorStore.asRetriever();
const directory = join(process.cwd(), 'static/book.epub');
const loader = new EPubLoader(directory);
const docs = await loader.load();
const context = docs.map(doc => doc.pageContent).join('\n\n');
const model = new ChatAnthropic({
modelName: 'claude-3-5-sonnet-20240620',
anthropicApiKey: process.env.ANTHROPIC_API_KEY
anthropicApiKey: process.env.ANTHROPIC_API_KEY,
});
const SYSTEM_TEMPLATE = `Use the following pieces of context to answer the question at the end.
If you don't know the answer, just say that you don't know, don't try to make up an answer.
Always format your response in markdown.
----------------
@ -59,7 +46,7 @@ Question:
const chain = RunnableSequence.from([
{
context: vectorStoreRetriever.pipe(formatDocumentsAsString),
context: () => context,
question: new RunnablePassthrough(),
},
prompt,
@ -72,11 +59,13 @@ Question:
chatHistory.push(new HumanMessage({ content: query }));
chatHistory.push(new AIMessage({ content: answer }));
setChatHistory(sessionId, chatHistory);
return json({ response: answer, chatHistory });
}
export async function GET({ locals }): Promise<Response> {
const sessionId = locals.sessionId;
const chatHistory = chatHistories[sessionId] || [];
const chatHistory = getChatHistory(sessionId);
return json({ chatHistory });
}

View File

@ -0,0 +1,8 @@
import type { RequestEvent } from '@sveltejs/kit';
import { clearChatHistory } from '$lib/store';
export async function POST({ locals }: RequestEvent) {
const sessionId = locals.sessionId;
clearChatHistory(sessionId);
return new Response(null, { status: 204 });
}

View File

@ -34,13 +34,12 @@
'An experiment with 3D vector math for a rudimentary simulation of gravity. You can change the strength of the gravity in the Controls menu.'
},
{
title: 'Animation Editor',
path: '/editor',
source:
'https://git.silentsilas.com/silentsilas/playground/src/branch/main/src/routes/editor',
title: 'Tea Guru',
path: '/ai',
source: 'https://git.silentsilas.com/silentsilas/playground/src/branch/main/src/routes/ai',
position: [4, -2, -4],
description:
'A 3D animation editor via Theatre.js. This is used internally by me for other ThreeJS projects.'
'A chatbot trained on an in-depth book about tea. Ask it about anything related to tea!'
},
{
title: 'Headbang',

BIN
static/book.epub Normal file

Binary file not shown.

BIN
static/imgs/ai/profile.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB