diff --git a/package-lock.json b/package-lock.json index 604dd74..8eb3cbd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -58,6 +58,9 @@ }, "engines": { "node": ">=18" + }, + "optionalDependencies": { + "@supabase/supabase-js": "^2.57.4" } }, "node_modules/@alcalzone/ansi-tokenize": { @@ -170,9 +173,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", - "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", + "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", "cpu": [ "ppc64" ], @@ -187,9 +190,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", - "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", + "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", "cpu": [ "arm" ], @@ -204,9 +207,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", - "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", + "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", "cpu": [ "arm64" ], @@ -221,9 +224,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", - "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", + "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", "cpu": [ "x64" ], @@ -238,9 +241,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", - "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", + "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", "cpu": [ "arm64" ], @@ -255,9 +258,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", - "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", + "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", "cpu": [ "x64" ], @@ -272,9 +275,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", - "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", + "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", "cpu": [ "arm64" ], @@ -289,9 +292,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", - "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", + "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", "cpu": [ "x64" ], @@ -306,9 +309,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", - "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", + "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", "cpu": [ "arm" ], @@ -323,9 +326,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", - "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", + "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", "cpu": [ "arm64" ], @@ -340,9 +343,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", - "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", + "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", "cpu": [ "ia32" ], @@ -357,9 +360,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", - "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", + "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", "cpu": [ "loong64" ], @@ -374,9 +377,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", - "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", + "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", "cpu": [ "mips64el" ], @@ -391,9 +394,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", - "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", + "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", "cpu": [ "ppc64" ], @@ -408,9 +411,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", - "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", + "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", "cpu": [ "riscv64" ], @@ -425,9 +428,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", - "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", + "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", "cpu": [ "s390x" ], @@ -442,9 +445,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", - "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", + "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", "cpu": [ "x64" ], @@ -459,9 +462,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", - "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", + "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", "cpu": [ "arm64" ], @@ -476,9 +479,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", - "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", + "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", "cpu": [ "x64" ], @@ -493,9 +496,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", - "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", + "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", "cpu": [ "arm64" ], @@ -510,9 +513,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", - "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", + "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", "cpu": [ "x64" ], @@ -527,9 +530,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", - "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", + "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", "cpu": [ "arm64" ], @@ -544,9 +547,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", - "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", + "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", "cpu": [ "x64" ], @@ -561,9 +564,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", - "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", + "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", "cpu": [ "arm64" ], @@ -578,9 +581,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", - "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", + "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", "cpu": [ "ia32" ], @@ -595,9 +598,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", - "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", + "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", "cpu": [ "x64" ], @@ -811,9 +814,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.35.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.35.0.tgz", - "integrity": "sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==", + "version": "9.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.36.0.tgz", + "integrity": "sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==", "dev": true, "license": "MIT", "engines": { @@ -1036,9 +1039,9 @@ } }, "node_modules/@langchain/core": { - "version": "0.3.76", - "resolved": "https://registry.npmjs.org/@langchain/core/-/core-0.3.76.tgz", - "integrity": "sha512-jYQ9Djbmp/iQNzZOtXc+/WACsBKV2Bha83+p7TddN+aC7Sb7jTRENoNWypnIFCd5EaEn1XVQazuXlaWZoxkA+A==", + "version": "0.3.77", + "resolved": "https://registry.npmjs.org/@langchain/core/-/core-0.3.77.tgz", + "integrity": "sha512-aqXHea9xfpVn6VoCq9pjujwFqrh3vw3Fgm9KFUZJ1cF7Bx5HI62DvQPw8LlRB3NB4dhwBBA1ldAVkkkd1du8nA==", "license": "MIT", "dependencies": { "@cfworker/json-schema": "^4.0.2", @@ -1120,9 +1123,9 @@ } }, "node_modules/@langchain/openai": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/@langchain/openai/-/openai-0.6.12.tgz", - "integrity": "sha512-xc81QFQ2E5IuwCOYN91TG2prsbsxH2jAqMbZx2nRO+3XUzqH5RNqxSHvJKFmh9793KcPw3PE3vEvBQ8oO+3iOA==", + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@langchain/openai/-/openai-0.6.13.tgz", + "integrity": "sha512-+QCVag3J2MeFxLMPjjYYpDCBKbmrK7D/xQGq+iWBGpNSg/08vnx7pEkkhiL2NTFIHiYu7w/7EG3UHQ8gOK/cag==", "license": "MIT", "dependencies": { "js-tiktoken": "^1.0.12", @@ -1552,6 +1555,87 @@ "eslint": ">=9.0.0" } }, + "node_modules/@supabase/auth-js": { + "version": "2.71.1", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.71.1.tgz", + "integrity": "sha512-mMIQHBRc+SKpZFRB2qtupuzulaUhFYupNyxqDj5Jp/LyPvcWvjaJzZzObv6URtL/O6lPxkanASnotGtNpS3H2Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/functions-js": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.4.6.tgz", + "integrity": "sha512-bhjZ7rmxAibjgmzTmQBxJU6ZIBCCJTc3Uwgvdi4FewueUTAGO5hxZT1Sj6tiD+0dSXf9XI87BDdJrg12z8Uaew==", + "license": "MIT", + "optional": true, + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/node-fetch": { + "version": "2.6.15", + "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz", + "integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/@supabase/postgrest-js": { + "version": "1.21.4", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.21.4.tgz", + "integrity": "sha512-TxZCIjxk6/dP9abAi89VQbWWMBbybpGWyvmIzTd79OeravM13OjR/YEYeyUOPcM1C3QyvXkvPZhUfItvmhY1IQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/realtime-js": { + "version": "2.15.5", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.15.5.tgz", + "integrity": "sha512-/Rs5Vqu9jejRD8ZeuaWXebdkH+J7V6VySbCZ/zQM93Ta5y3mAmocjioa/nzlB6qvFmyylUgKVS1KpE212t30OA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@supabase/node-fetch": "^2.6.13", + "@types/phoenix": "^1.6.6", + "@types/ws": "^8.18.1", + "ws": "^8.18.2" + } + }, + "node_modules/@supabase/storage-js": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.12.1.tgz", + "integrity": "sha512-QWg3HV6Db2J81VQx0PqLq0JDBn4Q8B1FYn1kYcbla8+d5WDmTdwwMr+EJAxNOSs9W4mhKMv+EYCpCrTFlTj4VQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/supabase-js": { + "version": "2.57.4", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.57.4.tgz", + "integrity": "sha512-LcbTzFhHYdwfQ7TRPfol0z04rLEyHabpGYANME6wkQ/kLtKNmI+Vy+WEM8HxeOZAtByUFxoUTTLwhXmrh+CcVw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@supabase/auth-js": "2.71.1", + "@supabase/functions-js": "2.4.6", + "@supabase/node-fetch": "2.6.15", + "@supabase/postgrest-js": "1.21.4", + "@supabase/realtime-js": "2.15.5", + "@supabase/storage-js": "2.12.1" + } + }, "node_modules/@swc-node/core": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@swc-node/core/-/core-1.14.1.tgz", @@ -1904,9 +1988,9 @@ } }, "node_modules/@types/node": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.5.0.tgz", - "integrity": "sha512-y1dMvuvJspJiPSDZUQ+WMBvF7dpnEqN4x9DDC9ie5Fs/HUZJA3wFp7EhHoVaKX/iI0cRoECV8X2jL8zi0xrHCg==", + "version": "24.5.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.5.2.tgz", + "integrity": "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==", "license": "MIT", "dependencies": { "undici-types": "~7.12.0" @@ -1922,6 +2006,13 @@ "form-data": "^4.0.4" } }, + "node_modules/@types/phoenix": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.6.tgz", + "integrity": "sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==", + "license": "MIT", + "optional": true + }, "node_modules/@types/react": { "version": "19.1.13", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.13.tgz", @@ -1954,18 +2045,28 @@ "@types/node": "*" } }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.44.0.tgz", - "integrity": "sha512-EGDAOGX+uwwekcS0iyxVDmRV9HX6FLSM5kzrAToLTsr9OWCIKG/y3lQheCq18yZ5Xh78rRKJiEpP0ZaCs4ryOQ==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.44.1.tgz", + "integrity": "sha512-molgphGqOBT7t4YKCSkbasmu1tb1MgrZ2szGzHbclF7PNmOkSTQVHy+2jXOSnxvR3+Xe1yySHFZoqMpz3TfQsw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.44.0", - "@typescript-eslint/type-utils": "8.44.0", - "@typescript-eslint/utils": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0", + "@typescript-eslint/scope-manager": "8.44.1", + "@typescript-eslint/type-utils": "8.44.1", + "@typescript-eslint/utils": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -1979,23 +2080,23 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.44.0", + "@typescript-eslint/parser": "^8.44.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.44.0.tgz", - "integrity": "sha512-VGMpFQGUQWYT9LfnPcX8ouFojyrZ/2w3K5BucvxL/spdNehccKhB4jUyB1yBCXpr2XFm0jkECxgrpXBW2ipoAw==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.44.1.tgz", + "integrity": "sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.44.0", - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/typescript-estree": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0", + "@typescript-eslint/scope-manager": "8.44.1", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/typescript-estree": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1", "debug": "^4.3.4" }, "engines": { @@ -2011,14 +2112,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.44.0.tgz", - "integrity": "sha512-ZeaGNraRsq10GuEohKTo4295Z/SuGcSq2LzfGlqiuEvfArzo/VRrT0ZaJsVPuKZ55lVbNk8U6FcL+ZMH8CoyVA==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.44.1.tgz", + "integrity": "sha512-ycSa60eGg8GWAkVsKV4E6Nz33h+HjTXbsDT4FILyL8Obk5/mx4tbvCNsLf9zret3ipSumAOG89UcCs/KRaKYrA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.44.0", - "@typescript-eslint/types": "^8.44.0", + "@typescript-eslint/tsconfig-utils": "^8.44.1", + "@typescript-eslint/types": "^8.44.1", "debug": "^4.3.4" }, "engines": { @@ -2033,14 +2134,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.0.tgz", - "integrity": "sha512-87Jv3E+al8wpD+rIdVJm/ItDBe/Im09zXIjFoipOjr5gHUhJmTzfFLuTJ/nPTMc2Srsroy4IBXwcTCHyRR7KzA==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.1.tgz", + "integrity": "sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0" + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2051,9 +2152,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.44.0.tgz", - "integrity": "sha512-x5Y0+AuEPqAInc6yd0n5DAcvtoQ/vyaGwuX5HE9n6qAefk1GaedqrLQF8kQGylLUb9pnZyLf+iEiL9fr8APDtQ==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.44.1.tgz", + "integrity": "sha512-B5OyACouEjuIvof3o86lRMvyDsFwZm+4fBOqFHccIctYgBjqR3qT39FBYGN87khcgf0ExpdCBeGKpKRhSFTjKQ==", "dev": true, "license": "MIT", "engines": { @@ -2068,15 +2169,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.44.0.tgz", - "integrity": "sha512-9cwsoSxJ8Sak67Be/hD2RNt/fsqmWnNE1iHohG8lxqLSNY8xNfyY7wloo5zpW3Nu9hxVgURevqfcH6vvKCt6yg==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.44.1.tgz", + "integrity": "sha512-KdEerZqHWXsRNKjF9NYswNISnFzXfXNDfPxoTh7tqohU/PRIbwTmsjGK6V9/RTYWau7NZvfo52lgVk+sJh0K3g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/typescript-estree": "8.44.0", - "@typescript-eslint/utils": "8.44.0", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/typescript-estree": "8.44.1", + "@typescript-eslint/utils": "8.44.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -2093,9 +2194,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.0.tgz", - "integrity": "sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.1.tgz", + "integrity": "sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==", "dev": true, "license": "MIT", "engines": { @@ -2107,16 +2208,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.0.tgz", - "integrity": "sha512-lqNj6SgnGcQZwL4/SBJ3xdPEfcBuhCG8zdcwCPgYcmiPLgokiNDKlbPzCwEwu7m279J/lBYWtDYL+87OEfn8Jw==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.1.tgz", + "integrity": "sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.44.0", - "@typescript-eslint/tsconfig-utils": "8.44.0", - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0", + "@typescript-eslint/project-service": "8.44.1", + "@typescript-eslint/tsconfig-utils": "8.44.1", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2136,16 +2237,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.0.tgz", - "integrity": "sha512-nktOlVcg3ALo0mYlV+L7sWUD58KG4CMj1rb2HUVOO4aL3K/6wcD+NERqd0rrA5Vg06b42YhF6cFxeixsp9Riqg==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.1.tgz", + "integrity": "sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.44.0", - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/typescript-estree": "8.44.0" + "@typescript-eslint/scope-manager": "8.44.1", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/typescript-estree": "8.44.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2160,13 +2261,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.0.tgz", - "integrity": "sha512-zaz9u8EJ4GBmnehlrpoKvj/E3dNbuQ7q0ucyZImm3cLqJ8INTc970B1qEqDX/Rzq65r3TvVTN7kHWPBoyW7DWw==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.1.tgz", + "integrity": "sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.0", + "@typescript-eslint/types": "8.44.1", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -3611,9 +3712,9 @@ ] }, "node_modules/esbuild": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", - "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", + "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -3624,32 +3725,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.9", - "@esbuild/android-arm": "0.25.9", - "@esbuild/android-arm64": "0.25.9", - "@esbuild/android-x64": "0.25.9", - "@esbuild/darwin-arm64": "0.25.9", - "@esbuild/darwin-x64": "0.25.9", - "@esbuild/freebsd-arm64": "0.25.9", - "@esbuild/freebsd-x64": "0.25.9", - "@esbuild/linux-arm": "0.25.9", - "@esbuild/linux-arm64": "0.25.9", - "@esbuild/linux-ia32": "0.25.9", - "@esbuild/linux-loong64": "0.25.9", - "@esbuild/linux-mips64el": "0.25.9", - "@esbuild/linux-ppc64": "0.25.9", - "@esbuild/linux-riscv64": "0.25.9", - "@esbuild/linux-s390x": "0.25.9", - "@esbuild/linux-x64": "0.25.9", - "@esbuild/netbsd-arm64": "0.25.9", - "@esbuild/netbsd-x64": "0.25.9", - "@esbuild/openbsd-arm64": "0.25.9", - "@esbuild/openbsd-x64": "0.25.9", - "@esbuild/openharmony-arm64": "0.25.9", - "@esbuild/sunos-x64": "0.25.9", - "@esbuild/win32-arm64": "0.25.9", - "@esbuild/win32-ia32": "0.25.9", - "@esbuild/win32-x64": "0.25.9" + "@esbuild/aix-ppc64": "0.25.10", + "@esbuild/android-arm": "0.25.10", + "@esbuild/android-arm64": "0.25.10", + "@esbuild/android-x64": "0.25.10", + "@esbuild/darwin-arm64": "0.25.10", + "@esbuild/darwin-x64": "0.25.10", + "@esbuild/freebsd-arm64": "0.25.10", + "@esbuild/freebsd-x64": "0.25.10", + "@esbuild/linux-arm": "0.25.10", + "@esbuild/linux-arm64": "0.25.10", + "@esbuild/linux-ia32": "0.25.10", + "@esbuild/linux-loong64": "0.25.10", + "@esbuild/linux-mips64el": "0.25.10", + "@esbuild/linux-ppc64": "0.25.10", + "@esbuild/linux-riscv64": "0.25.10", + "@esbuild/linux-s390x": "0.25.10", + "@esbuild/linux-x64": "0.25.10", + "@esbuild/netbsd-arm64": "0.25.10", + "@esbuild/netbsd-x64": "0.25.10", + "@esbuild/openbsd-arm64": "0.25.10", + "@esbuild/openbsd-x64": "0.25.10", + "@esbuild/openharmony-arm64": "0.25.10", + "@esbuild/sunos-x64": "0.25.10", + "@esbuild/win32-arm64": "0.25.10", + "@esbuild/win32-ia32": "0.25.10", + "@esbuild/win32-x64": "0.25.10" } }, "node_modules/esbuild-node-externals": { @@ -3691,9 +3792,9 @@ } }, "node_modules/eslint": { - "version": "9.35.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.35.0.tgz", - "integrity": "sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==", + "version": "9.36.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.36.0.tgz", + "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3703,7 +3804,7 @@ "@eslint/config-helpers": "^0.3.1", "@eslint/core": "^0.15.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.35.0", + "@eslint/js": "9.36.0", "@eslint/plugin-kit": "^0.3.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -4785,9 +4886,9 @@ } }, "node_modules/groq-sdk/node_modules/@types/node": { - "version": "18.19.125", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.125.tgz", - "integrity": "sha512-4TWNu0IxTQcszliYdW2mxrVvhHeERUeDCUwVuvQFn9JCU02kxrUDs8v52yOazPo7wLHKgqEd2FKxlSN6m8Deqg==", + "version": "18.19.127", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.127.tgz", + "integrity": "sha512-gSjxjrnKXML/yo0BO099uPixMqfpJU0TKYjpfLU7TrtA2WWDki412Np/RSTPRil1saKBhvVVKzVx/p/6p94nVA==", "license": "MIT", "dependencies": { "undici-types": "~5.26.4" @@ -4983,9 +5084,9 @@ "license": "ISC" }, "node_modules/ink": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/ink/-/ink-6.3.0.tgz", - "integrity": "sha512-2CbJAa7XeziZYe6pDS5RVLirRY28iSGMQuEV8jRU5NQsONQNfcR/BZHHc9vkMg2lGYTHTM2pskxC1YmY28p6bQ==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/ink/-/ink-6.3.1.tgz", + "integrity": "sha512-3wGwITGrzL6rkWsi2gEKzgwdafGn4ZYd3u4oRp+sOPvfoxEHlnoB5Vnk9Uy5dMRUhDOqF3hqr4rLQ4lEzBc2sQ==", "license": "MIT", "dependencies": { "@alcalzone/ansi-tokenize": "^0.2.0", @@ -5018,7 +5119,7 @@ "peerDependencies": { "@types/react": ">=19.0.0", "react": ">=19.0.0", - "react-devtools-core": "^4.19.1" + "react-devtools-core": "^6.1.2" }, "peerDependenciesMeta": { "@types/react": { diff --git a/package.json b/package.json index 390e940..c83ab23 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,9 @@ "ulid": "^3.0.1", "write-file-atomic": "^6.0.0" }, + "optionalDependencies": { + "@supabase/supabase-js": "^2.57.4" + }, "devDependencies": { "@sindresorhus/tsconfig": "^7.0.0", "@stylistic/eslint-plugin": "^5.1.0", diff --git a/src/ai/session/chat-server/api-client.ts b/src/ai/session/chat-server/api-client.ts new file mode 100644 index 0000000..7906508 --- /dev/null +++ b/src/ai/session/chat-server/api-client.ts @@ -0,0 +1,354 @@ +// A simple, configurable client library for the documents and links APIs. + +import type { REALTIME_SUBSCRIBE_STATES, RealtimeChannel, SupabaseClient } from "@supabase/supabase-js"; + +import tryCatch from "../../../utils/try-catch.js"; + +export interface IAuthData +{ + user_id: string; + access_token: string; + expires_at: number; + api_url: string; + api_key: string; + channel: string; +} + +export type IClientStatusOptional = + | string + | number + | boolean + | null + | undefined + | { [key: string]: IClientStatusOptional | undefined } + | IClientStatusOptional[]; + +export interface IClientStatus +{ + type: "consumer-client" | "super-client"; + user_id: string; + external_id: string; + status: "idle" | "working"; + optional?: { [key: string]: IClientStatusOptional }; +} + +export interface IApiClientOptions +{ + baseUrl?: string; + token?: string; +} + +export interface IApiClientCommandListener +{ + handleCommand: (payload: any) => void; + handleConnection: (connected: boolean) => void; + handleError: (message: string, level?: "debug" | "warn" | "error", error?: Error) => void; +} + +class ApiClient +{ + private baseUrl: string; + private token?: string; + + private authData?: IAuthData; + + private supabase?: SupabaseClient; + private channel?: RealtimeChannel; + + private commandListeners: IApiClientCommandListener[] = []; + + private _initPromise?: Promise; + + // Reconnection/backoff state + private reconnectAttempt = 0; + private reconnectTimer?: NodeJS.Timeout; + + constructor(options: IApiClientOptions = {}) + { + this.baseUrl = options.baseUrl || ""; + this.token = options.token; + } + + private async _request(path: string, options: RequestInit): Promise + { + const url = new URL(path, this.baseUrl).href; + const headers = new Headers(options.headers || {}); + headers.set("Content-Type", "application/json"); + + if (this.token) + { + headers.set("Authorization", `Bearer ${this.token}`); + } + + const response = await fetch(url, { ...options, headers }); + + if (!response.ok) + { + const errorBody = await response.json().catch(() => ({ error: `Request failed with status ${response.status}` })); + throw new Error(errorBody.error || "An unknown error occurred"); + } + + const text = await response.text(); + return text ? JSON.parse(text) as T : {} as T; + } + + // --- ---- + addCommandListener(listener: IApiClientCommandListener) + { + if (!this.commandListeners.includes(listener)) + { + this.commandListeners.push(listener); + } + }; + + removeCommandListener(f: IApiClientCommandListener) + { + const i = this.commandListeners.indexOf(f); + + if (i !== -1) + { + this.commandListeners.splice(i, 1); + } + }; + + private pushCommand(payload: any) + { + this.commandListeners.forEach(listener => tryCatch(() => listener.handleCommand(payload))); + } + + private pushConnection(connected: boolean) + { + this.commandListeners.forEach(listener => tryCatch(() => listener.handleConnection(connected))); + } + + private pushError(message: string, level: "debug" | "warn" | "error" = "error", error?: Error) + { + this.commandListeners.forEach(listener => tryCatch(() => listener.handleError(message, level, error))); + } + + // --- Auth API --- + + private getAuthData(): Promise + { + return this._request("api/auth/access-token", { method: "POST" }); + } + + // --- Realtime API --- + + private getAccessToken = async () => + { + if (!this.supabase || (this.authData?.expires_at || 0) > Date.now() / 1000 + 60) + { + return this.authData?.access_token || null; + } + + const authData = await this.getAuthData(); + this.authData = authData; + + if (this.supabase?.realtime) + { + this.supabase.realtime.setAuth(authData.access_token); + } + + return this.authData.access_token; + }; + + private createSupabaseClient = async () => + { + this.authData = await this.getAuthData(); + + this.pushError("AUTHDATA\n\n" + JSON.stringify(this.authData, null, 3), "debug"); + + const { createClient } = await import("@supabase/supabase-js"); + + const supabase = createClient(this.authData.api_url, this.authData.api_key, { + accessToken: this.getAccessToken, + }); + + supabase.realtime.setAuth(this.authData.access_token); + + this.supabase = supabase; + + this.channel = supabase.channel(this.authData.channel) + .on( + "postgres_changes", + { + event: "*", + schema: "public", + table: "documents", + filter: `user_id=eq.${this.authData.user_id}`, + }, + (payload: any) => this.pushCommand(payload), + ) + // .on("broadcast", { event: "command" }, (args: any) => this.pushCommand({ args })) + .on("presence", { event: "sync" }, () => this.pushCommand({ presenceState: this.channel?.presenceState() })) + .on("presence", { event: "join" }, (args: any) => this.pushCommand({ args, presenceState: this.channel?.presenceState() })) + .on("presence", { event: "leave" }, (args: any) => this.pushCommand({ args, presenceState: this.channel?.presenceState() })); + + let closed = false; + + this.channel.subscribe((status: REALTIME_SUBSCRIBE_STATES, err) => + { + if (closed) + { + // console.error("CHANNEL-ERROR: already closed!"); + return; + } + + if (["CHANNEL_ERROR", "TIMED_OUT", "CLOSED"].includes(status)) + { + closed = true; + + if (err) + { + this.pushError(err.message); + } + + this.pushConnection(false); + + this.closeSupabaseClient().then(() => this.scheduleReconnect(status)); + } + else if (status === "SUBSCRIBED") + { + this.clearReconnectTimer(); + this.reconnectAttempt = 0; + this.pushConnection(true); + } + }); + + return this.supabase; + }; + + private clearReconnectTimer() + { + if (this.reconnectTimer) + { + clearTimeout(this.reconnectTimer); + this.reconnectTimer = undefined; + } + } + + private scheduleReconnect(reason?: string) + { + // If the client is already connected or a reconnect is pending, do nothing. + if (this.supabase || this.reconnectTimer) + { + return; + } + + const attempt = ++this.reconnectAttempt; + const base = 1000; // 1s + const max = 30000; // 30s cap + const delay = Math.min(max, base * Math.pow(2, attempt - 1)); + const jitter = Math.floor(Math.random() * 250); + const totalDelay = delay + jitter; + + this.pushError(`Scheduling realtime reconnect in ${totalDelay}ms (attempt ${attempt}${reason ? ", reason: " + reason : ""})`, "debug"); + + this.reconnectTimer = setTimeout(async () => + { + this.reconnectTimer = undefined; + try + { + await this.ensureSupabaseClient(); + } + catch (e: any) + { + this.pushError("Reconnect failed.", "error", e); + + // Schedule next attempt if still not connected + if (!this.supabase) + { + this.scheduleReconnect("ensureSupabaseClient failed"); + } + } + }, totalDelay); + } + + private closeSupabaseClient = async (): Promise => + { + if (!this.channel && !this.supabase && !this._initPromise) + { + return; + } + + // Cancel any pending reconnect when we are explicitly closing + this.clearReconnectTimer(); + + await this.channel?.unsubscribe(); + this.channel = undefined; + + await this.supabase?.removeAllChannels(); + await this.supabase?.realtime?.disconnect(); + + this.supabase = undefined; + this.authData = undefined; + }; + + private async ensureSupabaseClient() + { + if (this.supabase) + { + return; + } + + if (!this._initPromise) + { + this._initPromise = this.createSupabaseClient() + .then((_supabase) => + { + // supabase should be ready now! + }) + .catch(error => + { + this.pushError("Failed to create supabase client", "error", error); + + // If creation fails before subscription, schedule a reconnect + this.scheduleReconnect("init-failed"); + }) + .finally(() => + { + this._initPromise = undefined; + }); + } + + await this._initPromise; + } + + async start() + { + await this.ensureSupabaseClient(); + } + + async setStatus(status: Pick) + { + await this.ensureSupabaseClient(); + + if (this.authData?.user_id) + { + await this.channel?.track({ + user_id: this.authData!.user_id, + type: "super-client", + external_id: status.external_id, + status: status.status, + optional: status.optional, + } satisfies IClientStatus); + } + } + + // --- Direct Supabase API --- + + async directUpsertDocument(externalId: string, documentData: { data: Record, schema_id?: string | null }) + { + const rpcParams = { + p_external_id: externalId, + p_data: documentData.data, + p_schema_id: documentData.schema_id, + } as const; + + await this.ensureSupabaseClient(); + await this.supabase?.rpc("upsert_document", rpcParams).select().single(); + } +} + +export { ApiClient }; diff --git a/src/ai/session/chat-server/chat-server-client.ts b/src/ai/session/chat-server/chat-server-client.ts new file mode 100644 index 0000000..3f29f71 --- /dev/null +++ b/src/ai/session/chat-server/chat-server-client.ts @@ -0,0 +1,298 @@ +import { AIMessage, BaseMessage, HumanMessage } from "@langchain/core/messages"; + +import { ErrorMessage, isMessageStreaming, TMessage, TMessageType, ToolProgressMessage } from "../../custom-messages.js"; +import { ChatSession, TToolMode } from "../session.js"; +import { ApiClient, IApiClientCommandListener } from "./api-client.js"; +import { IChat, IChatMessage } from "./types.js"; + +const MESSAGE_BASE = { + history: [], + historyIndex: 0, + createdAt: Date.now(), +}; + +function mapMessage(message: TMessage): IChatMessage +{ + const type: TMessageType = message.getType(); + + if (type === "tool-progress") + { + const toolProgressMessage = message as ToolProgressMessage; + + return { + ...MESSAGE_BASE, + role: "tool-progress", + content: toolProgressMessage.content ?? "", + toolCall: { + ...toolProgressMessage.toolCall, + status: toolProgressMessage.status, + confirmState: toolProgressMessage.confirmState, + description: toolProgressMessage.info.description, + fileName: toolProgressMessage.info.fileName, + }, + }; + } + + if (type === "error") + { + const errorMessage = message as ErrorMessage; + + return { + ...MESSAGE_BASE, + role: type, + content: errorMessage.content, + privateData: errorMessage, + }; + } + + if (type === "human") + { + const userMessage = message as HumanMessage; + + return { + ...MESSAGE_BASE, + role: "user", + content: userMessage.text, + }; + } + + if (type === "ai") + { + const assistantMessage = message as AIMessage; + + return { + ...MESSAGE_BASE, + hidden: assistantMessage.text.length === 0, + role: "assistant", + content: assistantMessage.text, + }; + } + + if (type === "system") + { + return { + ...MESSAGE_BASE, + role: type, + content: (message as BaseMessage).text, + }; + } + + return { + ...MESSAGE_BASE, + role: "private", + hidden: true, + content: (message as BaseMessage).text, + privateData: message, + }; +} + +function mapSessionToChat(session: ChatSession): IChat +{ + const messages = session.messages.map(mapMessage); + + if (session.isWorking && messages[messages.length - 1]?.role !== "assistant") + { + messages.push({ ...MESSAGE_BASE, role: "assistant", "content": "", state: "working" }); + } + + const chat: IChat = { + id: session.id, + model: { + id: "langchain", + account: { + id: "langchain", + name: "langchain", + }, + name: session.chatServiceOptions.model, + provider: "langchain", + state: { ready: true }, + }, + workspace: { + workDir: session.workDir, + }, + toolMode: session.toolMode, + messages, + state: session.isWorking ? "working" : "done", + }; + + return chat; +} + +class ChatServerClient implements IApiClientCommandListener +{ + private apiClient: ApiClient; + private session: ChatSession; + + private lastStreamingSync = Date.now(); + private isWorking: boolean | undefined = undefined; + + private debug: boolean = false; + + private constructor(apiClient: ApiClient, session: ChatSession) + { + this.apiClient = apiClient; + this.session = session; + + apiClient.addCommandListener(this); + session.onUpdate(props => this.handleSessionUpdate(props)); + } + + static create(session: ChatSession, options?: { debug?: boolean }): ChatServerClient | undefined + { + const URL = process.env["CODE_BANDIT_SERVER_URL"]; + const PAT = process.env["CODE_BANDIT_SERVER_PAT"]; + + const apiClient = URL && PAT ? new ApiClient({ baseUrl: URL, token: PAT }) : undefined; + + if (!apiClient) + { + return undefined; + } + + const chatServerClient = new ChatServerClient(apiClient, session); + chatServerClient.debug = !!options?.debug; + + apiClient.start().then(() => chatServerClient.syncSession()); + + return chatServerClient; + } + + handleCommand = (payload: any) => + { + // console.log("CMD?", payload.new?.external_id); + + if (payload.new?.external_id === `${this.session.id}/cmd`) + { + if (!this.session.isWorking && payload.new.data?.content?.length) + { + this.session.generateResponse([ + ...this.session.messages, + new HumanMessage(payload.new.data.content), + ]); + } + } + else if (payload.new?.external_id === `${this.session.id}/confirm`) + { + if (!this.session.isWorking && payload.new.data?.message_index) + { + this.session.confirmToolUse(payload.new.data.message_index, payload.new.data.confirm_state); + } + } + else if (payload.new?.external_id === `${this.session.id}/abort`) + { + if (this.session.isWorking) + { + this.session.abort(payload.new.data?.reason || "User cancelled."); + } + } + }; + + handleConnection = (connected: boolean) => + { + if (connected) + { + this.session.onlineMode = "ONLINE"; + this.session.notifyListeners(); + this.syncSession(true); + } + else + { + this.session.onlineMode = "OFFLINE"; + this.session.notifyListeners(); + } + }; + + handleError = (message: string, level: "debug" | "warn" | "error" = "error", error?: Error) => + { + if (level !== "debug" || this.debug) + { + this.session.setMessages([ + ...this.session.messages, + new ErrorMessage(message, level, error), + ]); + } + }; + + private handleSessionUpdate = (_props: { messages: TMessage[]; working: boolean; toolMode: TToolMode }) => + { + this._saveOnline(); + }; + + private syncSession = async (force: boolean = false) => + { + // update working status online if changed ... + if (force || this.session.isWorking !== this.isWorking || this.isWorking === undefined) + { + this.apiClient.setStatus({ + external_id: this.session.id, + status: this.session.isWorking ? "working" : "idle", + optional: { working_message_index: this.session.messages.findIndex(m => isMessageStreaming(m)) }, + }); + + this.isWorking = this.session.isWorking; + } + + const aiMessage = this.session.messages.find(m => isMessageStreaming(m)) as (BaseMessage | undefined); + + // console.log("SYNC", force, aiMessage ? "STREAM" : "SYNC"); + + if (aiMessage) + { + if (Date.now() > this.lastStreamingSync + 100) + { + this.lastStreamingSync = Date.now(); + + await this.pushStreamingMessageOnline(aiMessage.text); + } + + return; + } + + await this.pushSessionOnline(); + }; + + private pushSessionOnline = async () => + { + await this.apiClient.directUpsertDocument(this.session.id, { data: mapSessionToChat(this.session) }); + }; + + private pushStreamingMessageOnline = async (content: string) => + { + await this.apiClient.directUpsertDocument(this.session.id + "/rt", { + data: { + type: "chunk", + external_id: this.session.id, + chat_id: this.session.id, + message_number: this.session.messages.length - 1, + content, + }, + }); + }; + + private _saveOnlineQueue: Promise = Promise.resolve(); + _saveOnline = (): Promise => + { + this._saveOnlineQueue = this._saveOnlineQueue + .then(async () => + { + await this.syncSession(); + }) + .catch((error) => + { + this.handleError("Saving session failed", "error", error); + }); + + return this._saveOnlineQueue; + }; +} + +async function startChatServerClient(session: ChatSession, options?: { debug?: boolean }) +{ + ChatServerClient.create(session, options); +} + +export +{ + ChatServerClient, + startChatServerClient, +}; diff --git a/src/ai/session/chat-server/types.ts b/src/ai/session/chat-server/types.ts new file mode 100644 index 0000000..5202d75 --- /dev/null +++ b/src/ai/session/chat-server/types.ts @@ -0,0 +1,244 @@ +type TChatModelProvider = + | "node-llama-cpp" + | "ollama" + | "openai" + | "googleai" + | "groq" + | "xai" + | "openrouter" + | "langchain-js" + | "vercel-ai-sdk" + | string + ; + +export interface IChatModelFeatures +{ + tools?: boolean; + vision?: boolean; + options?: { + temperature?: boolean; + num_ctx?: boolean; + top_k?: boolean; + top_p?: boolean; + min_p?: boolean; + integratedWebSearch?: boolean; + }; +} + +interface IChatModelState +{ + ready?: boolean; + downloadable?: boolean; + removable?: boolean; + hasLocalModelFile?: boolean; +} + +export interface IChatModelOptions +{ + temperature?: number; + num_ctx?: number; + top_k?: number; + top_p?: number; + min_p?: number; + integratedWebSearch?: boolean; +} + +export interface IChatModelConfig +{ + favorite?: boolean; + hidden?: boolean; + options?: IChatModelOptions; +}; + +export interface IChatModel +{ + id: string; + name: string; + provider: TChatModelProvider; + + account: { id: string; name: string; remote?: boolean; removable?: boolean; }; + + displayName?: string; + description?: string; + + modelUri?: string; + modelFile?: string; + + state: IChatModelState; + + contextLength?: number; + size?: number; + parameterSize?: string; + quantizationLevel?: string; + features?: IChatModelFeatures; + + config?: IChatModelConfig; +} + +export class ChatModel implements IChatModel +{ + id: string; + name: string; + provider: TChatModelProvider; + + account: { id: string; name: string; remote?: boolean; removable?: boolean; }; + + displayName?: string; + description?: string; + + modelUri?: string; + modelFile?: string; + + state: IChatModelState; + + contextLength?: number; + size?: number; + parameterSize?: string; + quantizationLevel?: string; + features?: IChatModelFeatures; + + config?: IChatModelConfig; + + constructor(data: IChatModel) + { + this.id = data.id; + this.name = data.name; + this.provider = data.provider; + this.account = structuredClone(data.account); + this.displayName = data.displayName; + this.description = data.description; + this.modelUri = data.modelUri; + this.modelFile = data.modelFile; + this.state = structuredClone(data.state); + this.contextLength = data.contextLength; + this.parameterSize = data.parameterSize; + this.quantizationLevel = data.quantizationLevel; + this.features = structuredClone(data.features); + this.config = structuredClone(data.config); + } +} + +export interface IChatModelInfo +{ + model: Pick; + options?: IChatModelOptions; +} + +export type TAddChatModel = { provider: TChatModelProvider; modelUri: string; startDownload?: boolean; }; + +export type TRemoveChatModel = { provider: TChatModelProvider; modelUri: string; }; + +export interface IAddAccountOpenAI +{ + name: string; + provider: "openai"; + type: "openai"; + apiKey: string; + baseURL?: string; +} + +export interface IAddAccountOpenRouter extends Omit +{ + type: "openrouter"; +} + +interface IAddAccountGoogleAI +{ + name: string; + provider: "googleai"; + apiKey: string; +} + +export type TAddAccount = IAddAccountOpenAI | IAddAccountOpenRouter | IAddAccountGoogleAI; + +export interface TRemoveAccount +{ + provider: TChatModelProvider; + id: string; +} + +export type TChatMessageRole = + | "system" + | "user" + | "assistant" + | "tool" + | "tool-progress" + | "info" + | "error" + | "private" + ; + +export const CONFIRM_STATES = ["no", "yes", "none", "all"] as const; + +export type TConfirmState = typeof CONFIRM_STATES[number]; + +export interface IChatMessageBase +{ + content: string; + images?: string[]; + + toolCall?: { + name: string; + args: Record; + + description?: string; + fileName?: string; + fileData?: string; + originalFileData?: string; + + id?: string; + + status: "pending" | "pending-confirmation" | "confirmed" | "declined" | "success" | "error"; + confirmState?: TConfirmState; + }; + + readonly createdAt: number; + readonly info?: IChatModelInfo; + + showThinking?: boolean; + showDetails?: boolean; + + privateData?: any; +} + +export interface IChatMessage extends IChatMessageBase +{ + role: TChatMessageRole; + hidden?: boolean; + + state?: TChatState; + + history: IChatMessageBase[]; + historyIndex: number; +} + +export interface IWorkspace +{ + workDir?: string; +} + +export type TChatState = "working" | "done" | "stopped"; + +export type TToolMode = "confirm" | "read-only" | "yolo"; + +export interface IChat +{ + id: string; + sourceId?: string; + model: IChatModel; + title?: string; + generatedSummary?: string; + workspace?: IWorkspace; + messages: IChatMessage[]; + currentPrompt?: { content?: string; images?: string[]; messageIndex?: number; }; + state?: TChatState; + toolMode?: TToolMode; + scrollPos?: number; + favorite?: boolean; + useSystemPrompt?: boolean; + showSettings?: boolean; + updatedAt?: number; + deletedAt?: number | "deleted"; +} + +export type TProviderInfo = { [key: string]: any }; diff --git a/src/ai/session/session.ts b/src/ai/session/session.ts index 54f0617..74007df 100644 --- a/src/ai/session/session.ts +++ b/src/ai/session/session.ts @@ -73,6 +73,8 @@ export interface IChatSession streaming: boolean; chatServiceOptions: IChatServiceOptions; + onlineMode?: string; + systemPrompt?: string; // TODO: extend into service or template like "%{DEFAULT}% ..." messages: TMessage[]; @@ -95,6 +97,8 @@ export class ChatSession implements IChatSession chatServiceOptions: IChatServiceOptions; streaming: boolean; + onlineMode?: string; + systemPrompt?: string; messages: TMessage[] = []; @@ -113,6 +117,7 @@ export class ChatSession implements IChatSession this.toolMode = props.toolMode || "confirm"; this.streaming = props.streaming || true; this.chatServiceOptions = props.chatServiceOptions; + this.onlineMode = props.onlineMode; this.systemPrompt = props.systemPrompt; this.messages = props.messages || []; @@ -144,7 +149,7 @@ export class ChatSession implements IChatSession notifyListeners = (): void => { - const props = { messages: [...this.messages], working: this.#isWorking, toolMode: this.toolMode }; + const props = { messages: [...this.messages], working: this.#isWorking, toolMode: this.toolMode, onlineMode: this.onlineMode }; this.onUpdateListeners.forEach(listener => listener(props)); }; diff --git a/src/ai/tools/utils.ts b/src/ai/tools/utils.ts index 8e7d530..6fe8e91 100644 --- a/src/ai/tools/utils.ts +++ b/src/ai/tools/utils.ts @@ -3,7 +3,6 @@ import { tool } from "@langchain/core/tools"; import { realpathSync } from "fs"; import path from "path"; - export function resolveWithinWorkDir(userPath: string, workDir?: unknown): string { if (!workDir || typeof workDir !== "string") diff --git a/src/commands/chat.tsx b/src/commands/chat.tsx index 6244daf..add48ad 100644 --- a/src/commands/chat.tsx +++ b/src/commands/chat.tsx @@ -6,6 +6,7 @@ import React from "react"; import { ChatService, IChatServiceOptions } from "../ai/chat-service.js"; import { ToolProgressMessage } from "../ai/custom-messages.js"; +import { startChatServerClient } from "../ai/session/chat-server/chat-server-client.js"; import { resolveWithinWorkDir } from "../ai/tools/utils.js"; import { BaseMessage, FileSessionStorage, HumanMessage, NodeToolProvider, PromptLoader, TToolMode, work } from "../index.node.js"; import ChatApp from "../ui/chat-app.js"; @@ -70,7 +71,7 @@ async function chat(options: any) debug: options.debug, }; - session.flush(); + startChatServerClient(session, { debug: options.debug }); render(, { exitOnCtrlC: false }); } diff --git a/src/ui/chat-app.tsx b/src/ui/chat-app.tsx index 7672620..fcc6c76 100644 --- a/src/ui/chat-app.tsx +++ b/src/ui/chat-app.tsx @@ -33,6 +33,7 @@ function ChatApp(props: ChatAppProps) const { messages, working, + onlineMode, handleInput, action, selected, @@ -123,6 +124,11 @@ function ChatApp(props: ChatAppProps) [{session.workDir.replace(homedir(), "~")}] + {onlineMode?.length && + + {` ${onlineMode}`} + + } {currentGitBranch && {` ${currentGitBranch}`} diff --git a/src/ui/chat-controller.ts b/src/ui/chat-controller.ts index a799d43..34181b0 100644 --- a/src/ui/chat-controller.ts +++ b/src/ui/chat-controller.ts @@ -20,10 +20,11 @@ export function useChatController(props: UseChatControllerProps) const [ctrlC, setCtrlC] = useState(false); - const [sessionState, setSessionState] = useState<{ messages: TMessage[]; working: boolean; toolMode: TToolMode; }>({ + const [sessionState, setSessionState] = useState<{ messages: TMessage[]; working: boolean; toolMode: TToolMode; onlineMode?: string; }>({ messages: session.messages, working: session.isWorking, toolMode: session.toolMode, + onlineMode: session.onlineMode, }); const [tokenUsage, setTokenUsage] = useState(); @@ -129,6 +130,7 @@ export function useChatController(props: UseChatControllerProps) return { messages: sessionState.messages, working: sessionState.working, + onlineMode: sessionState.onlineMode, handleInput, action, selected: selectedIndex, diff --git a/vscode-extension/package-lock.json b/vscode-extension/package-lock.json index c424249..e95cea2 100644 --- a/vscode-extension/package-lock.json +++ b/vscode-extension/package-lock.json @@ -34,7 +34,7 @@ }, "..": { "name": "@janole/code-bandit", - "version": "0.3.13", + "version": "0.3.17", "license": "MIT", "dependencies": { "@langchain/anthropic": "^0.3.24", @@ -46,7 +46,6 @@ "chalk": "^5.4.1", "clipboardy": "^4.0.0", "commander": "^14.0.0", - "eslint-plugin-unicorn": "^60.0.0", "execa": "^9.6.0", "fast-glob": "^3.3.3", "globby": "^14.1.0", @@ -79,6 +78,7 @@ "eslint-plugin-jsonc": "^2.20.1", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-simple-import-sort": "^12.1.1", + "eslint-plugin-unicorn": "^61.0.1", "globals": "^16.3.0", "patch-package": "^8.0.0", "rimraf": "^6.0.1", @@ -86,6 +86,9 @@ }, "engines": { "node": ">=18" + }, + "optionalDependencies": { + "@supabase/supabase-js": "^2.57.4" } }, "node_modules/@bcoe/v8-coverage": {