mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-08 01:08:39 -10:00
Fix postgres 2
This commit is contained in:
1 parent
45bffe0914
commit
23a74c9ada
9 files changed
+621
-665
No files matched your search
+1
-1
@@ -1,6 +1,6 @@
|
||||
FROM python:3.11-slim
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN pip install flask praisonai==1.0.4 gunicorn markdown
|
||||
RUN pip install flask praisonai==1.0.5 gunicorn markdown
|
||||
EXPOSE 8080
|
||||
CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]
|
||||
@@ -110,7 +110,7 @@ Loads environment variables from .env file or system and sets them.</p>
|
||||
file.write("FROM python:3.11-slim\n")
|
||||
file.write("WORKDIR /app\n")
|
||||
file.write("COPY . .\n")
|
||||
file.write("RUN pip install flask praisonai==1.0.4 gunicorn markdown\n")
|
||||
file.write("RUN pip install flask praisonai==1.0.5 gunicorn markdown\n")
|
||||
file.write("EXPOSE 8080\n")
|
||||
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
||||
|
||||
|
||||
Generated
+168
-159
@@ -46,87 +46,87 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "aiohttp"
|
||||
version = "3.11.9"
|
||||
version = "3.11.10"
|
||||
description = "Async http client/server framework (asyncio)"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "aiohttp-3.11.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0411777249f25d11bd2964a230b3ffafcbed6cd65d0f2b132bc2b8f5b8c347c7"},
|
||||
{file = "aiohttp-3.11.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:499368eb904566fbdf1a3836a1532000ef1308f34a1bcbf36e6351904cced771"},
|
||||
{file = "aiohttp-3.11.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0b5a5009b0159a8f707879dc102b139466d8ec6db05103ec1520394fdd8ea02c"},
|
||||
{file = "aiohttp-3.11.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:176f8bb8931da0613bb0ed16326d01330066bb1e172dd97e1e02b1c27383277b"},
|
||||
{file = "aiohttp-3.11.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6435a66957cdba1a0b16f368bde03ce9c79c57306b39510da6ae5312a1a5b2c1"},
|
||||
{file = "aiohttp-3.11.9-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:202f40fb686e5f93908eee0c75d1e6fbe50a43e9bd4909bf3bf4a56b560ca180"},
|
||||
{file = "aiohttp-3.11.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39625703540feb50b6b7f938b3856d1f4886d2e585d88274e62b1bd273fae09b"},
|
||||
{file = "aiohttp-3.11.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6beeac698671baa558e82fa160be9761cf0eb25861943f4689ecf9000f8ebd0"},
|
||||
{file = "aiohttp-3.11.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:96726839a42429318017e67a42cca75d4f0d5248a809b3cc2e125445edd7d50d"},
|
||||
{file = "aiohttp-3.11.9-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3f5461c77649358610fb9694e790956b4238ac5d9e697a17f63619c096469afe"},
|
||||
{file = "aiohttp-3.11.9-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4313f3bc901255b22f01663eeeae167468264fdae0d32c25fc631d5d6e15b502"},
|
||||
{file = "aiohttp-3.11.9-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d6e274661c74195708fc4380a4ef64298926c5a50bb10fbae3d01627d7a075b7"},
|
||||
{file = "aiohttp-3.11.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:db2914de2559809fdbcf3e48f41b17a493b58cb7988d3e211f6b63126c55fe82"},
|
||||
{file = "aiohttp-3.11.9-cp310-cp310-win32.whl", hash = "sha256:27935716f8d62c1c73010428db310fd10136002cfc6d52b0ba7bdfa752d26066"},
|
||||
{file = "aiohttp-3.11.9-cp310-cp310-win_amd64.whl", hash = "sha256:afbe85b50ade42ddff5669947afde9e8a610e64d2c80be046d67ec4368e555fa"},
|
||||
{file = "aiohttp-3.11.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:afcda759a69c6a8be3aae764ec6733155aa4a5ad9aad4f398b52ba4037942fe3"},
|
||||
{file = "aiohttp-3.11.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5bba6b83fde4ca233cfda04cbd4685ab88696b0c8eaf76f7148969eab5e248a"},
|
||||
{file = "aiohttp-3.11.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:442356e8924fe1a121f8c87866b0ecdc785757fd28924b17c20493961b3d6697"},
|
||||
{file = "aiohttp-3.11.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f737fef6e117856400afee4f17774cdea392b28ecf058833f5eca368a18cf1bf"},
|
||||
{file = "aiohttp-3.11.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea142255d4901b03f89cb6a94411ecec117786a76fc9ab043af8f51dd50b5313"},
|
||||
{file = "aiohttp-3.11.9-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6e1e9e447856e9b7b3d38e1316ae9a8c92e7536ef48373de758ea055edfd5db5"},
|
||||
{file = "aiohttp-3.11.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7f6173302f8a329ca5d1ee592af9e628d3ade87816e9958dcf7cdae2841def7"},
|
||||
{file = "aiohttp-3.11.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7c6147c6306f537cff59409609508a1d2eff81199f0302dd456bb9e7ea50c39"},
|
||||
{file = "aiohttp-3.11.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e9d036a9a41fc78e8a3f10a86c2fc1098fca8fab8715ba9eb999ce4788d35df0"},
|
||||
{file = "aiohttp-3.11.9-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2ac9fd83096df36728da8e2f4488ac3b5602238f602706606f3702f07a13a409"},
|
||||
{file = "aiohttp-3.11.9-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d3108f0ad5c6b6d78eec5273219a5bbd884b4aacec17883ceefaac988850ce6e"},
|
||||
{file = "aiohttp-3.11.9-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:96bbec47beb131bbf4bae05d8ef99ad9e5738f12717cfbbf16648b78b0232e87"},
|
||||
{file = "aiohttp-3.11.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:fc726c3fa8f606d07bd2b500e5dc4c0fd664c59be7788a16b9e34352c50b6b6b"},
|
||||
{file = "aiohttp-3.11.9-cp311-cp311-win32.whl", hash = "sha256:5720ebbc7a1b46c33a42d489d25d36c64c419f52159485e55589fbec648ea49a"},
|
||||
{file = "aiohttp-3.11.9-cp311-cp311-win_amd64.whl", hash = "sha256:17af09d963fa1acd7e4c280e9354aeafd9e3d47eaa4a6bfbd2171ad7da49f0c5"},
|
||||
{file = "aiohttp-3.11.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c1f2d7fd583fc79c240094b3e7237d88493814d4b300d013a42726c35a734bc9"},
|
||||
{file = "aiohttp-3.11.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d4b8a1b6c7a68c73191f2ebd3bf66f7ce02f9c374e309bdb68ba886bbbf1b938"},
|
||||
{file = "aiohttp-3.11.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bd3f711f4c99da0091ced41dccdc1bcf8be0281dc314d6d9c6b6cf5df66f37a9"},
|
||||
{file = "aiohttp-3.11.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44cb1a1326a0264480a789e6100dc3e07122eb8cd1ad6b784a3d47d13ed1d89c"},
|
||||
{file = "aiohttp-3.11.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7a7ddf981a0b953ade1c2379052d47ccda2f58ab678fca0671c7c7ca2f67aac2"},
|
||||
{file = "aiohttp-3.11.9-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6ffa45cc55b18d4ac1396d1ddb029f139b1d3480f1594130e62bceadf2e1a838"},
|
||||
{file = "aiohttp-3.11.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cca505829cdab58c2495ff418c96092d225a1bbd486f79017f6de915580d3c44"},
|
||||
{file = "aiohttp-3.11.9-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44d323aa80a867cb6db6bebb4bbec677c6478e38128847f2c6b0f70eae984d72"},
|
||||
{file = "aiohttp-3.11.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b2fab23003c4bb2249729a7290a76c1dda38c438300fdf97d4e42bf78b19c810"},
|
||||
{file = "aiohttp-3.11.9-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:be0c7c98e38a1e3ad7a6ff64af8b6d6db34bf5a41b1478e24c3c74d9e7f8ed42"},
|
||||
{file = "aiohttp-3.11.9-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5cc5e0d069c56645446c45a4b5010d4b33ac6c5ebfd369a791b5f097e46a3c08"},
|
||||
{file = "aiohttp-3.11.9-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9bcf97b971289be69638d8b1b616f7e557e1342debc7fc86cf89d3f08960e411"},
|
||||
{file = "aiohttp-3.11.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c7333e7239415076d1418dbfb7fa4df48f3a5b00f8fdf854fca549080455bc14"},
|
||||
{file = "aiohttp-3.11.9-cp312-cp312-win32.whl", hash = "sha256:9384b07cfd3045b37b05ed002d1c255db02fb96506ad65f0f9b776b762a7572e"},
|
||||
{file = "aiohttp-3.11.9-cp312-cp312-win_amd64.whl", hash = "sha256:f5252ba8b43906f206048fa569debf2cd0da0316e8d5b4d25abe53307f573941"},
|
||||
{file = "aiohttp-3.11.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:282e0a7ddd36ebc411f156aeaa0491e8fe7f030e2a95da532cf0c84b0b70bc66"},
|
||||
{file = "aiohttp-3.11.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ebd3e6b0c7d4954cca59d241970011f8d3327633d555051c430bd09ff49dc494"},
|
||||
{file = "aiohttp-3.11.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:30f9f89ae625d412043f12ca3771b2ccec227cc93b93bb1f994db6e1af40a7d3"},
|
||||
{file = "aiohttp-3.11.9-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a3b5b2c012d70c63d9d13c57ed1603709a4d9d7d473e4a9dfece0e4ea3d5f51"},
|
||||
{file = "aiohttp-3.11.9-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ef1550bb5f55f71b97a6a395286db07f7f2c01c8890e613556df9a51da91e8d"},
|
||||
{file = "aiohttp-3.11.9-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:317251b9c9a2f1a9ff9cd093775b34c6861d1d7df9439ce3d32a88c275c995cd"},
|
||||
{file = "aiohttp-3.11.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cbe97839b009826a61b143d3ca4964c8590d7aed33d6118125e5b71691ca46"},
|
||||
{file = "aiohttp-3.11.9-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:618b18c3a2360ac940a5503da14fa4f880c5b9bc315ec20a830357bcc62e6bae"},
|
||||
{file = "aiohttp-3.11.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a0cf4d814689e58f57ecd5d8c523e6538417ca2e72ff52c007c64065cef50fb2"},
|
||||
{file = "aiohttp-3.11.9-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:15c4e489942d987d5dac0ba39e5772dcbed4cc9ae3710d1025d5ba95e4a5349c"},
|
||||
{file = "aiohttp-3.11.9-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ec8df0ff5a911c6d21957a9182402aad7bf060eaeffd77c9ea1c16aecab5adbf"},
|
||||
{file = "aiohttp-3.11.9-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ed95d66745f53e129e935ad726167d3a6cb18c5d33df3165974d54742c373868"},
|
||||
{file = "aiohttp-3.11.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:647ec5bee7e4ec9f1034ab48173b5fa970d9a991e565549b965e93331f1328fe"},
|
||||
{file = "aiohttp-3.11.9-cp313-cp313-win32.whl", hash = "sha256:ef2c9499b7bd1e24e473dc1a85de55d72fd084eea3d8bdeec7ee0720decb54fa"},
|
||||
{file = "aiohttp-3.11.9-cp313-cp313-win_amd64.whl", hash = "sha256:84de955314aa5e8d469b00b14d6d714b008087a0222b0f743e7ffac34ef56aff"},
|
||||
{file = "aiohttp-3.11.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e738aabff3586091221044b7a584865ddc4d6120346d12e28e788307cd731043"},
|
||||
{file = "aiohttp-3.11.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:28f29bce89c3b401a53d6fd4bee401ee943083bf2bdc12ef297c1d63155070b0"},
|
||||
{file = "aiohttp-3.11.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:31de2f10f63f96cc19e04bd2df9549559beadd0b2ee2da24a17e7ed877ca8c60"},
|
||||
{file = "aiohttp-3.11.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f31cebd8c27a36af6c7346055ac564946e562080ee1a838da724585c67474f"},
|
||||
{file = "aiohttp-3.11.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0bcb7f6976dc0b6b56efde13294862adf68dd48854111b422a336fa729a82ea6"},
|
||||
{file = "aiohttp-3.11.9-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a8b13b9950d8b2f8f58b6e5842c4b842b5887e2c32e3f4644d6642f1659a530"},
|
||||
{file = "aiohttp-3.11.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9c23e62f3545c2216100603614f9e019e41b9403c47dd85b8e7e5015bf1bde0"},
|
||||
{file = "aiohttp-3.11.9-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec656680fc53a13f849c71afd0c84a55c536206d524cbc831cde80abbe80489e"},
|
||||
{file = "aiohttp-3.11.9-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:36df00e0541f264ce42d62280281541a47474dfda500bc5b7f24f70a7f87be7a"},
|
||||
{file = "aiohttp-3.11.9-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:8dcfd14c712aa9dd18049280bfb2f95700ff6a8bde645e09f17c3ed3f05a0130"},
|
||||
{file = "aiohttp-3.11.9-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:14624d96f0d69cf451deed3173079a68c322279be6030208b045ab77e1e8d550"},
|
||||
{file = "aiohttp-3.11.9-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4b01d9cfcb616eeb6d40f02e66bebfe7b06d9f2ef81641fdd50b8dd981166e0b"},
|
||||
{file = "aiohttp-3.11.9-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:928f92f80e2e8d6567b87d3316c1fd9860ccfe36e87a9a7f5237d4cda8baa1ba"},
|
||||
{file = "aiohttp-3.11.9-cp39-cp39-win32.whl", hash = "sha256:c8a02f74ae419e3955af60f570d83187423e42e672a6433c5e292f1d23619269"},
|
||||
{file = "aiohttp-3.11.9-cp39-cp39-win_amd64.whl", hash = "sha256:0a97d657f6cf8782a830bb476c13f7d777cfcab8428ac49dde15c22babceb361"},
|
||||
{file = "aiohttp-3.11.9.tar.gz", hash = "sha256:a9266644064779840feec0e34f10a89b3ff1d2d6b751fe90017abcad1864fa7c"},
|
||||
{file = "aiohttp-3.11.10-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cbad88a61fa743c5d283ad501b01c153820734118b65aee2bd7dbb735475ce0d"},
|
||||
{file = "aiohttp-3.11.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80886dac673ceaef499de2f393fc80bb4481a129e6cb29e624a12e3296cc088f"},
|
||||
{file = "aiohttp-3.11.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:61b9bae80ed1f338c42f57c16918853dc51775fb5cb61da70d590de14d8b5fb4"},
|
||||
{file = "aiohttp-3.11.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9e2e576caec5c6a6b93f41626c9c02fc87cd91538b81a3670b2e04452a63def6"},
|
||||
{file = "aiohttp-3.11.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02c13415b5732fb6ee7ff64583a5e6ed1c57aa68f17d2bda79c04888dfdc2769"},
|
||||
{file = "aiohttp-3.11.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4cfce37f31f20800a6a6620ce2cdd6737b82e42e06e6e9bd1b36f546feb3c44f"},
|
||||
{file = "aiohttp-3.11.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3bbbfff4c679c64e6e23cb213f57cc2c9165c9a65d63717108a644eb5a7398df"},
|
||||
{file = "aiohttp-3.11.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49c7dbbc1a559ae14fc48387a115b7d4bbc84b4a2c3b9299c31696953c2a5219"},
|
||||
{file = "aiohttp-3.11.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:68386d78743e6570f054fe7949d6cb37ef2b672b4d3405ce91fafa996f7d9b4d"},
|
||||
{file = "aiohttp-3.11.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9ef405356ba989fb57f84cac66f7b0260772836191ccefbb987f414bcd2979d9"},
|
||||
{file = "aiohttp-3.11.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:5d6958671b296febe7f5f859bea581a21c1d05430d1bbdcf2b393599b1cdce77"},
|
||||
{file = "aiohttp-3.11.10-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:99b7920e7165be5a9e9a3a7f1b680f06f68ff0d0328ff4079e5163990d046767"},
|
||||
{file = "aiohttp-3.11.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0dc49f42422163efb7e6f1df2636fe3db72713f6cd94688e339dbe33fe06d61d"},
|
||||
{file = "aiohttp-3.11.10-cp310-cp310-win32.whl", hash = "sha256:40d1c7a7f750b5648642586ba7206999650208dbe5afbcc5284bcec6579c9b91"},
|
||||
{file = "aiohttp-3.11.10-cp310-cp310-win_amd64.whl", hash = "sha256:68ff6f48b51bd78ea92b31079817aff539f6c8fc80b6b8d6ca347d7c02384e33"},
|
||||
{file = "aiohttp-3.11.10-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:77c4aa15a89847b9891abf97f3d4048f3c2d667e00f8a623c89ad2dccee6771b"},
|
||||
{file = "aiohttp-3.11.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:909af95a72cedbefe5596f0bdf3055740f96c1a4baa0dd11fd74ca4de0b4e3f1"},
|
||||
{file = "aiohttp-3.11.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:386fbe79863eb564e9f3615b959e28b222259da0c48fd1be5929ac838bc65683"},
|
||||
{file = "aiohttp-3.11.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3de34936eb1a647aa919655ff8d38b618e9f6b7f250cc19a57a4bf7fd2062b6d"},
|
||||
{file = "aiohttp-3.11.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c9527819b29cd2b9f52033e7fb9ff08073df49b4799c89cb5754624ecd98299"},
|
||||
{file = "aiohttp-3.11.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65a96e3e03300b41f261bbfd40dfdbf1c301e87eab7cd61c054b1f2e7c89b9e8"},
|
||||
{file = "aiohttp-3.11.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98f5635f7b74bcd4f6f72fcd85bea2154b323a9f05226a80bc7398d0c90763b0"},
|
||||
{file = "aiohttp-3.11.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:03b6002e20938fc6ee0918c81d9e776bebccc84690e2b03ed132331cca065ee5"},
|
||||
{file = "aiohttp-3.11.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6362cc6c23c08d18ddbf0e8c4d5159b5df74fea1a5278ff4f2c79aed3f4e9f46"},
|
||||
{file = "aiohttp-3.11.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3691ed7726fef54e928fe26344d930c0c8575bc968c3e239c2e1a04bd8cf7838"},
|
||||
{file = "aiohttp-3.11.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31d5093d3acd02b31c649d3a69bb072d539d4c7659b87caa4f6d2bcf57c2fa2b"},
|
||||
{file = "aiohttp-3.11.10-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:8b3cf2dc0f0690a33f2d2b2cb15db87a65f1c609f53c37e226f84edb08d10f52"},
|
||||
{file = "aiohttp-3.11.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:fbbaea811a2bba171197b08eea288b9402faa2bab2ba0858eecdd0a4105753a3"},
|
||||
{file = "aiohttp-3.11.10-cp311-cp311-win32.whl", hash = "sha256:4b2c7ac59c5698a7a8207ba72d9e9c15b0fc484a560be0788b31312c2c5504e4"},
|
||||
{file = "aiohttp-3.11.10-cp311-cp311-win_amd64.whl", hash = "sha256:974d3a2cce5fcfa32f06b13ccc8f20c6ad9c51802bb7f829eae8a1845c4019ec"},
|
||||
{file = "aiohttp-3.11.10-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b78f053a7ecfc35f0451d961dacdc671f4bcbc2f58241a7c820e9d82559844cf"},
|
||||
{file = "aiohttp-3.11.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ab7485222db0959a87fbe8125e233b5a6f01f4400785b36e8a7878170d8c3138"},
|
||||
{file = "aiohttp-3.11.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cf14627232dfa8730453752e9cdc210966490992234d77ff90bc8dc0dce361d5"},
|
||||
{file = "aiohttp-3.11.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:076bc454a7e6fd646bc82ea7f98296be0b1219b5e3ef8a488afbdd8e81fbac50"},
|
||||
{file = "aiohttp-3.11.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:482cafb7dc886bebeb6c9ba7925e03591a62ab34298ee70d3dd47ba966370d2c"},
|
||||
{file = "aiohttp-3.11.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf3d1a519a324af764a46da4115bdbd566b3c73fb793ffb97f9111dbc684fc4d"},
|
||||
{file = "aiohttp-3.11.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24213ba85a419103e641e55c27dc7ff03536c4873470c2478cce3311ba1eee7b"},
|
||||
{file = "aiohttp-3.11.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b99acd4730ad1b196bfb03ee0803e4adac371ae8efa7e1cbc820200fc5ded109"},
|
||||
{file = "aiohttp-3.11.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:14cdb5a9570be5a04eec2ace174a48ae85833c2aadc86de68f55541f66ce42ab"},
|
||||
{file = "aiohttp-3.11.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7e97d622cb083e86f18317282084bc9fbf261801b0192c34fe4b1febd9f7ae69"},
|
||||
{file = "aiohttp-3.11.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:012f176945af138abc10c4a48743327a92b4ca9adc7a0e078077cdb5dbab7be0"},
|
||||
{file = "aiohttp-3.11.10-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44224d815853962f48fe124748227773acd9686eba6dc102578defd6fc99e8d9"},
|
||||
{file = "aiohttp-3.11.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c87bf31b7fdab94ae3adbe4a48e711bfc5f89d21cf4c197e75561def39e223bc"},
|
||||
{file = "aiohttp-3.11.10-cp312-cp312-win32.whl", hash = "sha256:06a8e2ee1cbac16fe61e51e0b0c269400e781b13bcfc33f5425912391a542985"},
|
||||
{file = "aiohttp-3.11.10-cp312-cp312-win_amd64.whl", hash = "sha256:be2b516f56ea883a3e14dda17059716593526e10fb6303189aaf5503937db408"},
|
||||
{file = "aiohttp-3.11.10-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8cc5203b817b748adccb07f36390feb730b1bc5f56683445bfe924fc270b8816"},
|
||||
{file = "aiohttp-3.11.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5ef359ebc6949e3a34c65ce20230fae70920714367c63afd80ea0c2702902ccf"},
|
||||
{file = "aiohttp-3.11.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9bca390cb247dbfaec3c664326e034ef23882c3f3bfa5fbf0b56cad0320aaca5"},
|
||||
{file = "aiohttp-3.11.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:811f23b3351ca532af598405db1093f018edf81368e689d1b508c57dcc6b6a32"},
|
||||
{file = "aiohttp-3.11.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddf5f7d877615f6a1e75971bfa5ac88609af3b74796ff3e06879e8422729fd01"},
|
||||
{file = "aiohttp-3.11.10-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6ab29b8a0beb6f8eaf1e5049252cfe74adbaafd39ba91e10f18caeb0e99ffb34"},
|
||||
{file = "aiohttp-3.11.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c49a76c1038c2dd116fa443eba26bbb8e6c37e924e2513574856de3b6516be99"},
|
||||
{file = "aiohttp-3.11.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f3dc0e330575f5b134918976a645e79adf333c0a1439dcf6899a80776c9ab39"},
|
||||
{file = "aiohttp-3.11.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:efb15a17a12497685304b2d976cb4939e55137df7b09fa53f1b6a023f01fcb4e"},
|
||||
{file = "aiohttp-3.11.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:db1d0b28fcb7f1d35600150c3e4b490775251dea70f894bf15c678fdd84eda6a"},
|
||||
{file = "aiohttp-3.11.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:15fccaf62a4889527539ecb86834084ecf6e9ea70588efde86e8bc775e0e7542"},
|
||||
{file = "aiohttp-3.11.10-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:593c114a2221444f30749cc5e5f4012488f56bd14de2af44fe23e1e9894a9c60"},
|
||||
{file = "aiohttp-3.11.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7852bbcb4d0d2f0c4d583f40c3bc750ee033265d80598d0f9cb6f372baa6b836"},
|
||||
{file = "aiohttp-3.11.10-cp313-cp313-win32.whl", hash = "sha256:65e55ca7debae8faaffee0ebb4b47a51b4075f01e9b641c31e554fd376595c6c"},
|
||||
{file = "aiohttp-3.11.10-cp313-cp313-win_amd64.whl", hash = "sha256:beb39a6d60a709ae3fb3516a1581777e7e8b76933bb88c8f4420d875bb0267c6"},
|
||||
{file = "aiohttp-3.11.10-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0580f2e12de2138f34debcd5d88894786453a76e98febaf3e8fe5db62d01c9bf"},
|
||||
{file = "aiohttp-3.11.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a55d2ad345684e7c3dd2c20d2f9572e9e1d5446d57200ff630e6ede7612e307f"},
|
||||
{file = "aiohttp-3.11.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:04814571cb72d65a6899db6099e377ed00710bf2e3eafd2985166f2918beaf59"},
|
||||
{file = "aiohttp-3.11.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e44a9a3c053b90c6f09b1bb4edd880959f5328cf63052503f892c41ea786d99f"},
|
||||
{file = "aiohttp-3.11.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:502a1464ccbc800b4b1995b302efaf426e8763fadf185e933c2931df7db9a199"},
|
||||
{file = "aiohttp-3.11.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:613e5169f8ae77b1933e42e418a95931fb4867b2991fc311430b15901ed67079"},
|
||||
{file = "aiohttp-3.11.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cca22a61b7fe45da8fc73c3443150c3608750bbe27641fc7558ec5117b27fdf"},
|
||||
{file = "aiohttp-3.11.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:86a5dfcc39309470bd7b68c591d84056d195428d5d2e0b5ccadfbaf25b026ebc"},
|
||||
{file = "aiohttp-3.11.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:77ae58586930ee6b2b6f696c82cf8e78c8016ec4795c53e36718365f6959dc82"},
|
||||
{file = "aiohttp-3.11.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:78153314f26d5abef3239b4a9af20c229c6f3ecb97d4c1c01b22c4f87669820c"},
|
||||
{file = "aiohttp-3.11.10-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:98283b94cc0e11c73acaf1c9698dea80c830ca476492c0fe2622bd931f34b487"},
|
||||
{file = "aiohttp-3.11.10-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:53bf2097e05c2accc166c142a2090e4c6fd86581bde3fd9b2d3f9e93dda66ac1"},
|
||||
{file = "aiohttp-3.11.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c5532f0441fc09c119e1dca18fbc0687e64fbeb45aa4d6a87211ceaee50a74c4"},
|
||||
{file = "aiohttp-3.11.10-cp39-cp39-win32.whl", hash = "sha256:47ad15a65fb41c570cd0ad9a9ff8012489e68176e7207ec7b82a0940dddfd8be"},
|
||||
{file = "aiohttp-3.11.10-cp39-cp39-win_amd64.whl", hash = "sha256:c6b9e6d7e41656d78e37ce754813fa44b455c3d0d0dced2a047def7dc5570b74"},
|
||||
{file = "aiohttp-3.11.10.tar.gz", hash = "sha256:b1fc6b45010a8d0ff9e88f9f2418c6fd408c99c211257334aff41597ebece42e"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -1047,17 +1047,17 @@ uvicorn = {version = ">=0.18.3", extras = ["standard"]}
|
||||
|
||||
[[package]]
|
||||
name = "clarifai"
|
||||
version = "10.8.0"
|
||||
version = "10.7.0"
|
||||
description = "Clarifai Python SDK"
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "clarifai-10.8.0-py3-none-any.whl", hash = "sha256:8caf4041ab704cba6225829d030e37ed41752613d8c4b4827323a9be9e312c17"},
|
||||
{file = "clarifai-10.8.0.tar.gz", hash = "sha256:068fbe63ac0d7d51630db6671db5e52b707f6d72d8e69c1d46092a84ca27a1a9"},
|
||||
{file = "clarifai-10.7.0-py3-none-any.whl", hash = "sha256:adf93f86a69569f07f88545155460e440bd94213797b2392119c2cbbf46a085d"},
|
||||
{file = "clarifai-10.7.0.tar.gz", hash = "sha256:8ae6c9b537f9f66cf2444d7ce85d7e27364de9643acf5e084a2019289499a9d1"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
clarifai-grpc = ">=10.8.0"
|
||||
clarifai-grpc = ">=10.7.0"
|
||||
inquirerpy = "0.3.4"
|
||||
numpy = ">=1.22.0"
|
||||
Pillow = ">=9.5.0"
|
||||
@@ -1073,18 +1073,18 @@ all = ["pycocotools (==2.0.6)"]
|
||||
|
||||
[[package]]
|
||||
name = "clarifai-grpc"
|
||||
version = "10.10.2"
|
||||
version = "10.7.1"
|
||||
description = "Clarifai gRPC API Client"
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "clarifai_grpc-10.10.2-py3-none-any.whl", hash = "sha256:2d25d2c79fe4e9aaa04ef3a121a3c470a34bd5869d8896fc2949201c5245570e"},
|
||||
{file = "clarifai_grpc-10.10.2.tar.gz", hash = "sha256:cfd04c9f8217c942242032ee08faaecfb784e14abe18441e45cc6526aec390ae"},
|
||||
{file = "clarifai_grpc-10.7.1-py3-none-any.whl", hash = "sha256:94395d332e71521ae14b6e449a65d6cd1b33f818e1e2fe7b0ea19d70ab764ee8"},
|
||||
{file = "clarifai_grpc-10.7.1.tar.gz", hash = "sha256:cd1e84d348396b5cae76d610391f2175addd6c6f704cfb4507bbe36da3d7c6fe"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
googleapis-common-protos = ">=1.53.0"
|
||||
grpcio = ">=1.44.0,<1.65.0"
|
||||
grpcio = ">=1.44.0"
|
||||
protobuf = ">=3.20.3"
|
||||
requests = ">=2.25.1"
|
||||
|
||||
@@ -2573,61 +2573,70 @@ protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4
|
||||
|
||||
[[package]]
|
||||
name = "grpcio"
|
||||
version = "1.64.3"
|
||||
version = "1.68.1"
|
||||
description = "HTTP/2-based RPC framework"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "grpcio-1.64.3-cp310-cp310-linux_armv7l.whl", hash = "sha256:32b6d78f378df38914cbb6340cec5e02ed78cb3c9cc9f7db3bb8c8132ccd1a9a"},
|
||||
{file = "grpcio-1.64.3-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:5900314a91ac4b4bad70b64c7ccd013605dcbad92a1e28f73b54dd7d1d32f09e"},
|
||||
{file = "grpcio-1.64.3-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:b6bb9d6180fc71a32a0608724f80f40d3c7e26910b65e9dd88e7c38d8400214f"},
|
||||
{file = "grpcio-1.64.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:efaadc7b76d8475aec84cbf79169457960274f018fb53e7da19eb752d0d6e924"},
|
||||
{file = "grpcio-1.64.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f6c9b6b91dcfe68fe50b15ea89bc602feb597b5191631ac3b3353d5dddc5a0d"},
|
||||
{file = "grpcio-1.64.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0d25eee06cfdfe2387d3394b313acee5a22148613a7d8dd3f994b369c019fc92"},
|
||||
{file = "grpcio-1.64.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7d613f6f4bfb4c475201c35bcdfd596ddfa0ed41906441dd514d5a972c7f364a"},
|
||||
{file = "grpcio-1.64.3-cp310-cp310-win32.whl", hash = "sha256:577249998c8f6db7275413431f05717be0fdc258a1f427827967a9fe21f83ad4"},
|
||||
{file = "grpcio-1.64.3-cp310-cp310-win_amd64.whl", hash = "sha256:9b11173fae31abd5ce81315696bad87daed5bdb74160e3cacd4bec9c352870d7"},
|
||||
{file = "grpcio-1.64.3-cp311-cp311-linux_armv7l.whl", hash = "sha256:56d21c7392aaf7c193a4ba1341974400cf268941007203b05e9bee707d0f2d83"},
|
||||
{file = "grpcio-1.64.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:145069b1ee5ee8bb1060f32b00f0f462838064879788cbcbc43d599cdbf5ab9e"},
|
||||
{file = "grpcio-1.64.3-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:a9f8a8c4cfbd43a44e6415e42995d7dbb8b98cb3a9d88eff34291ef670e69121"},
|
||||
{file = "grpcio-1.64.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6902b9ebfc833a927aa0f41fe1ffa986a2666ae96c909c7d0cf265cabc78ce93"},
|
||||
{file = "grpcio-1.64.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee2987148d689f14f53b8cdb3c2545d42826343e38d0d31c00ab9249ecbe579d"},
|
||||
{file = "grpcio-1.64.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a87076b01979d7e0297f6cd79d6ad90f305bd0168a2d217c6ae9870023f76776"},
|
||||
{file = "grpcio-1.64.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fe357d7b2114568b55dde795c324c272e0029a48fdcb7c2eb5ee06a311c19b91"},
|
||||
{file = "grpcio-1.64.3-cp311-cp311-win32.whl", hash = "sha256:48933a53b57941ed02a2c97a5a821872fec80d4240c936df7800a5af0c89263f"},
|
||||
{file = "grpcio-1.64.3-cp311-cp311-win_amd64.whl", hash = "sha256:5bbeea3aac7dc25fdbf39a42cd99e7b8cce9ad248ed99747c403de540fc1157d"},
|
||||
{file = "grpcio-1.64.3-cp312-cp312-linux_armv7l.whl", hash = "sha256:90dc5acc2059737b98b849b910fde8ff83467fe5d791042333d007136085c7e0"},
|
||||
{file = "grpcio-1.64.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f5674f0c9ff5af675a85e1ff03546f938b1e9f28022535e18482835165016cc7"},
|
||||
{file = "grpcio-1.64.3-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:9a6a1c0b5133fdcde4473112000eae10d04cafd8bcd6d0a1fe01b04535e24f49"},
|
||||
{file = "grpcio-1.64.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb19ec6c0b3064a8f94e0842804be185ce2c7a872ea45327f4c7b626b67b663b"},
|
||||
{file = "grpcio-1.64.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54fe53b503746f76981b96e7c6c8fde7d3cc1fdfd804e7aa399e7eb0d24d5b65"},
|
||||
{file = "grpcio-1.64.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:448cb624544caa17f90acce094b6cfab8f7f788c616be591114d679c580e8485"},
|
||||
{file = "grpcio-1.64.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:786f6c15d648b29ef25278de9026c9f2042903b9e875830b64f27816e3055b93"},
|
||||
{file = "grpcio-1.64.3-cp312-cp312-win32.whl", hash = "sha256:7599dc7d4ff6079612386fe93f45a98c3f2bea66e59bcf1c5de811d2c4da8084"},
|
||||
{file = "grpcio-1.64.3-cp312-cp312-win_amd64.whl", hash = "sha256:2b3154eb0cb1db36934c7fbb7686698650a607b9581bad103101ed86462e369e"},
|
||||
{file = "grpcio-1.64.3-cp38-cp38-linux_armv7l.whl", hash = "sha256:25532056a702a3fdb7a7306da87d49f5636e5b5495abdb9dfd9bb20149a300ca"},
|
||||
{file = "grpcio-1.64.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:896461893a76c933ae6b05595255a3f49e6161cc805d94fbc74359ad5f213681"},
|
||||
{file = "grpcio-1.64.3-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:ae947a47a793da4df0ea3af6ebf9c3e3d8bcf266a86c9547778e6d750ce2f69d"},
|
||||
{file = "grpcio-1.64.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fae61bcbbbf9bcc48178bb03ea419b5faca48b420e53e663bbb57d65c3bd6733"},
|
||||
{file = "grpcio-1.64.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce0a8bcb9ff28cb972353cf321759872cfdb27f927b2b9442a599198c53d4013"},
|
||||
{file = "grpcio-1.64.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cc4ebad61b073ae08326b61c2a0707fc7aa1a53bd4db201408b7d118db51b94c"},
|
||||
{file = "grpcio-1.64.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9c8ee1858eab59e6a6aed142d698a37e9474394956e399b69b8ec32977ce2d0d"},
|
||||
{file = "grpcio-1.64.3-cp38-cp38-win32.whl", hash = "sha256:be3e5d3b693e9998599c5a173af56c11de14ae37fa21bb071c24ed09ac80bee7"},
|
||||
{file = "grpcio-1.64.3-cp38-cp38-win_amd64.whl", hash = "sha256:48cabd2278e6f3dc20a5bf8a73b20e3663297d40dc7702b5e4513c50bbd5cbc3"},
|
||||
{file = "grpcio-1.64.3-cp39-cp39-linux_armv7l.whl", hash = "sha256:bcb1a5c09151b2454463143125b591b2909138e56b7dcbcb310cc98b21f56a14"},
|
||||
{file = "grpcio-1.64.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d7a600d6eddaf579bdbda4e8a6ce03ee1c7a7ff66635ab1b19cf0e5b6618829e"},
|
||||
{file = "grpcio-1.64.3-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:137be8c41cdb284fecd9f823c680522e602fca810aa38fa008e29d9e8b2bfe5a"},
|
||||
{file = "grpcio-1.64.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3e707bd119d2ddd521f45d0f0e6cb1c0714b900fa4644a6c16a5b68050065083"},
|
||||
{file = "grpcio-1.64.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:595cf5a0b4bcb1f583f7014defe4cf96cf8fc1225d1f221c1dbfc5773c619900"},
|
||||
{file = "grpcio-1.64.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:50553d7d48d9107bc1dcce745ca5d4f62f7a82c6780df0acb42e50ced766a2fc"},
|
||||
{file = "grpcio-1.64.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1f937a3124bfcb8995d78c1f9a9600395d97c5674703c823018dc5764e16ae5e"},
|
||||
{file = "grpcio-1.64.3-cp39-cp39-win32.whl", hash = "sha256:067a1d9539e4822f03982d0736e2e6890b356a255d82452921555165154a3c1e"},
|
||||
{file = "grpcio-1.64.3-cp39-cp39-win_amd64.whl", hash = "sha256:ca272e96578a844a6cb4f3b461c419ae9c30c039cb7ff4e69624d68005ef9c38"},
|
||||
{file = "grpcio-1.64.3.tar.gz", hash = "sha256:f37a0297293918c695e625d7148f99f4e401298d1b6e2bea7a8e9130aa940419"},
|
||||
{file = "grpcio-1.68.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:d35740e3f45f60f3c37b1e6f2f4702c23867b9ce21c6410254c9c682237da68d"},
|
||||
{file = "grpcio-1.68.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:d99abcd61760ebb34bdff37e5a3ba333c5cc09feda8c1ad42547bea0416ada78"},
|
||||
{file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:f8261fa2a5f679abeb2a0a93ad056d765cdca1c47745eda3f2d87f874ff4b8c9"},
|
||||
{file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0feb02205a27caca128627bd1df4ee7212db051019a9afa76f4bb6a1a80ca95e"},
|
||||
{file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:919d7f18f63bcad3a0f81146188e90274fde800a94e35d42ffe9eadf6a9a6330"},
|
||||
{file = "grpcio-1.68.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:963cc8d7d79b12c56008aabd8b457f400952dbea8997dd185f155e2f228db079"},
|
||||
{file = "grpcio-1.68.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ccf2ebd2de2d6661e2520dae293298a3803a98ebfc099275f113ce1f6c2a80f1"},
|
||||
{file = "grpcio-1.68.1-cp310-cp310-win32.whl", hash = "sha256:2cc1fd04af8399971bcd4f43bd98c22d01029ea2e56e69c34daf2bf8470e47f5"},
|
||||
{file = "grpcio-1.68.1-cp310-cp310-win_amd64.whl", hash = "sha256:ee2e743e51cb964b4975de572aa8fb95b633f496f9fcb5e257893df3be854746"},
|
||||
{file = "grpcio-1.68.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:55857c71641064f01ff0541a1776bfe04a59db5558e82897d35a7793e525774c"},
|
||||
{file = "grpcio-1.68.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4b177f5547f1b995826ef529d2eef89cca2f830dd8b2c99ffd5fde4da734ba73"},
|
||||
{file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:3522c77d7e6606d6665ec8d50e867f13f946a4e00c7df46768f1c85089eae515"},
|
||||
{file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d1fae6bbf0816415b81db1e82fb3bf56f7857273c84dcbe68cbe046e58e1ccd"},
|
||||
{file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:298ee7f80e26f9483f0b6f94cc0a046caf54400a11b644713bb5b3d8eb387600"},
|
||||
{file = "grpcio-1.68.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cbb5780e2e740b6b4f2d208e90453591036ff80c02cc605fea1af8e6fc6b1bbe"},
|
||||
{file = "grpcio-1.68.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ddda1aa22495d8acd9dfbafff2866438d12faec4d024ebc2e656784d96328ad0"},
|
||||
{file = "grpcio-1.68.1-cp311-cp311-win32.whl", hash = "sha256:b33bd114fa5a83f03ec6b7b262ef9f5cac549d4126f1dc702078767b10c46ed9"},
|
||||
{file = "grpcio-1.68.1-cp311-cp311-win_amd64.whl", hash = "sha256:7f20ebec257af55694d8f993e162ddf0d36bd82d4e57f74b31c67b3c6d63d8b2"},
|
||||
{file = "grpcio-1.68.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:8829924fffb25386995a31998ccbbeaa7367223e647e0122043dfc485a87c666"},
|
||||
{file = "grpcio-1.68.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3aed6544e4d523cd6b3119b0916cef3d15ef2da51e088211e4d1eb91a6c7f4f1"},
|
||||
{file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:4efac5481c696d5cb124ff1c119a78bddbfdd13fc499e3bc0ca81e95fc573684"},
|
||||
{file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ab2d912ca39c51f46baf2a0d92aa265aa96b2443266fc50d234fa88bf877d8e"},
|
||||
{file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c87ce2a97434dffe7327a4071839ab8e8bffd0054cc74cbe971fba98aedd60"},
|
||||
{file = "grpcio-1.68.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e4842e4872ae4ae0f5497bf60a0498fa778c192cc7a9e87877abd2814aca9475"},
|
||||
{file = "grpcio-1.68.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:255b1635b0ed81e9f91da4fcc8d43b7ea5520090b9a9ad9340d147066d1d3613"},
|
||||
{file = "grpcio-1.68.1-cp312-cp312-win32.whl", hash = "sha256:7dfc914cc31c906297b30463dde0b9be48e36939575eaf2a0a22a8096e69afe5"},
|
||||
{file = "grpcio-1.68.1-cp312-cp312-win_amd64.whl", hash = "sha256:a0c8ddabef9c8f41617f213e527254c41e8b96ea9d387c632af878d05db9229c"},
|
||||
{file = "grpcio-1.68.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:a47faedc9ea2e7a3b6569795c040aae5895a19dde0c728a48d3c5d7995fda385"},
|
||||
{file = "grpcio-1.68.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:390eee4225a661c5cd133c09f5da1ee3c84498dc265fd292a6912b65c421c78c"},
|
||||
{file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:66a24f3d45c33550703f0abb8b656515b0ab777970fa275693a2f6dc8e35f1c1"},
|
||||
{file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c08079b4934b0bf0a8847f42c197b1d12cba6495a3d43febd7e99ecd1cdc8d54"},
|
||||
{file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8720c25cd9ac25dd04ee02b69256d0ce35bf8a0f29e20577427355272230965a"},
|
||||
{file = "grpcio-1.68.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:04cfd68bf4f38f5bb959ee2361a7546916bd9a50f78617a346b3aeb2b42e2161"},
|
||||
{file = "grpcio-1.68.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c28848761a6520c5c6071d2904a18d339a796ebe6b800adc8b3f474c5ce3c3ad"},
|
||||
{file = "grpcio-1.68.1-cp313-cp313-win32.whl", hash = "sha256:77d65165fc35cff6e954e7fd4229e05ec76102d4406d4576528d3a3635fc6172"},
|
||||
{file = "grpcio-1.68.1-cp313-cp313-win_amd64.whl", hash = "sha256:a8040f85dcb9830d8bbb033ae66d272614cec6faceee88d37a88a9bd1a7a704e"},
|
||||
{file = "grpcio-1.68.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:eeb38ff04ab6e5756a2aef6ad8d94e89bb4a51ef96e20f45c44ba190fa0bcaad"},
|
||||
{file = "grpcio-1.68.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8a3869a6661ec8f81d93f4597da50336718bde9eb13267a699ac7e0a1d6d0bea"},
|
||||
{file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:2c4cec6177bf325eb6faa6bd834d2ff6aa8bb3b29012cceb4937b86f8b74323c"},
|
||||
{file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12941d533f3cd45d46f202e3667be8ebf6bcb3573629c7ec12c3e211d99cfccf"},
|
||||
{file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80af6f1e69c5e68a2be529990684abdd31ed6622e988bf18850075c81bb1ad6e"},
|
||||
{file = "grpcio-1.68.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e8dbe3e00771bfe3d04feed8210fc6617006d06d9a2679b74605b9fed3e8362c"},
|
||||
{file = "grpcio-1.68.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:83bbf5807dc3ee94ce1de2dfe8a356e1d74101e4b9d7aa8c720cc4818a34aded"},
|
||||
{file = "grpcio-1.68.1-cp38-cp38-win32.whl", hash = "sha256:8cb620037a2fd9eeee97b4531880e439ebfcd6d7d78f2e7dcc3726428ab5ef63"},
|
||||
{file = "grpcio-1.68.1-cp38-cp38-win_amd64.whl", hash = "sha256:52fbf85aa71263380d330f4fce9f013c0798242e31ede05fcee7fbe40ccfc20d"},
|
||||
{file = "grpcio-1.68.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:cb400138e73969eb5e0535d1d06cae6a6f7a15f2cc74add320e2130b8179211a"},
|
||||
{file = "grpcio-1.68.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a1b988b40f2fd9de5c820f3a701a43339d8dcf2cb2f1ca137e2c02671cc83ac1"},
|
||||
{file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:96f473cdacfdd506008a5d7579c9f6a7ff245a9ade92c3c0265eb76cc591914f"},
|
||||
{file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:37ea3be171f3cf3e7b7e412a98b77685eba9d4fd67421f4a34686a63a65d99f9"},
|
||||
{file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ceb56c4285754e33bb3c2fa777d055e96e6932351a3082ce3559be47f8024f0"},
|
||||
{file = "grpcio-1.68.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:dffd29a2961f3263a16d73945b57cd44a8fd0b235740cb14056f0612329b345e"},
|
||||
{file = "grpcio-1.68.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:025f790c056815b3bf53da850dd70ebb849fd755a4b1ac822cb65cd631e37d43"},
|
||||
{file = "grpcio-1.68.1-cp39-cp39-win32.whl", hash = "sha256:1098f03dedc3b9810810568060dea4ac0822b4062f537b0f53aa015269be0a76"},
|
||||
{file = "grpcio-1.68.1-cp39-cp39-win_amd64.whl", hash = "sha256:334ab917792904245a028f10e803fcd5b6f36a7b2173a820c0b5b076555825e1"},
|
||||
{file = "grpcio-1.68.1.tar.gz", hash = "sha256:44a8502dd5de653ae6a73e2de50a401d84184f0331d0ac3daeb044e66d5c5054"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
protobuf = ["grpcio-tools (>=1.64.3)"]
|
||||
protobuf = ["grpcio-tools (>=1.68.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "grpcio-status"
|
||||
@@ -2779,13 +2788,13 @@ test = ["Cython (>=0.29.24)"]
|
||||
|
||||
[[package]]
|
||||
name = "httpx"
|
||||
version = "0.28.0"
|
||||
version = "0.28.1"
|
||||
description = "The next generation HTTP client."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "httpx-0.28.0-py3-none-any.whl", hash = "sha256:dc0b419a0cfeb6e8b34e85167c0da2671206f5095f1baa9663d23bcfd6b535fc"},
|
||||
{file = "httpx-0.28.0.tar.gz", hash = "sha256:0858d3bab51ba7e386637f22a61d8ccddaeec5f3fe4209da3a6168dbb91573e0"},
|
||||
{file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"},
|
||||
{file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -2814,13 +2823,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "huggingface-hub"
|
||||
version = "0.26.3"
|
||||
version = "0.26.5"
|
||||
description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub"
|
||||
optional = false
|
||||
python-versions = ">=3.8.0"
|
||||
files = [
|
||||
{file = "huggingface_hub-0.26.3-py3-none-any.whl", hash = "sha256:e66aa99e569c2d5419240a9e553ad07245a5b1300350bfbc5a4945cf7432991b"},
|
||||
{file = "huggingface_hub-0.26.3.tar.gz", hash = "sha256:90e1fe62ffc26757a073aaad618422b899ccf9447c2bba8c902a90bef5b42e1d"},
|
||||
{file = "huggingface_hub-0.26.5-py3-none-any.whl", hash = "sha256:fb7386090bbe892072e64b85f7c4479fd2d65eea5f2543327c970d5169e83924"},
|
||||
{file = "huggingface_hub-0.26.5.tar.gz", hash = "sha256:1008bd18f60bfb65e8dbc0a97249beeeaa8c99d3c2fa649354df9fa5a13ed83b"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -3840,13 +3849,13 @@ source = ["Cython (>=3.0.11)"]
|
||||
|
||||
[[package]]
|
||||
name = "mako"
|
||||
version = "1.3.7"
|
||||
version = "1.3.8"
|
||||
description = "A super-fast templating language that borrows the best ideas from the existing templating languages."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "Mako-1.3.7-py3-none-any.whl", hash = "sha256:d18f990ad57f800ce8e76cbfb0b74afe471c293517e9f5003ace6dad5aa72c36"},
|
||||
{file = "mako-1.3.7.tar.gz", hash = "sha256:20405b1232e0759f0e7d87b01f6bb94fce0761747f1cb876ecf90bd512d0b639"},
|
||||
{file = "Mako-1.3.8-py3-none-any.whl", hash = "sha256:42f48953c7eb91332040ff567eb7eea69b22e7a4affbc5ba8e845e8f730f6627"},
|
||||
{file = "mako-1.3.8.tar.gz", hash = "sha256:577b97e414580d3e088d47c2dbbe9594aa7a5146ed2875d4dfa9075af2dd3cc8"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -4172,13 +4181,13 @@ pygments = ">2.12.0"
|
||||
|
||||
[[package]]
|
||||
name = "mkdocs-material"
|
||||
version = "9.5.47"
|
||||
version = "9.5.48"
|
||||
description = "Documentation that simply works"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "mkdocs_material-9.5.47-py3-none-any.whl", hash = "sha256:53fb9c9624e7865da6ec807d116cd7be24b3cb36ab31b1d1d1a9af58c56009a2"},
|
||||
{file = "mkdocs_material-9.5.47.tar.gz", hash = "sha256:fc3b7a8e00ad896660bd3a5cc12ca0cb28bdc2bcbe2a946b5714c23ac91b0ede"},
|
||||
{file = "mkdocs_material-9.5.48-py3-none-any.whl", hash = "sha256:b695c998f4b939ce748adbc0d3bff73fa886a670ece948cf27818fa115dc16f8"},
|
||||
{file = "mkdocs_material-9.5.48.tar.gz", hash = "sha256:a582531e8b34f4c7ed38c29d5c44763053832cf2a32f7409567e0c74749a47db"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -5511,20 +5520,20 @@ virtualenv = ">=20.10.0"
|
||||
|
||||
[[package]]
|
||||
name = "primp"
|
||||
version = "0.8.1"
|
||||
version = "0.8.2"
|
||||
description = "HTTP client that can impersonate web browsers, mimicking their headers and `TLS/JA3/JA4/HTTP2` fingerprints"
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "primp-0.8.1-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:8294db817701ad76b6a186c16e22cc49d36fac5986647a83657ad4a58ddeee42"},
|
||||
{file = "primp-0.8.1-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:e8117531dcdb0dbcf9855fdbac73febdde5967ca0332a2c05b5961d2fbcfe749"},
|
||||
{file = "primp-0.8.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:993cc4284e8c5c858254748f078e872ba250c9339d64398dc000a8f9cffadda3"},
|
||||
{file = "primp-0.8.1-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4a27ac642be5c616fc5f139a5ad391dcd0c5964ace56fe6cf31cbffb972a7480"},
|
||||
{file = "primp-0.8.1-cp38-abi3-manylinux_2_34_armv7l.whl", hash = "sha256:e8483b8d9eec9fc43d77bb448555466030f29cdd99d9375eb75155e9f832e5bd"},
|
||||
{file = "primp-0.8.1-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:92f5f8267216252cfb27f2149811e14682bb64f0c5d37f00d218d1592e02f0b9"},
|
||||
{file = "primp-0.8.1-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:98f7f3a9481c55c56e7eff9024f29e16379a87d5b0a1b683e145dd8fcbdcc46b"},
|
||||
{file = "primp-0.8.1-cp38-abi3-win_amd64.whl", hash = "sha256:6f0018a26be787431504e32548b296a278abbe85da43bcbaf2d4982ac3dcd332"},
|
||||
{file = "primp-0.8.1.tar.gz", hash = "sha256:ddf05754a7b70d59df8a014a8585e418f9c04e0b69065bab6633f4a9b92bad93"},
|
||||
{file = "primp-0.8.2-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:20c4988c6538dfcac804e804f286493696e53498d5705e745a36d9fe436c787c"},
|
||||
{file = "primp-0.8.2-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:dde74d6bf5534a60fd075e81b5828a6591753a647c5bfe69e664883e5c7a28bb"},
|
||||
{file = "primp-0.8.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f988d7e47d7f63b63f851885d51abd86ba3a2a1981d047466c1e63827753a168"},
|
||||
{file = "primp-0.8.2-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:965cf0c19986d074d4e20ce18f1b81e5c31818324718814af6317a291a3aba65"},
|
||||
{file = "primp-0.8.2-cp38-abi3-manylinux_2_34_armv7l.whl", hash = "sha256:afc56989ae09bed76105bf045e666ea2da5f32e2e93dfb967795a4da4fc777e5"},
|
||||
{file = "primp-0.8.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:64e8b9b216ee0f52d2885ac23303000339f798a59eb9b4b3b747dcbbf9187beb"},
|
||||
{file = "primp-0.8.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b65de6d8fe4c7ef9d5d508e2a9cee3da77455e3a44c9282bdebb2134c55087c9"},
|
||||
{file = "primp-0.8.2-cp38-abi3-win_amd64.whl", hash = "sha256:d686cf4ce21c318bafe2f0574aec9f7f9526d18a4b0c017f507bd007f323e519"},
|
||||
{file = "primp-0.8.2.tar.gz", hash = "sha256:572ecd34b77021a89a0574b66b07e1da100afd6ec490d3b519a6763fac6ae6c5"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
@@ -5866,13 +5875,13 @@ pyasn1 = ">=0.4.6,<0.7.0"
|
||||
|
||||
[[package]]
|
||||
name = "pyautogen"
|
||||
version = "0.4.1"
|
||||
version = "0.5.0"
|
||||
description = "A programming framework for agentic AI"
|
||||
optional = true
|
||||
python-versions = "<3.14,>=3.8"
|
||||
files = [
|
||||
{file = "pyautogen-0.4.1-py3-none-any.whl", hash = "sha256:5e1820f21239adabe548ef2aea6f3182232fea8a761b6f862281229b738e62ed"},
|
||||
{file = "pyautogen-0.4.1.tar.gz", hash = "sha256:48ca3b7d26119b6eac580c4618b5038f98a427fbcee4383fdd9c8e4353ba2708"},
|
||||
{file = "pyautogen-0.5.0-py3-none-any.whl", hash = "sha256:e0d1407302ec7d86a86caa8ce9524b91c0d9030e96457b1d8fe89b86c7ca7aa9"},
|
||||
{file = "pyautogen-0.5.0.tar.gz", hash = "sha256:cced78493a3006a1c0d0ddcc41bdfc5d1ab890e5818250927d34e1bb92537561"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -5898,7 +5907,7 @@ cohere = ["cohere (>=5.5.8)"]
|
||||
cosmosdb = ["azure-cosmos (>=4.2.0)"]
|
||||
gemini = ["google-auth", "google-cloud-aiplatform", "google-generativeai (>=0.5,<1)", "pillow", "pydantic"]
|
||||
graph = ["matplotlib", "networkx"]
|
||||
graph-rag-falkor-db = ["graphrag-sdk (==0.3.3)"]
|
||||
graph-rag-falkor-db = ["falkordb (>=1.0.10)", "graphrag-sdk (==0.3.3)"]
|
||||
groq = ["groq (>=0.9.0)"]
|
||||
jupyter-executor = ["ipykernel (>=6.29.0)", "jupyter-client (>=8.6.0)", "jupyter-kernel-gateway", "requests", "websocket-client"]
|
||||
lmm = ["pillow", "replicate"]
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ class Praisonai < Formula
|
||||
|
||||
desc "AI tools for various AI applications"
|
||||
homepage "https://github.com/MervinPraison/PraisonAI"
|
||||
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/1.0.4.tar.gz"
|
||||
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/1.0.5.tar.gz"
|
||||
sha256 "1828fb9227d10f991522c3f24f061943a254b667196b40b1a3e4a54a8d30ce32" # Replace with actual SHA256 checksum
|
||||
license "MIT"
|
||||
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ class CloudDeployer:
|
||||
file.write("FROM python:3.11-slim\n")
|
||||
file.write("WORKDIR /app\n")
|
||||
file.write("COPY . .\n")
|
||||
file.write("RUN pip install flask praisonai==1.0.4 gunicorn markdown\n")
|
||||
file.write("RUN pip install flask praisonai==1.0.5 gunicorn markdown\n")
|
||||
file.write("EXPOSE 8080\n")
|
||||
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Changes to DB
|
||||
|
||||
The following columns are renamed or modified between the first and second versions of the code:
|
||||
|
||||
| Table Name | Original Column Name | New Column Name |
|
||||
|-------------|----------------------------|--------------------|
|
||||
| `users` | `metadata` | `meta` |
|
||||
| `users` | `created_at` | `createdAt` |
|
||||
| `threads` | `metadata` | `meta` |
|
||||
| `threads` | `created_at` | `createdAt` |
|
||||
| `steps` | `metadata` | `meta` |
|
||||
| `steps` | `start_time` | `startTime` |
|
||||
| `steps` | `end_time` | `endTime` |
|
||||
| `elements` | `metadata` | (Removed) |
|
||||
|
||||
Key changes:
|
||||
1. The `metadata` column in several tables is renamed to `meta`.
|
||||
2. Timestamps (`created_at`, `start_time`, and `end_time`) are renamed to PascalCase (`createdAt`, `startTime`, and `endTime`).
|
||||
3. Some columns are removed (e.g., `metadata` in `elements`).
|
||||
|
||||
These changes make the column names consistent and follow a specific naming convention.
|
||||
+263
-333
@@ -1,6 +1,6 @@
|
||||
import chainlit as cl
|
||||
from chainlit.input_widget import TextInput
|
||||
from chainlit.types import ThreadDict
|
||||
from chainlit.types import ThreadDict
|
||||
from litellm import acompletion
|
||||
import os
|
||||
import sqlite3
|
||||
@@ -9,6 +9,7 @@ from typing import Dict, List, Optional
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
import chainlit.data as cl_data
|
||||
from chainlit.step import StepDict
|
||||
from literalai.helper import utc_now
|
||||
import logging
|
||||
import json
|
||||
@@ -19,275 +20,275 @@ import asyncio
|
||||
from PIL import Image
|
||||
import io
|
||||
import base64
|
||||
from sqlalchemy import text
|
||||
from sqlalchemy.exc import DatabaseError
|
||||
|
||||
# Set up logging
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from sqlalchemy import text
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
log_level = os.getenv("LOGLEVEL", "INFO").upper()
|
||||
logger.handlers = []
|
||||
|
||||
# Set up logging to console
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setLevel(log_level)
|
||||
console_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
console_handler.setFormatter(console_formatter)
|
||||
logger.addHandler(console_handler)
|
||||
|
||||
# Set the logging level for the logger
|
||||
logger.setLevel(log_level)
|
||||
|
||||
CHAINLIT_AUTH_SECRET = os.getenv("CHAINLIT_AUTH_SECRET")
|
||||
|
||||
if not CHAINLIT_AUTH_SECRET:
|
||||
os.environ["CHAINLIT_AUTH_SECRET"] = "p8BPhQChpg@J>jBz$wGxqLX2V>yTVgP*7Ky9H$aV:axW~ANNX-7_T:o@lnyCBu^U"
|
||||
CHAINLIT_AUTH_SECRET = os.getenv("CHAINLIT_AUTH_SECRET")
|
||||
|
||||
now = utc_now()
|
||||
|
||||
create_step_counter = 0
|
||||
|
||||
DB_PATH = os.path.expanduser("~/.praison/database.sqlite")
|
||||
DATABASE_URL = os.getenv("DATABASE_URL")
|
||||
|
||||
async def create_tables(engine):
|
||||
"""Create all necessary tables if they don't exist."""
|
||||
try:
|
||||
async with engine.begin() as conn:
|
||||
# Check if we're using PostgreSQL
|
||||
dialect = engine.dialect.name
|
||||
if dialect == 'postgresql':
|
||||
# Create tables with PostgreSQL-specific types
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id UUID PRIMARY KEY,
|
||||
identifier TEXT NOT NULL UNIQUE,
|
||||
metadata JSONB NOT NULL,
|
||||
created_at TEXT
|
||||
)
|
||||
"""))
|
||||
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS threads (
|
||||
id UUID PRIMARY KEY,
|
||||
created_at TEXT,
|
||||
name TEXT,
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
||||
user_identifier TEXT,
|
||||
tags TEXT[],
|
||||
metadata JSONB NOT NULL DEFAULT '{}'
|
||||
)
|
||||
"""))
|
||||
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS steps (
|
||||
id UUID PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
type TEXT NOT NULL,
|
||||
thread_id UUID NOT NULL REFERENCES threads(id) ON DELETE CASCADE,
|
||||
parent_id UUID,
|
||||
disable_feedback BOOLEAN NOT NULL DEFAULT false,
|
||||
streaming BOOLEAN NOT NULL DEFAULT false,
|
||||
wait_for_answer BOOLEAN DEFAULT false,
|
||||
is_error BOOLEAN NOT NULL DEFAULT false,
|
||||
metadata JSONB DEFAULT '{}',
|
||||
tags TEXT[],
|
||||
input TEXT,
|
||||
output TEXT,
|
||||
created_at TEXT,
|
||||
start_time TEXT,
|
||||
end_time TEXT,
|
||||
generation JSONB,
|
||||
show_input TEXT,
|
||||
language TEXT,
|
||||
indent INTEGER
|
||||
)
|
||||
"""))
|
||||
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS elements (
|
||||
id UUID PRIMARY KEY,
|
||||
thread_id UUID REFERENCES threads(id) ON DELETE CASCADE,
|
||||
type TEXT,
|
||||
url TEXT,
|
||||
chainlit_key TEXT,
|
||||
name TEXT NOT NULL,
|
||||
display TEXT,
|
||||
object_key TEXT,
|
||||
size TEXT,
|
||||
page INTEGER,
|
||||
language TEXT,
|
||||
for_id UUID,
|
||||
mime TEXT
|
||||
)
|
||||
"""))
|
||||
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS feedbacks (
|
||||
id UUID PRIMARY KEY,
|
||||
for_id UUID NOT NULL,
|
||||
value INTEGER NOT NULL,
|
||||
thread_id UUID,
|
||||
comment TEXT
|
||||
)
|
||||
"""))
|
||||
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
id SERIAL PRIMARY KEY,
|
||||
key TEXT UNIQUE,
|
||||
value TEXT
|
||||
)
|
||||
"""))
|
||||
|
||||
# Create indexes
|
||||
await conn.execute(text(
|
||||
"CREATE INDEX IF NOT EXISTS idx_steps_thread_id ON steps(thread_id)"
|
||||
))
|
||||
await conn.execute(text(
|
||||
"CREATE INDEX IF NOT EXISTS idx_threads_created_at ON threads(created_at DESC)"
|
||||
))
|
||||
else:
|
||||
# SQLite tables (existing schema)
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id TEXT PRIMARY KEY,
|
||||
identifier TEXT NOT NULL UNIQUE,
|
||||
metadata TEXT NOT NULL,
|
||||
created_at TEXT
|
||||
)
|
||||
"""))
|
||||
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS threads (
|
||||
id TEXT PRIMARY KEY,
|
||||
created_at TEXT,
|
||||
name TEXT,
|
||||
user_id TEXT REFERENCES users(id) ON DELETE CASCADE,
|
||||
user_identifier TEXT,
|
||||
tags TEXT,
|
||||
metadata TEXT NOT NULL DEFAULT '{}'
|
||||
)
|
||||
"""))
|
||||
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS steps (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
type TEXT NOT NULL,
|
||||
thread_id TEXT NOT NULL REFERENCES threads(id) ON DELETE CASCADE,
|
||||
parent_id TEXT,
|
||||
disable_feedback INTEGER NOT NULL DEFAULT 0,
|
||||
streaming INTEGER NOT NULL DEFAULT 0,
|
||||
wait_for_answer INTEGER DEFAULT 0,
|
||||
is_error INTEGER NOT NULL DEFAULT 0,
|
||||
metadata TEXT DEFAULT '{}',
|
||||
tags TEXT,
|
||||
input TEXT,
|
||||
output TEXT,
|
||||
created_at TEXT,
|
||||
start_time TEXT,
|
||||
end_time TEXT,
|
||||
generation TEXT,
|
||||
show_input TEXT,
|
||||
language TEXT,
|
||||
indent INTEGER
|
||||
)
|
||||
"""))
|
||||
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS elements (
|
||||
id TEXT PRIMARY KEY,
|
||||
thread_id TEXT REFERENCES threads(id) ON DELETE CASCADE,
|
||||
type TEXT,
|
||||
url TEXT,
|
||||
chainlit_key TEXT,
|
||||
name TEXT NOT NULL,
|
||||
display TEXT,
|
||||
object_key TEXT,
|
||||
size TEXT,
|
||||
page INTEGER,
|
||||
language TEXT,
|
||||
for_id TEXT,
|
||||
mime TEXT
|
||||
)
|
||||
"""))
|
||||
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS feedbacks (
|
||||
id TEXT PRIMARY KEY,
|
||||
for_id TEXT NOT NULL,
|
||||
value INTEGER NOT NULL,
|
||||
thread_id TEXT,
|
||||
comment TEXT
|
||||
)
|
||||
"""))
|
||||
|
||||
await conn.execute(text("""
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
key TEXT UNIQUE,
|
||||
value TEXT
|
||||
)
|
||||
"""))
|
||||
|
||||
# Create indexes
|
||||
await conn.execute(text(
|
||||
"CREATE INDEX IF NOT EXISTS idx_steps_thread_id ON steps(thread_id)"
|
||||
))
|
||||
await conn.execute(text(
|
||||
"CREATE INDEX IF NOT EXISTS idx_threads_created_at ON threads(created_at DESC)"
|
||||
))
|
||||
|
||||
logger.info(f"Successfully created tables for {dialect} database")
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating tables: {str(e)}")
|
||||
from sqlalchemy.exc import DatabaseError as SQLAlchemyDatabaseError
|
||||
raise SQLAlchemyDatabaseError(statement=str(e), params=None, orig=e)
|
||||
async def create_schema_async():
|
||||
if not DATABASE_URL:
|
||||
return
|
||||
engine = create_async_engine(DATABASE_URL, echo=False)
|
||||
async with engine.begin() as conn:
|
||||
# Use double quotes for column names and renamed start/end to startTime/endTime
|
||||
await conn.execute(text('''
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
"id" TEXT PRIMARY KEY,
|
||||
"identifier" TEXT NOT NULL UNIQUE,
|
||||
"meta" TEXT NOT NULL DEFAULT '{}',
|
||||
"createdAt" TEXT
|
||||
);
|
||||
'''))
|
||||
await conn.execute(text('''
|
||||
CREATE TABLE IF NOT EXISTS threads (
|
||||
"id" TEXT PRIMARY KEY,
|
||||
"createdAt" TEXT,
|
||||
"name" TEXT,
|
||||
"userId" TEXT,
|
||||
"userIdentifier" TEXT,
|
||||
"tags" TEXT DEFAULT '[]',
|
||||
"meta" TEXT NOT NULL DEFAULT '{}',
|
||||
FOREIGN KEY ("userId") REFERENCES users("id") ON DELETE CASCADE
|
||||
);
|
||||
'''))
|
||||
await conn.execute(text('''
|
||||
CREATE TABLE IF NOT EXISTS steps (
|
||||
"id" TEXT PRIMARY KEY,
|
||||
"name" TEXT NOT NULL,
|
||||
"type" TEXT NOT NULL,
|
||||
"threadId" TEXT NOT NULL,
|
||||
"parentId" TEXT,
|
||||
"disableFeedback" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
"streaming" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
"waitForAnswer" BOOLEAN DEFAULT FALSE,
|
||||
"isError" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
"meta" TEXT DEFAULT '{}',
|
||||
"tags" TEXT DEFAULT '[]',
|
||||
"input" TEXT,
|
||||
"output" TEXT,
|
||||
"createdAt" TEXT,
|
||||
"startTime" TEXT,
|
||||
"endTime" TEXT,
|
||||
"generation" TEXT,
|
||||
"showInput" TEXT,
|
||||
"language" TEXT,
|
||||
"indent" INT,
|
||||
FOREIGN KEY ("threadId") REFERENCES threads("id") ON DELETE CASCADE
|
||||
);
|
||||
'''))
|
||||
await conn.execute(text('''
|
||||
CREATE TABLE IF NOT EXISTS elements (
|
||||
"id" TEXT PRIMARY KEY,
|
||||
"threadId" TEXT,
|
||||
"type" TEXT,
|
||||
"url" TEXT,
|
||||
"chainlitKey" TEXT,
|
||||
"name" TEXT NOT NULL,
|
||||
"display" TEXT,
|
||||
"objectKey" TEXT,
|
||||
"size" TEXT,
|
||||
"page" INT,
|
||||
"language" TEXT,
|
||||
"forId" TEXT,
|
||||
"mime" TEXT,
|
||||
FOREIGN KEY ("threadId") REFERENCES threads("id") ON DELETE CASCADE
|
||||
);
|
||||
'''))
|
||||
await conn.execute(text('''
|
||||
CREATE TABLE IF NOT EXISTS feedbacks (
|
||||
"id" TEXT PRIMARY KEY,
|
||||
"forId" TEXT NOT NULL,
|
||||
"value" INT NOT NULL,
|
||||
"threadId" TEXT,
|
||||
"comment" TEXT
|
||||
);
|
||||
'''))
|
||||
await conn.execute(text('''
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
"id" SERIAL PRIMARY KEY,
|
||||
"key" TEXT UNIQUE,
|
||||
"value" TEXT
|
||||
);
|
||||
'''))
|
||||
await engine.dispose()
|
||||
|
||||
# Initialize the database
|
||||
async def initialize_db():
|
||||
await create_tables(cl_data._data_layer.engine)
|
||||
def create_schema_sqlite(db_path: str):
|
||||
os.makedirs(os.path.dirname(db_path), exist_ok=True)
|
||||
conn = sqlite3.connect(db_path)
|
||||
cursor = conn.cursor()
|
||||
# Renamed start to startTime, end to endTime
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
"id" TEXT PRIMARY KEY,
|
||||
"identifier" TEXT NOT NULL UNIQUE,
|
||||
"meta" TEXT NOT NULL DEFAULT '{}',
|
||||
"createdAt" TEXT
|
||||
)
|
||||
''')
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS threads (
|
||||
"id" TEXT PRIMARY KEY,
|
||||
"createdAt" TEXT,
|
||||
"name" TEXT,
|
||||
"userId" TEXT,
|
||||
"userIdentifier" TEXT,
|
||||
"tags" TEXT DEFAULT '[]',
|
||||
"meta" TEXT NOT NULL DEFAULT '{}',
|
||||
FOREIGN KEY ("userId") REFERENCES users("id") ON DELETE CASCADE
|
||||
)
|
||||
''')
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS steps (
|
||||
"id" TEXT PRIMARY KEY,
|
||||
"name" TEXT NOT NULL,
|
||||
"type" TEXT NOT NULL,
|
||||
"threadId" TEXT NOT NULL,
|
||||
"parentId" TEXT,
|
||||
"disableFeedback" BOOLEAN NOT NULL DEFAULT 0,
|
||||
"streaming" BOOLEAN NOT NULL DEFAULT 0,
|
||||
"waitForAnswer" BOOLEAN DEFAULT 0,
|
||||
"isError" BOOLEAN NOT NULL DEFAULT 0,
|
||||
"meta" TEXT DEFAULT '{}',
|
||||
"tags" TEXT DEFAULT '[]',
|
||||
"input" TEXT,
|
||||
"output" TEXT,
|
||||
"createdAt" TEXT,
|
||||
"startTime" TEXT,
|
||||
"endTime" TEXT,
|
||||
"generation" TEXT,
|
||||
"showInput" TEXT,
|
||||
"language" TEXT,
|
||||
"indent" INT,
|
||||
FOREIGN KEY ("threadId") REFERENCES threads ("id") ON DELETE CASCADE
|
||||
)
|
||||
''')
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS elements (
|
||||
"id" TEXT PRIMARY KEY,
|
||||
"threadId" TEXT,
|
||||
"type" TEXT,
|
||||
"url" TEXT,
|
||||
"chainlitKey" TEXT,
|
||||
"name" TEXT NOT NULL,
|
||||
"display" TEXT,
|
||||
"objectKey" TEXT,
|
||||
"size" TEXT,
|
||||
"page" INT,
|
||||
"language" TEXT,
|
||||
"forId" TEXT,
|
||||
"mime" TEXT,
|
||||
FOREIGN KEY ("threadId") REFERENCES threads ("id") ON DELETE CASCADE
|
||||
)
|
||||
''')
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS feedbacks (
|
||||
"id" TEXT PRIMARY KEY,
|
||||
"forId" TEXT NOT NULL,
|
||||
"value" INT NOT NULL,
|
||||
"threadId" TEXT,
|
||||
"comment" TEXT
|
||||
)
|
||||
''')
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
"key" TEXT UNIQUE,
|
||||
"value" TEXT
|
||||
)
|
||||
''')
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
# Get database connection string from environment variable or use SQLite as default
|
||||
DB_URL = os.getenv("DATABASE_URL", f"sqlite+aiosqlite:///{DB_PATH}")
|
||||
if DB_URL.startswith('postgresql'):
|
||||
# Convert postgresql:// to postgresql+psycopg:// if needed
|
||||
DB_URL = DB_URL.replace('postgresql://', 'postgresql+psycopg://')
|
||||
if DATABASE_URL:
|
||||
asyncio.run(create_schema_async())
|
||||
conninfo = DATABASE_URL
|
||||
else:
|
||||
DB_PATH = os.path.expanduser("~/.praison/database.sqlite")
|
||||
create_schema_sqlite(DB_PATH)
|
||||
conninfo = f"sqlite+aiosqlite:///{DB_PATH}"
|
||||
|
||||
# Initialize SQLAlchemy data layer
|
||||
cl_data._data_layer = SQLAlchemyDataLayer(
|
||||
conninfo=DB_URL,
|
||||
ssl_require=bool(os.getenv("DATABASE_SSL", False))
|
||||
)
|
||||
def save_setting(key: str, value: str):
|
||||
if DATABASE_URL:
|
||||
async def save_setting_async():
|
||||
engine = create_async_engine(DATABASE_URL, echo=False)
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text("""
|
||||
INSERT INTO settings ("key", "value") VALUES (:key, :value)
|
||||
ON CONFLICT ("key") DO UPDATE SET "value" = EXCLUDED."value"
|
||||
"""), {"key": key, "value": value})
|
||||
await engine.dispose()
|
||||
asyncio.run(save_setting_async())
|
||||
else:
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(
|
||||
"""
|
||||
INSERT OR REPLACE INTO settings (id, "key", "value")
|
||||
VALUES ((SELECT id FROM settings WHERE "key" = ?), ?, ?)
|
||||
""",
|
||||
(key, key, value),
|
||||
)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
# Create tables if using PostgreSQL
|
||||
if DB_URL.startswith('postgresql'):
|
||||
asyncio.run(initialize_db())
|
||||
def load_setting(key: str) -> str:
|
||||
if DATABASE_URL:
|
||||
async def load_setting_async():
|
||||
engine = create_async_engine(DATABASE_URL, echo=False)
|
||||
async with engine.connect() as conn:
|
||||
result = await conn.execute(text('SELECT "value" FROM settings WHERE "key" = :key'), {"key": key})
|
||||
row = result.fetchone()
|
||||
await engine.dispose()
|
||||
return row[0] if row else None
|
||||
return asyncio.run(load_setting_async())
|
||||
else:
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('SELECT "value" FROM settings WHERE "key" = ?', (key,))
|
||||
result = cursor.fetchone()
|
||||
conn.close()
|
||||
return result[0] if result else None
|
||||
|
||||
cl_data._data_layer = SQLAlchemyDataLayer(conninfo=conninfo)
|
||||
|
||||
# Set Tavily API key
|
||||
tavily_api_key = os.getenv("TAVILY_API_KEY")
|
||||
tavily_client = TavilyClient(api_key=tavily_api_key) if tavily_api_key else None
|
||||
|
||||
# Modify the tavily_web_search function to be async
|
||||
async def tavily_web_search(query):
|
||||
if not tavily_client:
|
||||
return json.dumps({
|
||||
"query": query,
|
||||
"error": "Tavily API key is not set. Web search is unavailable."
|
||||
})
|
||||
|
||||
|
||||
response = tavily_client.search(query)
|
||||
logger.debug(f"Tavily search response: {response}")
|
||||
|
||||
# Create an instance of AsyncWebCrawler
|
||||
async with AsyncWebCrawler() as crawler:
|
||||
# Prepare the results
|
||||
results = []
|
||||
for result in response.get('results', []):
|
||||
url = result.get('url')
|
||||
if url:
|
||||
try:
|
||||
# Run the crawler asynchronously on each URL
|
||||
crawl_result = await crawler.arun(url=url)
|
||||
results.append({
|
||||
"content": result.get('content'),
|
||||
@@ -307,7 +308,6 @@ async def tavily_web_search(query):
|
||||
"results": results
|
||||
})
|
||||
|
||||
# Update the tools definition
|
||||
tools = [{
|
||||
"type": "function",
|
||||
"function": {
|
||||
@@ -323,60 +323,10 @@ tools = [{
|
||||
}
|
||||
}] if tavily_api_key else []
|
||||
|
||||
async def save_setting(key: str, value: str):
|
||||
"""Saves a setting to the database.
|
||||
|
||||
Args:
|
||||
key: The setting key.
|
||||
value: The setting value.
|
||||
"""
|
||||
try:
|
||||
async with cl_data._data_layer.engine.begin() as conn:
|
||||
await conn.execute(
|
||||
text("""
|
||||
INSERT INTO settings (key, value)
|
||||
VALUES (:key, :value)
|
||||
ON CONFLICT (key) DO UPDATE SET value = :value
|
||||
"""),
|
||||
{"key": key, "value": value}
|
||||
)
|
||||
logger.debug(f"Saved setting {key}={value}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error saving setting {key}: {str(e)}")
|
||||
raise DatabaseError(f"Failed to save setting: {str(e)}")
|
||||
|
||||
async def load_setting(key: str) -> str:
|
||||
"""Loads a setting from the database.
|
||||
|
||||
Args:
|
||||
key: The setting key.
|
||||
|
||||
Returns:
|
||||
The setting value, or None if the key is not found.
|
||||
"""
|
||||
try:
|
||||
async with cl_data._data_layer.engine.connect() as conn:
|
||||
result = await conn.execute(
|
||||
text("SELECT value FROM settings WHERE key = :key"),
|
||||
{"key": key}
|
||||
)
|
||||
row = result.fetchone()
|
||||
return row[0] if row else None
|
||||
except Exception as e:
|
||||
logger.error(f"Error loading setting {key}: {str(e)}")
|
||||
return None
|
||||
|
||||
@cl.on_chat_start
|
||||
async def start():
|
||||
await initialize_db()
|
||||
model_name = await load_setting("model_name")
|
||||
|
||||
if model_name:
|
||||
cl.user_session.set("model_name", model_name)
|
||||
else:
|
||||
# If no setting found, use default or environment variable
|
||||
model_name = os.getenv("MODEL_NAME", "gpt-4o-mini")
|
||||
cl.user_session.set("model_name", model_name)
|
||||
model_name = load_setting("model_name") or os.getenv("MODEL_NAME", "gpt-4o-mini")
|
||||
cl.user_session.set("model_name", model_name)
|
||||
logger.debug(f"Model name: {model_name}")
|
||||
settings = cl.ChatSettings(
|
||||
[
|
||||
@@ -397,47 +347,43 @@ async def setup_agent(settings):
|
||||
cl.user_session.set("settings", settings)
|
||||
model_name = settings["model_name"]
|
||||
cl.user_session.set("model_name", model_name)
|
||||
|
||||
# Save in settings table
|
||||
await save_setting("model_name", model_name)
|
||||
|
||||
# Save in thread metadata
|
||||
|
||||
save_setting("model_name", model_name)
|
||||
|
||||
thread_id = cl.user_session.get("thread_id")
|
||||
if thread_id:
|
||||
thread = await cl_data.get_thread(thread_id)
|
||||
if thread:
|
||||
metadata = thread.get("metadata", {})
|
||||
if isinstance(metadata, str):
|
||||
try:
|
||||
metadata = json.loads(metadata)
|
||||
except:
|
||||
metadata = {}
|
||||
metadata["model_name"] = model_name
|
||||
|
||||
# Always store metadata as a JSON string
|
||||
await cl_data.update_thread(thread_id, metadata=json.dumps(metadata))
|
||||
|
||||
# Update the user session with the new metadata
|
||||
await cl_data.update_thread(thread_id, metadata=metadata)
|
||||
cl.user_session.set("metadata", metadata)
|
||||
|
||||
@cl.on_message
|
||||
async def main(message: cl.Message):
|
||||
model_name = await load_setting("model_name") or os.getenv("MODEL_NAME") or "gpt-4o-mini"
|
||||
model_name = load_setting("model_name") or os.getenv("MODEL_NAME", "gpt-4o-mini")
|
||||
message_history = cl.user_session.get("message_history", [])
|
||||
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
# Check if an image was uploaded with this message
|
||||
|
||||
image = None
|
||||
if message.elements and isinstance(message.elements[0], cl.Image):
|
||||
image_element = message.elements[0]
|
||||
try:
|
||||
# Open the image and keep it in memory
|
||||
image = Image.open(image_element.path)
|
||||
image.load() # This ensures the file is fully loaded into memory
|
||||
image.load()
|
||||
cl.user_session.set("image", image)
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing image: {str(e)}")
|
||||
await cl.Message(content="There was an error processing the uploaded image. Please try again.").send()
|
||||
await cl.Message(content="Error processing the image. Please try again.").send()
|
||||
return
|
||||
|
||||
# Prepare user message
|
||||
user_message = f"""
|
||||
Answer the question and use tools if needed:\n
|
||||
Answer the question and use tools if needed:
|
||||
|
||||
Current Date and Time: {now}
|
||||
|
||||
@@ -448,23 +394,19 @@ User Question: {message.content}
|
||||
user_message = f"Image uploaded. {user_message}"
|
||||
|
||||
message_history.append({"role": "user", "content": user_message})
|
||||
|
||||
msg = cl.Message(content="")
|
||||
await msg.send()
|
||||
|
||||
# Prepare the completion parameters
|
||||
completion_params = {
|
||||
"model": model_name,
|
||||
"messages": message_history,
|
||||
"stream": True,
|
||||
}
|
||||
|
||||
# If an image is uploaded, include it in the message
|
||||
if image:
|
||||
buffered = io.BytesIO()
|
||||
image.save(buffered, format="PNG")
|
||||
img_str = base64.b64encode(buffered.getvalue()).decode()
|
||||
|
||||
completion_params["messages"][-1] = {
|
||||
"role": "user",
|
||||
"content": [
|
||||
@@ -472,7 +414,7 @@ User Question: {message.content}
|
||||
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{img_str}"}}
|
||||
]
|
||||
}
|
||||
# Only add tools and tool_choice if Tavily API key is available
|
||||
|
||||
if tavily_api_key:
|
||||
completion_params["tools"] = tools
|
||||
completion_params["tool_choice"] = "auto"
|
||||
@@ -486,12 +428,12 @@ User Question: {message.content}
|
||||
async for part in response:
|
||||
if 'choices' in part and len(part['choices']) > 0:
|
||||
delta = part['choices'][0].get('delta', {})
|
||||
|
||||
|
||||
if 'content' in delta and delta['content'] is not None:
|
||||
token = delta['content']
|
||||
await msg.stream_token(token)
|
||||
full_response += token
|
||||
|
||||
|
||||
if tavily_api_key and 'tool_calls' in delta and delta['tool_calls'] is not None:
|
||||
for tool_call in delta['tool_calls']:
|
||||
if current_tool_call is None or tool_call.index != current_tool_call['index']:
|
||||
@@ -522,7 +464,6 @@ User Question: {message.content}
|
||||
cl.user_session.set("message_history", message_history)
|
||||
await msg.update()
|
||||
|
||||
# Handle tool calls if any
|
||||
if tavily_api_key and tool_calls:
|
||||
available_functions = {
|
||||
"tavily_web_search": tavily_web_search,
|
||||
@@ -540,7 +481,6 @@ User Question: {message.content}
|
||||
if function_args:
|
||||
try:
|
||||
function_args = json.loads(function_args)
|
||||
# Call the function asynchronously
|
||||
function_response = await function_to_call(
|
||||
query=function_args.get("query"),
|
||||
)
|
||||
@@ -561,7 +501,6 @@ User Question: {message.content}
|
||||
)
|
||||
logger.debug(f"Second LLM response: {second_response}")
|
||||
|
||||
# Handle the streaming response
|
||||
full_response = ""
|
||||
async for part in second_response:
|
||||
if 'choices' in part and len(part['choices']) > 0:
|
||||
@@ -571,20 +510,18 @@ User Question: {message.content}
|
||||
await msg.stream_token(token)
|
||||
full_response += token
|
||||
|
||||
# Update the message content
|
||||
msg.content = full_response
|
||||
await msg.update()
|
||||
else:
|
||||
# If no tool calls, the full_response is already set
|
||||
msg.content = full_response
|
||||
await msg.update()
|
||||
|
||||
username = os.getenv("CHAINLIT_USERNAME", "admin") # Default to "admin" if not found
|
||||
password = os.getenv("CHAINLIT_PASSWORD", "admin") # Default to "admin" if not found
|
||||
username = os.getenv("CHAINLIT_USERNAME", "admin")
|
||||
password = os.getenv("CHAINLIT_PASSWORD", "admin")
|
||||
|
||||
@cl.password_auth_callback
|
||||
def auth_callback(username: str, password: str):
|
||||
if (username, password) == (username, password):
|
||||
def auth_callback(u: str, p: str):
|
||||
if (u, p) == (username, password):
|
||||
return cl.User(
|
||||
identifier=username, metadata={"role": "ADMIN", "provider": "credentials"}
|
||||
)
|
||||
@@ -599,7 +536,7 @@ async def send_count():
|
||||
@cl.on_chat_resume
|
||||
async def on_chat_resume(thread: ThreadDict):
|
||||
logger.info(f"Resuming chat: {thread['id']}")
|
||||
model_name = await load_setting("model_name") or os.getenv("MODEL_NAME") or "gpt-4o-mini"
|
||||
model_name = load_setting("model_name") or os.getenv("MODEL_NAME", "gpt-4o-mini")
|
||||
logger.debug(f"Model name: {model_name}")
|
||||
settings = cl.ChatSettings(
|
||||
[
|
||||
@@ -613,42 +550,35 @@ async def on_chat_resume(thread: ThreadDict):
|
||||
)
|
||||
await settings.send()
|
||||
thread_id = thread["id"]
|
||||
cl.user_session.set("thread_id", thread["id"])
|
||||
|
||||
# Ensure metadata is a dictionary
|
||||
cl.user_session.set("thread_id", thread_id)
|
||||
|
||||
metadata = thread.get("metadata", {})
|
||||
if isinstance(metadata, str):
|
||||
try:
|
||||
metadata = json.loads(metadata)
|
||||
except json.JSONDecodeError:
|
||||
metadata = {}
|
||||
|
||||
cl.user_session.set("metadata", metadata)
|
||||
|
||||
|
||||
message_history = cl.user_session.get("message_history", [])
|
||||
steps = thread["steps"]
|
||||
|
||||
for message in steps:
|
||||
msg_type = message.get("type")
|
||||
for m in steps:
|
||||
msg_type = m.get("type")
|
||||
if msg_type == "user_message":
|
||||
message_history.append({"role": "user", "content": message.get("output", "")})
|
||||
message_history.append({"role": "user", "content": m.get("output", "")})
|
||||
elif msg_type == "assistant_message":
|
||||
message_history.append({"role": "assistant", "content": message.get("output", "")})
|
||||
message_history.append({"role": "assistant", "content": m.get("output", "")})
|
||||
elif msg_type == "run":
|
||||
# Handle 'run' type messages
|
||||
if message.get("isError"):
|
||||
message_history.append({"role": "system", "content": f"Error: {message.get('output', '')}"})
|
||||
else:
|
||||
# You might want to handle non-error 'run' messages differently
|
||||
pass
|
||||
if m.get("isError"):
|
||||
message_history.append({"role": "system", "content": f"Error: {m.get('output', '')}"})
|
||||
else:
|
||||
logger.warning(f"Message without recognized type: {message}")
|
||||
logger.warning(f"Message without recognized type: {m}")
|
||||
|
||||
cl.user_session.set("message_history", message_history)
|
||||
|
||||
# Check if there's an image in the thread metadata
|
||||
image_data = metadata.get("image")
|
||||
if image_data:
|
||||
image = Image.open(io.BytesIO(base64.b64decode(image_data)))
|
||||
cl.user_session.set("image", image)
|
||||
await cl.Message(content="Previous image loaded. You can continue asking questions about it or upload a new image.").send()
|
||||
await cl.Message(content="Previous image loaded.").send()
|
||||
+164
-168
@@ -4,6 +4,7 @@ import uuid
|
||||
from dataclasses import asdict
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
|
||||
import os
|
||||
|
||||
import aiofiles
|
||||
import aiohttp
|
||||
@@ -12,7 +13,6 @@ from chainlit.data.base import BaseDataLayer, BaseStorageClient
|
||||
from chainlit.data.utils import queue_until_user_message
|
||||
from chainlit.element import ElementDict
|
||||
from chainlit.logger import logger
|
||||
from chainlit.message import Message
|
||||
from chainlit.step import StepDict
|
||||
from chainlit.types import (
|
||||
Feedback,
|
||||
@@ -30,9 +30,10 @@ from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, create_async_engin
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from chainlit.element import Element, ElementDict
|
||||
from chainlit.element import Element
|
||||
from chainlit.step import StepDict
|
||||
|
||||
DATABASE_URL = os.getenv("DATABASE_URL")
|
||||
|
||||
class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
def __init__(
|
||||
@@ -48,7 +49,6 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
self.show_logger = show_logger
|
||||
ssl_args = {}
|
||||
if ssl_require:
|
||||
# Create an SSL context to require an SSL connection
|
||||
ssl_context = ssl.create_default_context()
|
||||
ssl_context.check_hostname = False
|
||||
ssl_context.verify_mode = ssl.CERT_NONE
|
||||
@@ -58,7 +58,7 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
)
|
||||
self.async_session = sessionmaker(
|
||||
bind=self.engine, expire_on_commit=False, class_=AsyncSession
|
||||
) # type: ignore
|
||||
)
|
||||
if storage_provider:
|
||||
self.storage_provider: Optional[BaseStorageClient] = storage_provider
|
||||
if self.show_logger:
|
||||
@@ -104,7 +104,6 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
return datetime.now().isoformat() + "Z"
|
||||
|
||||
def clean_result(self, obj):
|
||||
"""Recursively change UUID -> str and serialize dictionaries"""
|
||||
if isinstance(obj, dict):
|
||||
return {k: self.clean_result(v) for k, v in obj.items()}
|
||||
elif isinstance(obj, list):
|
||||
@@ -117,52 +116,42 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
async def get_user(self, identifier: str) -> Optional[PersistedUser]:
|
||||
if self.show_logger:
|
||||
logger.info(f"SQLAlchemy: get_user, identifier={identifier}")
|
||||
query = "SELECT * FROM users WHERE identifier = :identifier"
|
||||
query = 'SELECT * FROM users WHERE "identifier" = :identifier'
|
||||
parameters = {"identifier": identifier}
|
||||
result = await self.execute_sql(query=query, parameters=parameters)
|
||||
if result and isinstance(result, list):
|
||||
user_data = result[0]
|
||||
|
||||
# SQLite returns JSON as string, we most convert it. (#1137)
|
||||
metadata = user_data.get("metadata", {})
|
||||
if isinstance(metadata, str):
|
||||
metadata = json.loads(metadata)
|
||||
|
||||
assert isinstance(metadata, dict)
|
||||
assert isinstance(user_data["id"], str)
|
||||
assert isinstance(user_data["identifier"], str)
|
||||
assert isinstance(user_data["createdAt"], str)
|
||||
meta = user_data.get("meta", "{}")
|
||||
if isinstance(meta, str):
|
||||
meta = json.loads(meta)
|
||||
|
||||
return PersistedUser(
|
||||
id=user_data["id"],
|
||||
identifier=user_data["identifier"],
|
||||
createdAt=user_data["createdAt"],
|
||||
metadata=metadata,
|
||||
metadata=meta,
|
||||
)
|
||||
return None
|
||||
|
||||
async def _get_user_identifer_by_id(self, user_id: str) -> str:
|
||||
if self.show_logger:
|
||||
logger.info(f"SQLAlchemy: _get_user_identifer_by_id, user_id={user_id}")
|
||||
query = "SELECT identifier FROM users WHERE id = :user_id"
|
||||
query = 'SELECT "identifier" FROM users WHERE "id" = :user_id'
|
||||
parameters = {"user_id": user_id}
|
||||
result = await self.execute_sql(query=query, parameters=parameters)
|
||||
|
||||
assert result
|
||||
assert isinstance(result, list)
|
||||
|
||||
return result[0]["identifier"]
|
||||
|
||||
async def _get_user_id_by_thread(self, thread_id: str) -> Optional[str]:
|
||||
if self.show_logger:
|
||||
logger.info(f"SQLAlchemy: _get_user_id_by_thread, thread_id={thread_id}")
|
||||
query = "SELECT userId FROM threads WHERE id = :thread_id"
|
||||
query = 'SELECT "userId" FROM threads WHERE "id" = :thread_id'
|
||||
parameters = {"thread_id": thread_id}
|
||||
result = await self.execute_sql(query=query, parameters=parameters)
|
||||
if result:
|
||||
assert isinstance(result, list)
|
||||
if result and isinstance(result, list):
|
||||
return result[0]["userId"]
|
||||
|
||||
return None
|
||||
|
||||
async def create_user(self, user: User) -> Optional[PersistedUser]:
|
||||
@@ -171,29 +160,23 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
existing_user: Optional["PersistedUser"] = await self.get_user(user.identifier)
|
||||
user_dict: Dict[str, Any] = {
|
||||
"identifier": str(user.identifier),
|
||||
"metadata": json.dumps(user.metadata) or {},
|
||||
"meta": json.dumps(user.metadata) or "{}",
|
||||
}
|
||||
if not existing_user: # create the user
|
||||
if self.show_logger:
|
||||
logger.info("SQLAlchemy: create_user, creating the user")
|
||||
if not existing_user:
|
||||
user_dict["id"] = str(uuid.uuid4())
|
||||
user_dict["createdAt"] = await self.get_current_timestamp()
|
||||
query = """INSERT INTO users ("id", "identifier", "createdAt", "metadata") VALUES (:id, :identifier, :createdAt, :metadata)"""
|
||||
query = 'INSERT INTO users ("id", "identifier", "createdAt", "meta") VALUES (:id, :identifier, :createdAt, :meta)'
|
||||
await self.execute_sql(query=query, parameters=user_dict)
|
||||
else:
|
||||
query = 'UPDATE users SET "meta" = :meta WHERE "identifier" = :identifier'
|
||||
await self.execute_sql(query=query, parameters=user_dict)
|
||||
else: # update the user
|
||||
if self.show_logger:
|
||||
logger.info("SQLAlchemy: update user metadata")
|
||||
query = """UPDATE users SET "metadata" = :metadata WHERE "identifier" = :identifier"""
|
||||
await self.execute_sql(
|
||||
query=query, parameters=user_dict
|
||||
) # We want to update the metadata
|
||||
return await self.get_user(user.identifier)
|
||||
|
||||
###### Threads ######
|
||||
async def get_thread_author(self, thread_id: str) -> str:
|
||||
if self.show_logger:
|
||||
logger.info(f"SQLAlchemy: get_thread_author, thread_id={thread_id}")
|
||||
query = """SELECT "userIdentifier" FROM threads WHERE "id" = :id"""
|
||||
query = 'SELECT "userIdentifier" FROM threads WHERE "id" = :id'
|
||||
parameters = {"id": thread_id}
|
||||
result = await self.execute_sql(query=query, parameters=parameters)
|
||||
if isinstance(result, list) and result:
|
||||
@@ -205,10 +188,9 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
async def get_thread(self, thread_id: str) -> Optional[ThreadDict]:
|
||||
if self.show_logger:
|
||||
logger.info(f"SQLAlchemy: get_thread, thread_id={thread_id}")
|
||||
user_threads: Optional[List[ThreadDict]] = (
|
||||
await self.get_all_user_threads(thread_id=thread_id) or []
|
||||
user_threads: Optional[List[ThreadDict]] = await self.get_all_user_threads(
|
||||
thread_id=thread_id
|
||||
)
|
||||
|
||||
if user_threads:
|
||||
return user_threads[0]
|
||||
else:
|
||||
@@ -241,14 +223,12 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
),
|
||||
"userId": user_id,
|
||||
"userIdentifier": user_identifier,
|
||||
"tags": tags,
|
||||
"metadata": json.dumps(metadata) if metadata else None,
|
||||
"tags": json.dumps(tags) if tags else None,
|
||||
"meta": json.dumps(metadata) if metadata else None,
|
||||
}
|
||||
parameters = {
|
||||
key: value for key, value in data.items() if value is not None
|
||||
} # Remove keys with None values
|
||||
parameters = {key: value for key, value in data.items() if value is not None}
|
||||
columns = ", ".join(f'"{key}"' for key in parameters.keys())
|
||||
values = ", ".join(f":{key}" for key in parameters.keys())
|
||||
values = ", ".join(f':{key}' for key in parameters.keys())
|
||||
updates = ", ".join(
|
||||
f'"{key}" = EXCLUDED."{key}"' for key in parameters.keys() if key != "id"
|
||||
)
|
||||
@@ -263,11 +243,10 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
async def delete_thread(self, thread_id: str):
|
||||
if self.show_logger:
|
||||
logger.info(f"SQLAlchemy: delete_thread, thread_id={thread_id}")
|
||||
# Delete feedbacks/elements/steps/thread
|
||||
feedbacks_query = """DELETE FROM feedbacks WHERE "forId" IN (SELECT "id" FROM steps WHERE "threadId" = :id)"""
|
||||
elements_query = """DELETE FROM elements WHERE "threadId" = :id"""
|
||||
steps_query = """DELETE FROM steps WHERE "threadId" = :id"""
|
||||
thread_query = """DELETE FROM threads WHERE "id" = :id"""
|
||||
feedbacks_query = 'DELETE FROM feedbacks WHERE "forId" IN (SELECT "id" FROM steps WHERE "threadId" = :id)'
|
||||
elements_query = 'DELETE FROM elements WHERE "threadId" = :id'
|
||||
steps_query = 'DELETE FROM steps WHERE "threadId" = :id'
|
||||
thread_query = 'DELETE FROM threads WHERE "id" = :id'
|
||||
parameters = {"id": thread_id}
|
||||
await self.execute_sql(query=feedbacks_query, parameters=parameters)
|
||||
await self.execute_sql(query=elements_query, parameters=parameters)
|
||||
@@ -299,10 +278,10 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
keyword_match = any(
|
||||
search_keyword in step["output"].lower()
|
||||
for step in thread["steps"]
|
||||
if "output" in step
|
||||
if "output" in step and isinstance(step["output"], str)
|
||||
)
|
||||
if feedback_value is not None:
|
||||
feedback_match = False # Assume no match until found
|
||||
feedback_match = False
|
||||
for step in thread["steps"]:
|
||||
feedback = step.get("feedback")
|
||||
if feedback and feedback.get("value") == feedback_value:
|
||||
@@ -313,10 +292,8 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
|
||||
start = 0
|
||||
if pagination.cursor:
|
||||
for i, thread in enumerate(filtered_threads):
|
||||
if (
|
||||
thread["id"] == pagination.cursor
|
||||
): # Find the start index using pagination.cursor
|
||||
for i, thr in enumerate(filtered_threads):
|
||||
if thr["id"] == pagination.cursor:
|
||||
start = i + 1
|
||||
break
|
||||
end = start + pagination.first
|
||||
@@ -337,7 +314,7 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
|
||||
###### Steps ######
|
||||
@queue_until_user_message()
|
||||
async def create_step(self, step_dict: dict):
|
||||
async def create_step(self, step_dict: "StepDict"):
|
||||
if self.show_logger:
|
||||
logger.info(f"SQLAlchemy: create_step, step_id={step_dict.get('id')}")
|
||||
|
||||
@@ -346,28 +323,52 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
if "showInput" in step_dict
|
||||
else None
|
||||
)
|
||||
|
||||
# Use updated column names: startTime, endTime
|
||||
# Make sure tags is always a JSON array
|
||||
tags = step_dict.get("tags")
|
||||
if not tags:
|
||||
tags = []
|
||||
meta = json.dumps(step_dict.get("metadata", {}))
|
||||
generation = json.dumps(step_dict.get("generation", {}))
|
||||
parameters = {
|
||||
key: value
|
||||
for key, value in step_dict.items()
|
||||
if value is not None and not (isinstance(value, dict) and not value)
|
||||
"id": step_dict.get("id"),
|
||||
"name": step_dict.get("name"),
|
||||
"type": step_dict.get("type"),
|
||||
"threadId": step_dict.get("threadId"),
|
||||
"parentId": step_dict.get("parentId"),
|
||||
"disableFeedback": step_dict.get("disableFeedback", False),
|
||||
"streaming": step_dict.get("streaming", False),
|
||||
"waitForAnswer": step_dict.get("waitForAnswer", False),
|
||||
"isError": step_dict.get("isError", False),
|
||||
"meta": meta,
|
||||
"tags": json.dumps(tags),
|
||||
"input": step_dict.get("input"),
|
||||
"output": step_dict.get("output"),
|
||||
"createdAt": step_dict.get("createdAt"),
|
||||
"startTime": step_dict.get("start"),
|
||||
"endTime": step_dict.get("end"),
|
||||
"generation": generation,
|
||||
"showInput": step_dict.get("showInput"),
|
||||
"language": step_dict.get("language"),
|
||||
"indent": step_dict.get("indent"),
|
||||
}
|
||||
parameters["metadata"] = json.dumps(step_dict.get("metadata", {}))
|
||||
parameters["generation"] = json.dumps(step_dict.get("generation", {}))
|
||||
parameters = {k: v for k, v in parameters.items() if v is not None}
|
||||
columns = ", ".join(f'"{key}"' for key in parameters.keys())
|
||||
values = ", ".join(f":{key}" for key in parameters.keys())
|
||||
values = ", ".join(f':{key}' for key in parameters.keys())
|
||||
updates = ", ".join(
|
||||
f'"{key}" = :{key}' for key in parameters.keys() if key != "id"
|
||||
)
|
||||
query = f"""
|
||||
INSERT INTO steps ({columns})
|
||||
VALUES ({values})
|
||||
ON CONFLICT (id) DO UPDATE
|
||||
ON CONFLICT ("id") DO UPDATE
|
||||
SET {updates};
|
||||
"""
|
||||
await self.execute_sql(query=query, parameters=parameters)
|
||||
|
||||
@queue_until_user_message()
|
||||
async def update_step(self, step_dict: dict):
|
||||
async def update_step(self, step_dict: "StepDict"):
|
||||
if self.show_logger:
|
||||
logger.info(f"SQLAlchemy: update_step, step_id={step_dict.get('id')}")
|
||||
await self.create_step(step_dict)
|
||||
@@ -376,10 +377,9 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
async def delete_step(self, step_id: str):
|
||||
if self.show_logger:
|
||||
logger.info(f"SQLAlchemy: delete_step, step_id={step_id}")
|
||||
# Delete feedbacks/elements/steps
|
||||
feedbacks_query = """DELETE FROM feedbacks WHERE "forId" = :id"""
|
||||
elements_query = """DELETE FROM elements WHERE "forId" = :id"""
|
||||
steps_query = """DELETE FROM steps WHERE "id" = :id"""
|
||||
feedbacks_query = 'DELETE FROM feedbacks WHERE "forId" = :id'
|
||||
elements_query = 'DELETE FROM elements WHERE "forId" = :id'
|
||||
steps_query = 'DELETE FROM steps WHERE "id" = :id'
|
||||
parameters = {"id": step_id}
|
||||
await self.execute_sql(query=feedbacks_query, parameters=parameters)
|
||||
await self.execute_sql(query=elements_query, parameters=parameters)
|
||||
@@ -391,19 +391,16 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
logger.info(f"SQLAlchemy: upsert_feedback, feedback_id={feedback.id}")
|
||||
feedback.id = feedback.id or str(uuid.uuid4())
|
||||
feedback_dict = asdict(feedback)
|
||||
parameters = {
|
||||
key: value for key, value in feedback_dict.items() if value is not None
|
||||
}
|
||||
|
||||
parameters = {k: v for k, v in feedback_dict.items() if v is not None}
|
||||
columns = ", ".join(f'"{key}"' for key in parameters.keys())
|
||||
values = ", ".join(f":{key}" for key in parameters.keys())
|
||||
values = ", ".join(f':{key}' for key in parameters.keys())
|
||||
updates = ", ".join(
|
||||
f'"{key}" = :{key}' for key in parameters.keys() if key != "id"
|
||||
)
|
||||
query = f"""
|
||||
INSERT INTO feedbacks ({columns})
|
||||
VALUES ({values})
|
||||
ON CONFLICT (id) DO UPDATE
|
||||
ON CONFLICT ("id") DO UPDATE
|
||||
SET {updates};
|
||||
"""
|
||||
await self.execute_sql(query=query, parameters=parameters)
|
||||
@@ -412,7 +409,7 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
async def delete_feedback(self, feedback_id: str) -> bool:
|
||||
if self.show_logger:
|
||||
logger.info(f"SQLAlchemy: delete_feedback, feedback_id={feedback_id}")
|
||||
query = """DELETE FROM feedbacks WHERE "id" = :feedback_id"""
|
||||
query = 'DELETE FROM feedbacks WHERE "id" = :feedback_id'
|
||||
parameters = {"feedback_id": feedback_id}
|
||||
await self.execute_sql(query=query, parameters=parameters)
|
||||
return True
|
||||
@@ -425,17 +422,15 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
logger.info(
|
||||
f"SQLAlchemy: get_element, thread_id={thread_id}, element_id={element_id}"
|
||||
)
|
||||
query = """SELECT * FROM elements WHERE "threadId" = :thread_id AND "id" = :element_id"""
|
||||
query = 'SELECT * FROM elements WHERE "threadId" = :thread_id AND "id" = :element_id'
|
||||
parameters = {"thread_id": thread_id, "element_id": element_id}
|
||||
element: Union[List[Dict[str, Any]], int, None] = await self.execute_sql(
|
||||
query=query, parameters=parameters
|
||||
)
|
||||
element = await self.execute_sql(query=query, parameters=parameters)
|
||||
if isinstance(element, list) and element:
|
||||
element_dict: Dict[str, Any] = element[0]
|
||||
element_dict = element[0]
|
||||
return ElementDict(
|
||||
id=element_dict["id"],
|
||||
threadId=element_dict.get("threadId"),
|
||||
type=element_dict["type"],
|
||||
type=element_dict.get("type"),
|
||||
chainlitKey=element_dict.get("chainlitKey"),
|
||||
url=element_dict.get("url"),
|
||||
objectKey=element_dict.get("objectKey"),
|
||||
@@ -458,9 +453,7 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
logger.info(f"SQLAlchemy: create_element, element_id = {element.id}")
|
||||
|
||||
if not self.storage_provider:
|
||||
logger.warn(
|
||||
"SQLAlchemy: create_element error. No blob_storage_client is configured!"
|
||||
)
|
||||
logger.warn("SQLAlchemy: create_element error. No storage client!")
|
||||
return
|
||||
if not element.for_id:
|
||||
return
|
||||
@@ -496,18 +489,15 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
object_key=file_object_key, data=content, mime=element.mime, overwrite=True
|
||||
)
|
||||
if not uploaded_file:
|
||||
raise ValueError(
|
||||
"SQLAlchemy Error: create_element, Failed to persist data in storage_provider"
|
||||
)
|
||||
raise ValueError("Failed to persist data in storage_provider")
|
||||
|
||||
element_dict: ElementDict = element.to_dict()
|
||||
|
||||
element_dict["url"] = uploaded_file.get("url")
|
||||
element_dict["objectKey"] = uploaded_file.get("object_key")
|
||||
element_dict_cleaned = {k: v for k, v in element_dict.items() if v is not None}
|
||||
|
||||
columns = ", ".join(f'"{column}"' for column in element_dict_cleaned.keys())
|
||||
placeholders = ", ".join(f":{column}" for column in element_dict_cleaned.keys())
|
||||
placeholders = ", ".join(f':{column}' for column in element_dict_cleaned.keys())
|
||||
query = f"INSERT INTO elements ({columns}) VALUES ({placeholders})"
|
||||
await self.execute_sql(query=query, parameters=element_dict_cleaned)
|
||||
|
||||
@@ -515,14 +505,13 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
async def delete_element(self, element_id: str, thread_id: Optional[str] = None):
|
||||
if self.show_logger:
|
||||
logger.info(f"SQLAlchemy: delete_element, element_id={element_id}")
|
||||
query = """DELETE FROM elements WHERE "id" = :id"""
|
||||
query = 'DELETE FROM elements WHERE "id" = :id'
|
||||
parameters = {"id": element_id}
|
||||
await self.execute_sql(query=query, parameters=parameters)
|
||||
|
||||
async def get_all_user_threads(
|
||||
self, user_id: Optional[str] = None, thread_id: Optional[str] = None
|
||||
) -> Optional[List[ThreadDict]]:
|
||||
"""Fetch all user threads up to self.user_thread_limit, or one thread by id if thread_id is provided."""
|
||||
if self.show_logger:
|
||||
logger.info("SQLAlchemy: get_all_user_threads")
|
||||
user_threads_query = """
|
||||
@@ -533,19 +522,21 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
"userId" AS user_id,
|
||||
"userIdentifier" AS user_identifier,
|
||||
"tags" AS thread_tags,
|
||||
"metadata" AS thread_metadata
|
||||
"meta" AS thread_meta
|
||||
FROM threads
|
||||
WHERE "userId" = :user_id OR "id" = :thread_id
|
||||
WHERE ("userId" = :user_id OR :user_id IS NULL)
|
||||
AND ("id" = :thread_id OR :thread_id IS NULL)
|
||||
ORDER BY "createdAt" DESC
|
||||
LIMIT :limit
|
||||
"""
|
||||
params = {
|
||||
"user_id": user_id,
|
||||
"thread_id": thread_id,
|
||||
"limit": self.user_thread_limit,
|
||||
}
|
||||
user_threads = await self.execute_sql(
|
||||
query=user_threads_query,
|
||||
parameters={
|
||||
"user_id": user_id,
|
||||
"limit": self.user_thread_limit,
|
||||
"thread_id": thread_id,
|
||||
},
|
||||
parameters=params,
|
||||
)
|
||||
if not isinstance(user_threads, list):
|
||||
return None
|
||||
@@ -553,9 +544,7 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
return []
|
||||
else:
|
||||
thread_ids = (
|
||||
"('"
|
||||
+ "','".join(map(str, [thread["thread_id"] for thread in user_threads]))
|
||||
+ "')"
|
||||
"('" + "','".join([t["thread_id"] for t in user_threads]) + "')"
|
||||
)
|
||||
|
||||
steps_feedbacks_query = f"""
|
||||
@@ -568,13 +557,13 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
s."streaming" AS step_streaming,
|
||||
s."waitForAnswer" AS step_waitforanswer,
|
||||
s."isError" AS step_iserror,
|
||||
s."metadata" AS step_metadata,
|
||||
s."meta" AS step_meta,
|
||||
s."tags" AS step_tags,
|
||||
s."input" AS step_input,
|
||||
s."output" AS step_output,
|
||||
s."createdAt" AS step_createdat,
|
||||
s."start" AS step_start,
|
||||
s."end" AS step_end,
|
||||
s."startTime" AS step_start,
|
||||
s."endTime" AS step_end,
|
||||
s."generation" AS step_generation,
|
||||
s."showInput" AS step_showinput,
|
||||
s."language" AS step_language,
|
||||
@@ -612,34 +601,47 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
|
||||
thread_dicts = {}
|
||||
for thread in user_threads:
|
||||
thread_id = thread["thread_id"]
|
||||
if thread_id is not None:
|
||||
# Ensure metadata is a dictionary
|
||||
metadata = thread["thread_metadata"]
|
||||
if isinstance(metadata, str):
|
||||
try:
|
||||
metadata = json.loads(metadata)
|
||||
except json.JSONDecodeError:
|
||||
metadata = {}
|
||||
elif metadata is None:
|
||||
metadata = {}
|
||||
t_id = thread["thread_id"]
|
||||
meta = thread["thread_meta"]
|
||||
if isinstance(meta, str):
|
||||
try:
|
||||
meta = json.loads(meta)
|
||||
except:
|
||||
meta = {}
|
||||
tags = thread["thread_tags"]
|
||||
if isinstance(tags, str):
|
||||
try:
|
||||
tags = json.loads(tags)
|
||||
except:
|
||||
tags = []
|
||||
thread_dicts[t_id] = ThreadDict(
|
||||
id=t_id,
|
||||
createdAt=thread["thread_createdat"],
|
||||
name=thread["thread_name"],
|
||||
userId=thread["user_id"],
|
||||
userIdentifier=thread["user_identifier"],
|
||||
tags=tags,
|
||||
metadata=meta,
|
||||
steps=[],
|
||||
elements=[],
|
||||
)
|
||||
|
||||
thread_dicts[thread_id] = ThreadDict(
|
||||
id=thread_id,
|
||||
createdAt=thread["thread_createdat"],
|
||||
name=thread["thread_name"],
|
||||
userId=thread["user_id"],
|
||||
userIdentifier=thread["user_identifier"],
|
||||
tags=thread["thread_tags"],
|
||||
metadata=metadata,
|
||||
steps=[],
|
||||
elements=[],
|
||||
)
|
||||
# Process steps_feedbacks to populate the steps in the corresponding ThreadDict
|
||||
if isinstance(steps_feedbacks, list):
|
||||
for step_feedback in steps_feedbacks:
|
||||
thread_id = step_feedback["step_threadid"]
|
||||
if thread_id is not None:
|
||||
t_id = step_feedback["step_threadid"]
|
||||
if t_id in thread_dicts:
|
||||
meta = step_feedback["step_meta"]
|
||||
if isinstance(meta, str):
|
||||
try:
|
||||
meta = json.loads(meta)
|
||||
except:
|
||||
meta = {}
|
||||
tags = step_feedback["step_tags"]
|
||||
if isinstance(tags, str):
|
||||
try:
|
||||
tags = json.loads(tags)
|
||||
except:
|
||||
tags = []
|
||||
feedback = None
|
||||
if step_feedback["feedback_value"] is not None:
|
||||
feedback = FeedbackDict(
|
||||
@@ -648,47 +650,41 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
value=step_feedback["feedback_value"],
|
||||
comment=step_feedback.get("feedback_comment"),
|
||||
)
|
||||
step_dict = {
|
||||
"id": step_feedback["step_id"],
|
||||
"name": step_feedback["step_name"],
|
||||
"type": step_feedback["step_type"],
|
||||
"threadId": thread_id,
|
||||
"parentId": step_feedback.get("step_parentid"),
|
||||
"streaming": step_feedback.get("step_streaming", False),
|
||||
"waitForAnswer": step_feedback.get("step_waitforanswer"),
|
||||
"isError": step_feedback.get("step_iserror"),
|
||||
"metadata": (
|
||||
step_feedback["step_metadata"]
|
||||
if step_feedback.get("step_metadata") is not None
|
||||
else {}
|
||||
),
|
||||
"tags": step_feedback.get("step_tags"),
|
||||
"input": (
|
||||
step_feedback.get("step_input", "")
|
||||
if step_feedback.get("step_showinput")
|
||||
not in [None, "false"]
|
||||
else ""
|
||||
),
|
||||
"output": step_feedback.get("step_output", ""),
|
||||
"createdAt": step_feedback.get("step_createdat"),
|
||||
"start": step_feedback.get("step_start"),
|
||||
"end": step_feedback.get("step_end"),
|
||||
"generation": step_feedback.get("step_generation"),
|
||||
"showInput": step_feedback.get("step_showinput"),
|
||||
"language": step_feedback.get("step_language"),
|
||||
"indent": step_feedback.get("step_indent"),
|
||||
"feedback": feedback,
|
||||
}
|
||||
# Append the step to the steps list of the corresponding ThreadDict
|
||||
thread_dicts[thread_id]["steps"].append(step_dict)
|
||||
input_val = step_feedback.get("step_input", "")
|
||||
show_input = step_feedback.get("step_showinput", "false")
|
||||
if show_input == "false":
|
||||
input_val = ""
|
||||
step_dict = StepDict(
|
||||
id=step_feedback["step_id"],
|
||||
name=step_feedback["step_name"],
|
||||
type=step_feedback["step_type"],
|
||||
threadId=t_id,
|
||||
parentId=step_feedback.get("step_parentid"),
|
||||
streaming=step_feedback.get("step_streaming", False),
|
||||
waitForAnswer=step_feedback.get("step_waitforanswer"),
|
||||
isError=step_feedback.get("step_iserror"),
|
||||
metadata=meta,
|
||||
tags=tags,
|
||||
input=input_val,
|
||||
output=step_feedback.get("step_output", ""),
|
||||
createdAt=step_feedback.get("step_createdat"),
|
||||
start=step_feedback.get("step_start"),
|
||||
end=step_feedback.get("step_end"),
|
||||
generation=step_feedback.get("step_generation"),
|
||||
showInput=step_feedback.get("step_showinput"),
|
||||
language=step_feedback.get("step_language"),
|
||||
indent=step_feedback.get("step_indent"),
|
||||
feedback=feedback,
|
||||
)
|
||||
thread_dicts[t_id]["steps"].append(step_dict)
|
||||
|
||||
if isinstance(elements, list):
|
||||
for element in elements:
|
||||
thread_id = element["element_threadid"]
|
||||
if thread_id is not None:
|
||||
t_id = element["element_threadid"]
|
||||
if t_id in thread_dicts:
|
||||
element_dict = ElementDict(
|
||||
id=element["element_id"],
|
||||
threadId=thread_id,
|
||||
threadId=t_id,
|
||||
type=element["element_type"],
|
||||
chainlitKey=element.get("element_chainlitkey"),
|
||||
url=element.get("element_url"),
|
||||
@@ -703,6 +699,6 @@ class SQLAlchemyDataLayer(BaseDataLayer):
|
||||
forId=element.get("element_forid"),
|
||||
mime=element.get("element_mime"),
|
||||
)
|
||||
thread_dicts[thread_id]["elements"].append(element_dict) # type: ignore
|
||||
thread_dicts[t_id]["elements"].append(element_dict)
|
||||
|
||||
return list(thread_dicts.values())
|
||||
return list(thread_dicts.values())
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "PraisonAI"
|
||||
version = "1.0.4"
|
||||
version = "1.0.5"
|
||||
description = "PraisonAI application combines AutoGen and CrewAI or similar frameworks into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customization, and efficient human-agent collaboration."
|
||||
authors = ["Mervin Praison"]
|
||||
license = ""
|
||||
|
||||
Reference in new issue
Block a user