Compare commits
1029 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2eff703e72 | |||
| dd06333732 | |||
| 847e1cc986 | |||
| af29ecc93f | |||
| 52eaddbd8a | |||
| 06d1757038 | |||
| 9900b4f5e4 | |||
| 25ef5dda53 | |||
| 2e1d257f36 | |||
| 4b34751bda | |||
| ba9c2e68f9 | |||
| 86d3e36ace | |||
| 7284317cef | |||
| 1508a5a418 | |||
| 9b55b717e0 | |||
| 8c087fcabc | |||
| 4b8e32830a | |||
| 62ca0ddbe2 | |||
| bcb41f85c9 | |||
| 751f5d5a19 | |||
| 5ab09ffd5a | |||
| 13374a12e9 | |||
| a02597ed59 | |||
| 8a56f0ed4a | |||
| fd7fab4e08 | |||
| e909e3e76c | |||
| 1ebe5b643d | |||
| c0b9a10224 | |||
| 802231c105 | |||
| 0d5085454b | |||
| 6d535951df | |||
| eaf295756e | |||
| 11894c64b3 | |||
| b9e22beecb | |||
| 6f051036d9 | |||
| 3731965537 | |||
| 549e5e3ce8 | |||
| 48bbfcbb2c | |||
| 4cc91d7505 | |||
| 77b0912808 | |||
| 6a00643bfa | |||
| 2e74667cc6 | |||
| d2b653ab10 | |||
| 2c94e6b817 | |||
| a6ac4a6698 | |||
| e7cc8b9552 | |||
| f6290a0e48 | |||
| 6668be3d5b | |||
| cf12148bc7 | |||
| d928ea4a2b | |||
| efd45c0c4d | |||
| 4896d5c66f | |||
| 61a24f011a | |||
| 8d9eb225a8 | |||
| 605558da9d | |||
| dca74a1ec0 | |||
| fb3eef6cf5 | |||
| 10d3209e5a | |||
| aace88d2e7 | |||
| 228eaa16d5 | |||
| f3416aa46a | |||
| eb32fb912d | |||
| 8c4ee7569f | |||
| fbf1d8c372 | |||
| c5d298eec8 | |||
| 078aa66b90 | |||
| d4ffed9822 | |||
| ff7761aaf8 | |||
| f058cda152 | |||
| b6f9054567 | |||
| 5667bc1eab | |||
| 4661d55913 | |||
| 9c52d72dc1 | |||
| 2cd9f94ea6 | |||
| 2b262a65b2 | |||
| bd5ce7c6d2 | |||
| 20c3aee636 | |||
| 721d765921 | |||
| 84eb666618 | |||
| 3f2d5bee34 | |||
| 9341d9f597 | |||
| aacc7c25d3 | |||
| b59fbb0bd2 | |||
| ae7b1a666e | |||
| bf57d253a5 | |||
| c689f94c52 | |||
| ab862d0d40 | |||
| 29178a4c72 | |||
| d107b639b3 | |||
| c09c4926a7 | |||
| 395af18d88 | |||
| ecefb793fc | |||
| c6b9035956 | |||
| 3513a9def6 | |||
| 0d45c61aa3 | |||
| f324462cc3 | |||
| 52bd8fca5c | |||
| c45f14e77d | |||
| 0dbfcbe6d9 | |||
| 23279d4248 | |||
| 68c7355f47 | |||
| aaf8e6e7ff | |||
| 699741c760 | |||
| 2d3dda3a4c | |||
| 61dd5a5ea4 | |||
| 41be228e5c | |||
| 0491854298 | |||
| 44ee48e924 | |||
| 5525c4e6fe | |||
| 3914f4d6ac | |||
| 8511eca03b | |||
| 56ceecb4e3 | |||
| db5cb1986a | |||
| 6102aa76bb | |||
| fc88cae628 | |||
| 8c3c9e1520 | |||
| 55c54beeab | |||
| 0a78cb9f7a | |||
| 3502344e89 | |||
| 30edf49aaf | |||
| 5b9be679a8 | |||
| 8e2f7f2bfb | |||
| dc5a26fe95 | |||
| d66654bf67 | |||
| 959f4bb059 | |||
| f9634b4bf3 | |||
| 47a8e677e9 | |||
| f40a2e7603 | |||
| ac7b7aa20a | |||
| 5eeeb4e38c | |||
| db835cdcb8 | |||
| e3aca7026b | |||
| 3bd49b57cc | |||
| 5b9b65c395 | |||
| bbddb98aca | |||
| b081e43b8d | |||
| 58f29d8781 | |||
| f01e8a083e | |||
| 7170edd13f | |||
| bf0cf2d9c4 | |||
| 51c4f2aae8 | |||
| a972d2fb07 | |||
| 6a54d27286 | |||
| d32ae1a0b1 | |||
| 965f7a3735 | |||
| 136b5545ec | |||
| 8099d60e0e | |||
| da2fd1a51a | |||
| 18d069d10c | |||
| 851b665c11 | |||
| c674625e88 | |||
| 23e2ed2163 | |||
| 0b1ca090f5 | |||
| bf3ad37369 | |||
| f21ca9b765 | |||
| d113037a4f | |||
| b2f683f3cc | |||
| 83eb800fb3 | |||
| af8454811c | |||
| 8dbfe28bbb | |||
| 5d53b0c2ca | |||
| 65056311a6 | |||
| d03ba0fc8a | |||
| 9804f078d0 | |||
| c886764b62 | |||
| 2262fadd5b | |||
| 462aaebd6c | |||
| 077d0c47f9 | |||
| ad233034ef | |||
| 9d0932971d | |||
| 822a8acedb | |||
| 28bc4fe05b | |||
| df5b7109f5 | |||
| 4bbbc904b6 | |||
| fee3c27af3 | |||
| deeb4f2250 | |||
| a80796b5ff | |||
| a279ed0694 | |||
| 06d6fe7d76 | |||
| 6057cf5202 | |||
| a94bd11a76 | |||
| e8004537c1 | |||
| c8a47b2f98 | |||
| c545dcf412 | |||
| b80925e857 | |||
| 3fb4f2655b | |||
| 324e17b226 | |||
| b3d6e645b7 | |||
| cb2f86551b | |||
| 4f5a40a84f | |||
| ea86dc1576 | |||
| 7de35b4a68 | |||
| 2d66c23116 | |||
| 515fb86497 | |||
| 8ea12ca24b | |||
| 448a21f617 | |||
| a7f5fb59c3 | |||
| c64e0824da | |||
| 9b7a882d57 | |||
| e3a3a48973 | |||
| 6a9f5341b5 | |||
| e31ca239a0 | |||
| 0e0d0b8fc7 | |||
| 8476ce5d8e | |||
| 047a85711e | |||
| 32ea60a5fc | |||
| 1e39a22c52 | |||
| daa65e7b02 | |||
| eb7a7e09eb | |||
| c0232a7d97 | |||
| a8ba7abb7d | |||
| e35786e567 | |||
| 214a1ddca5 | |||
| 10cbee943c | |||
| aba5bb052d | |||
| a461091ba5 | |||
| 64218db7bd | |||
| 2180b83a8b | |||
| f19dfe70d7 | |||
| 31ef9135e7 | |||
| 5cea47947c | |||
| 883ffd7de0 | |||
| e66f277324 | |||
| 01cfad62b1 | |||
| 6cc4a31e91 | |||
| 629bb5bb63 | |||
| b245309242 | |||
| 464a188662 | |||
| 4aae2b5cca | |||
| 442f6d72d0 | |||
| d1c5c70b4c | |||
| e570888437 | |||
| 38965ab6bf | |||
| 7a2fd70184 | |||
| 388c70789a | |||
| d5b3eda16c | |||
| 8c8f4120f4 | |||
| e190445492 | |||
| 2dcbcdf7a5 | |||
| 0ccb1124bd | |||
| 874c2e96ca | |||
| 4a643a8449 | |||
| 37cacb27ec | |||
| a14a4405db | |||
| 7ba46ec5ec | |||
| 296327793c | |||
| 4af6288adb | |||
| de7ee38e45 | |||
| 9f6ec325fb | |||
| b10ec8c34a | |||
| b6cfd960d1 | |||
| 5aa7bedabe | |||
| 04b4807145 | |||
| 5837991e5c | |||
| 81b4431c9b | |||
| 504a87d799 | |||
| 024089d33e | |||
| 1c46fddce1 | |||
| 784b607613 | |||
| 44aa16a0f8 | |||
| 3eff82082e | |||
| d2f6fce52e | |||
| 419dc6598c | |||
| 51092b0b64 | |||
| 918823d805 | |||
| e287fb9a89 | |||
| ab4f872502 | |||
| 8be831f7ed | |||
| 67c775276f | |||
| 12a4934112 | |||
| b386e24f5d | |||
| 58b6887bf5 | |||
| 2269194662 | |||
| 1290c1bb2e | |||
| c197a5fe93 | |||
| 563a130141 | |||
| 80945df4ca | |||
| 45ae1f0313 | |||
| e585d3c1cc | |||
| abd4ec64eb | |||
| 47afe52296 | |||
| f2ddc573f6 | |||
| 6f42a95aab | |||
| ac6b53ed0a | |||
| c39436ae74 | |||
| 607c689cb0 | |||
| 914feb65a0 | |||
| ab3c9f889d | |||
| bb2efb8b8b | |||
| 9148cce8fc | |||
| cbb2b2991d | |||
| fd1d5e0e2b | |||
| 04b0297ae4 | |||
| ef706ad976 | |||
| d9f09c1819 | |||
| 0773b37197 | |||
| c8a5c6f0e9 | |||
| c7b9498693 | |||
| c27ab0585c | |||
| e913c96926 | |||
| 0c9c5fe9c2 | |||
| 51fd7db205 | |||
| e9136c1aa0 | |||
| a546a9f56a | |||
| 40c9abe484 | |||
| c411dc294e | |||
| fb5a3bfd95 | |||
| 7441f1462d | |||
| c9240e7ca6 | |||
| 1e7618dfa4 | |||
| 4e5d34103f | |||
| da435bc025 | |||
| 2a43aa6902 | |||
| b620f8fae3 | |||
| 03f787d5cb | |||
| 19637804b3 | |||
| 80f145fceb | |||
| 34477d4936 | |||
| 4ec51f2dd6 | |||
| f842a92e25 | |||
| 83e8c97295 | |||
| 1a5d0d236a | |||
| ebbf90f4aa | |||
| 4f119692f1 | |||
| bbe56107fb | |||
| bd654e7aac | |||
| 33500a7ce2 | |||
| 4880557d51 | |||
| ea09b5f7f0 | |||
| 5258fd91ea | |||
| b305d674de | |||
| 7c24601d0f | |||
| 50c0285cb2 | |||
| 0a78198bb5 | |||
| edaeb78ccf | |||
| f80be2d2ea | |||
| 8700165b42 | |||
| 18fb92f1f8 | |||
| 14fc6bbadd | |||
| 5070a1d83e | |||
| 8a9088ea9d | |||
| 48b24f6f12 | |||
| f6ddd5ffc5 | |||
| b43a116b3c | |||
| 50512a5f03 | |||
| e3e107b31d | |||
| 21a04541ea | |||
| cdd5d8ac76 | |||
| 11094f504e | |||
| 5acaae5f56 | |||
| 4547d870af | |||
| dc0d8e0932 | |||
| c558eae9ce | |||
| abb9af66a6 | |||
| 4800e0344c | |||
| 439b425c61 | |||
| 2855f1635b | |||
| 08b67b4a78 | |||
| 1bddd46ed2 | |||
| 6ecdadfd97 | |||
| 4119040005 | |||
| 873eef6ef8 | |||
| 445fed4d3f | |||
| 52fd3e0dd4 | |||
| 8fd0e1f3b0 | |||
| 11fc4a8451 | |||
| e22293294e | |||
| 73e53aaff1 | |||
| 6fa946557f | |||
| fb0852f585 | |||
| 4070fc1bf0 | |||
| 00c1fa1ec7 | |||
| 04e77ef34e | |||
| 827d63d115 | |||
| e0d0f6e94c | |||
| fd07513004 | |||
| b0e436d9c4 | |||
| a4bfd9cfc6 | |||
| 8ca01918e5 | |||
| a5b2381458 | |||
| 26c771503b | |||
| 622ed4a7c9 | |||
| 940f0128d5 | |||
| 1354747ca8 | |||
| 9544c69c55 | |||
| 9ba445e623 | |||
| ebc5e25f98 | |||
| 78301ee63d | |||
| 797dea1dca | |||
| a0ff764f0a | |||
| a795798156 | |||
| 1a66f961f4 | |||
| 6fb2048af0 | |||
| ba9f186fc5 | |||
| 6c32d287b5 | |||
| 536f85b78a | |||
| f8619870ad | |||
| d00a2085d5 | |||
| 85ec61335a | |||
| 9b48a12c27 | |||
| c181ccbe42 | |||
| 8520033d44 | |||
| ebdce87fde | |||
| f2122ed696 | |||
| 3616eaadb4 | |||
| ef69c91b60 | |||
| 117824b32c | |||
| f77f5b996e | |||
| a4d32aec24 | |||
| 9111495fae | |||
| ee1e3f0957 | |||
| 4dc5c7348f | |||
| 4428768eaa | |||
| 11f4ce8fb6 | |||
| 6078738d34 | |||
| faacfeb891 | |||
| 8d7e8b6fb9 | |||
| 7e1d2ffdd7 | |||
| 91044ec591 | |||
| c77a75dfb5 | |||
| 6518c0c06b | |||
| 09cdaff9a2 | |||
| 56bf33ab7f | |||
| 752f638cfc | |||
| 92dd7edb57 | |||
| b4bb4cf053 | |||
| f0400e928a | |||
| aa5ad625af | |||
| f8f69eab03 | |||
| 2b2263acaa | |||
| 5e2e7fb639 | |||
| 6c12bc9044 | |||
| 9a11683003 | |||
| 38b4e06963 | |||
| 0766a44ccf | |||
| 036bf3a161 | |||
| 41bd258b93 | |||
| 38e212c721 | |||
| 2f285ea00a | |||
| d38120c839 | |||
| d94aee812b | |||
| 68d650ec40 | |||
| 769d926f5a | |||
| 9478bab04e | |||
| 7ad4af250f | |||
| 9fa368b114 | |||
| 4afef04f26 | |||
| 8fe2c3effc | |||
| fa78c972be | |||
| 0e66261644 | |||
| 819650a254 | |||
| 34c41c87dc | |||
| 2985b667b0 | |||
| 31bb0e7f0f | |||
| 8f28264aec | |||
| ec4fb11aa5 | |||
| b210723de1 | |||
| 433f99dd78 | |||
| e75c05112e | |||
| d2a5b50ff8 | |||
| 120690afd4 | |||
| 344dbeee42 | |||
| 3fe3b0320a | |||
| 75896b647f | |||
| 446d0975aa | |||
| b7d365119c | |||
| 2d9fbd4e49 | |||
| 22e14b5e65 | |||
| 1a654beea4 | |||
| f50f8a444a | |||
| 3cc3a0058d | |||
| ae473b5e3c | |||
| efb7e31565 | |||
| 069d265338 | |||
| 751a3a4bd1 | |||
| cb0499407e | |||
| 9afc6878c8 | |||
| 0b5b12575a | |||
| d79d30bf0c | |||
| 59600e2a5b | |||
| e572b5a3dc | |||
| 5b46daaee4 | |||
| 2784bae772 | |||
| 325e11f0de | |||
| 7444f59e3c | |||
| affe319460 | |||
| 862ff6cca6 | |||
| c020e65a50 | |||
| f582c1fe25 | |||
| 785929c502 | |||
| 68ec6615b1 | |||
| e2cca61cd3 | |||
| 69e83adae0 | |||
| 9e24aee40d | |||
| 3cff5e9898 | |||
| f3553040bc | |||
| 2b13984e11 | |||
| 0de9491c61 | |||
| c9df7a2020 | |||
| a7222e8c50 | |||
| 0373fa231c | |||
| 5f653e69ae | |||
| 2496ed133e | |||
| 62c0c52e31 | |||
| e36198dcc2 | |||
| 5fa6221f91 | |||
| f7696d1dc1 | |||
| 1878f8d4fc | |||
| 6c69ddef9b | |||
| 0c45020d81 | |||
| 4dfce44c1a | |||
| 1b661bb2fd | |||
| 73e726f6e3 | |||
| f58bbeffce | |||
| 99261e5fb5 | |||
| b4a59d1bd5 | |||
| 5c1f78879f | |||
| 94ba82f2a2 | |||
| b4ec14382b | |||
| 38ad57a22c | |||
| 60bbc180ba | |||
| a67d902b85 | |||
| ae2e9cb890 | |||
| 1976d38b25 | |||
| f5e3410e9a | |||
| 2f6ba642c7 | |||
| dd9b72dc62 | |||
| dd258c14b5 | |||
| 295cd3fac6 | |||
| c62663f2e4 | |||
| 367d6b70e2 | |||
| 27236bd1b2 | |||
| 6a82eb4287 | |||
| bd88fe3980 | |||
| 4f70fea6df | |||
| aee5bbb44b | |||
| a304ded500 | |||
| a54dde0509 | |||
| 52b4577d3b | |||
| e199f57279 | |||
| dec12b33a6 | |||
| 04daa1b206 | |||
| a7e1520d08 | |||
| 9e2b232c13 | |||
| 404e73af77 | |||
| a544b4d3ff | |||
| 6df63d9ca7 | |||
| 904baac153 | |||
| a926bcc640 | |||
| c0aafd38c9 | |||
| 19d80914df | |||
| d9d529987e | |||
| 12e6eaf802 | |||
| 7a026ea282 | |||
| 97dc90169b | |||
| 64c02f374a | |||
| 6c1ea7799e | |||
| 6be29f5bed | |||
| 68737da7a2 | |||
| da388b679f | |||
| 11f0d719f5 | |||
| e90673ae5b | |||
| f055028c6b | |||
| 106a338371 | |||
| 9fe80c5cca | |||
| 050706e95e | |||
| 6d2389de1c | |||
| dd97fad5a4 | |||
| 0f73ba9677 | |||
| 210fe9bb80 | |||
| ec8549d0e1 | |||
| b77d9d750f | |||
| a10823d309 | |||
| 3a09c2bd62 | |||
| a1394ce32e | |||
| 1020a4121f | |||
| 737837ae0b | |||
| 7ee2d0653b | |||
| 43926fb527 | |||
| 7bcc9e35dd | |||
| 6437661837 | |||
| b5f84f27ff | |||
| 48c38b5dc3 | |||
| b4f3bbbbc9 | |||
| 3cd50c4cd9 | |||
| cd2c40a9c4 | |||
| 33dcfe42b5 | |||
| db37b2ac15 | |||
| bee4e834b1 | |||
| 0272459435 | |||
| c0b5e93967 | |||
| 6983ebba49 | |||
| 9943d1e015 | |||
| b348251484 | |||
| e719b5bac3 | |||
| 54f43215cd | |||
| b246d9823e | |||
| 65c8dd445b | |||
| 0efbc80ac9 | |||
| 151746beec | |||
| c0ee680546 | |||
| 9303a1bf81 | |||
| d54cdc5b00 | |||
| b7a44ef472 | |||
| ae6f866901 | |||
| 7910cee259 | |||
| d66e647f99 | |||
| ff4a333be7 | |||
| 111749a95d | |||
| adde398b65 | |||
| d8897ce356 | |||
| 0ea8ab228c | |||
| d62a23edf6 | |||
| 51ebf3439b | |||
| 4a5ed1dd8d | |||
| e84b5034ea | |||
| a4831d6ed9 | |||
| 51b4966801 | |||
| 1d4e00ccef | |||
| c9fbc2e7d6 | |||
| fa34788df6 | |||
| 0f4f220119 | |||
| 512cfc9466 | |||
| 541b1cb7c7 | |||
| 36af1a7615 | |||
| b02e8feeda | |||
| 406c46e7f4 | |||
| e35eaf1bfc | |||
| 38426a7af1 | |||
| 141a23fb1e | |||
| bb28569abf | |||
| 1df46b2bb3 | |||
| 58f72e1ffe | |||
| 33409140b4 | |||
| f6b80e01a1 | |||
| 798d3fcc5a | |||
| 85f3ac428b | |||
| 9fcf2130b5 | |||
| 51df00729e | |||
| 023a61446f | |||
| e0b73e6a5a | |||
| 28460f725c | |||
| c93e49d2b8 | |||
| 07fb6bee54 | |||
| 3fa7db8420 | |||
| c14bd7b73b | |||
| 5201beaab0 | |||
| 122313d8a5 | |||
| 82fd595306 | |||
| 95c0d47236 | |||
| 919cc74e94 | |||
| d839991acb | |||
| 539286aafd | |||
| 23522b7b55 | |||
| bf3fac56e4 | |||
| a5bf8e9075 | |||
| 1d31b8f7e4 | |||
| b144c7dccc | |||
| 1364975396 | |||
| deaa7f50f8 | |||
| 744ab5156f | |||
| c45413969a | |||
| b314e5e080 | |||
| 17129e2eaa | |||
| 654fd8d74c | |||
| 9d3568ef75 | |||
| 14712cac88 | |||
| 0d568c758b | |||
| 7c6b88c7c5 | |||
| 32c93be46e | |||
| 7de8d85199 | |||
| f7dd65a3de | |||
| d8cdbe0041 | |||
| 2b8b6d3ea9 | |||
| 936c7e389f | |||
| 6864b4207b | |||
| 98eb5b54be | |||
| 3332e6e236 | |||
| 0533da72d7 | |||
| a1de238716 | |||
| f0d112254b | |||
| 830a7397ef | |||
| 5428765329 | |||
| 23c912f2b7 | |||
| 9c4b023297 | |||
| 53037b5ed8 | |||
| e2546a653d | |||
| 4b8cada873 | |||
| fa3ca1d08a | |||
| 8dd5cb9602 | |||
| a054f7be9c | |||
| df314dc6d1 | |||
| 930280f4ce | |||
| 5022c1ae29 | |||
| 6ced756a6b | |||
| b17268db50 | |||
| 476da37009 | |||
| 455f059c6f | |||
| 5255a37c93 | |||
| 68dc274f72 | |||
| 30228f7f8e | |||
| e15ef79ca9 | |||
| bc012a7518 | |||
| 3b4409cfad | |||
| d3726134b2 | |||
| 5acb7f1c55 | |||
| 81336668b3 | |||
| 35c2b83015 | |||
| cc1ee1deaa | |||
| 29bd038579 | |||
| f6c4f86986 | |||
| 68183e9dce | |||
| 78ec91a3a9 | |||
| c95d458e52 | |||
| 191ae3ec1e | |||
| ab9598d00a | |||
| 0f8a2e624a | |||
| d77e8da3f3 | |||
| a27eeb3255 | |||
| 413ccb83e6 | |||
| 797bb567c6 | |||
| f2a5dc40ee | |||
| 3979480532 | |||
| 76f1993e7a | |||
| d783fa2b89 | |||
| bbce18caac | |||
| 3ce2d8a656 | |||
| a5c86a2f5c | |||
| d18e533adf | |||
| 2b881aaad0 | |||
| 39cc07608f | |||
| 9894cfcced | |||
| b5d80be037 | |||
| b7870fbd9b | |||
| 36e6d486fc | |||
| 2d5dc84f1a | |||
| b47405e1bd | |||
| 8b64deab40 | |||
| c8846e0e93 | |||
| 7641cba01d | |||
| 4dc1785ef1 | |||
| b2286f3e34 | |||
| 65a20aa457 | |||
| d8a7d71344 | |||
| bb490df9a6 | |||
| cdfd6519c8 | |||
| e8a2846449 | |||
| d065cbf934 | |||
| 413b107b9a | |||
| c336292346 | |||
| adf50f1e81 | |||
| 636bc0a99d | |||
| a7a61fae1d | |||
| 5ec12212e4 | |||
| 77c90a308e | |||
| 4a8c50f886 | |||
| a86d7f52e9 | |||
| 4820ea15d6 | |||
| b5de605e2b | |||
| d6ed2050d4 | |||
| 16e123b7bb | |||
| 4eb91683a9 | |||
| 0cb78b9067 | |||
| e226a89637 | |||
| 431f8c2c6a | |||
| 19a9141c2d | |||
| bc649b9a85 | |||
| 702067e521 | |||
| 03a84daf9d | |||
| b91d922600 | |||
| ed02aebf9a | |||
| 1a048390fd | |||
| 1741d3bef6 | |||
| 540a0a3685 | |||
| d2fd3ce434 | |||
| ea76868d65 | |||
| f31351bedb | |||
| 8863983c7b | |||
| 64a34cac32 | |||
| 352e71461d | |||
| 87d0b5c76f | |||
| d0af018b8d | |||
| 55e9a1cbd6 | |||
| 65bafb75b1 | |||
| 01fd1c2437 | |||
| 78ba4468b0 | |||
| 8581c7ecce | |||
| 9be6fe6bc3 | |||
| 8c506da21e | |||
| c02002eb4b | |||
| 57ecfca862 | |||
| 28d41e9397 | |||
| 7a1866d280 | |||
| d229b108c3 | |||
| 39640cb697 | |||
| 9ecf2e9feb | |||
| 2db07cdb1f | |||
| faa29ef285 | |||
| 16b0d5b829 | |||
| 6ae33d04b8 | |||
| 333eb8d60f | |||
| 414c69fd62 | |||
| 9951b58005 | |||
| e73ed82ae9 | |||
| 8bde34a24f | |||
| b58380e505 | |||
| 16f8de810c | |||
| 70f2de4fd3 | |||
| a5d5e5825f | |||
| 0f16c72762 | |||
| 9ca7a0d6d1 | |||
| 7d5bfd8c9f | |||
| cc9a06b116 | |||
| b8fc7b0c9e | |||
| 3999f2a373 | |||
| 4eb2c0e123 | |||
| b8a838aee1 | |||
| 84e5932ea5 | |||
| e41573ca74 | |||
| 4c5c99e6ae | |||
| dcb940ba95 | |||
| 8d3b66f7e3 | |||
| bc89b6ea74 | |||
| f0742dffa2 | |||
| 6c71a1020d | |||
| 1db3e43adf | |||
| cb59b0b5e4 | |||
| 8e0f05055e | |||
| 4768bacf1c | |||
| dc206c0999 | |||
| 77e1983b2e | |||
| d344ee226c | |||
| 3d0e4141bf | |||
| 01fb216ff7 | |||
| a662b2a6c6 | |||
| b1af82eba8 | |||
| 378ef5246e | |||
| 606814f10e | |||
| 5e06a0d001 | |||
| c0e3274375 | |||
| 119ec5e405 | |||
| 79efa51941 | |||
| 701d0b21ef | |||
| 0f23d5f967 | |||
| 36b26e08c3 | |||
| ac08638a63 | |||
| 03146946fa | |||
| 0f9a10c598 | |||
| 2bd6881361 | |||
| ba208f5b48 | |||
| bdef85f7db | |||
| 2cb47938fd | |||
| dfe0b414ac | |||
| 1864f4cb38 | |||
| 7c39d9f0c1 | |||
| 79f5a1d052 | |||
| 6fed75bb45 | |||
| 352ed3b6a1 | |||
| b37691711c | |||
| 13fda2efe1 | |||
| 3c3d98b9c3 | |||
| f582d70031 | |||
| 1ac8aef4de | |||
| 4754372fcd | |||
| eac85779eb | |||
| b0d8711b65 | |||
| f0844ed923 | |||
| 129242534d | |||
| 6481b555b4 | |||
| 794e51494e | |||
| 3059e96041 | |||
| bd595f84e8 | |||
| 344e7470f6 | |||
| 387b042a49 | |||
| b3837572be | |||
| d4e6462e4d | |||
| 60d5daaaf5 | |||
| 3e66ddf69a | |||
| 202fd2d5b6 | |||
| eecdbc5e06 | |||
| 433c4157e0 | |||
| 8be8990507 | |||
| 2cfeb5ed80 | |||
| 0d4ad07d7b | |||
| 2aa25a5169 | |||
| c07fbc07b1 | |||
| 12eb16d60b | |||
| ec9f454ad1 | |||
| 9f1f17a611 | |||
| 94369657ef | |||
| 490d7db601 | |||
| ea18b80f90 | |||
| 70077f4e46 | |||
| 85106c7c7e | |||
| 1b19d0d19c | |||
| 13f01e399c | |||
| 261e2d088c | |||
| b0ae3e95c7 | |||
| fc633dadeb | |||
| aafb334916 | |||
| 04d851e802 | |||
| de31c63dac | |||
| c068f58543 | |||
| 70df373807 | |||
| 4388f6bfc2 | |||
| d0956a0dc1 | |||
| ccf515cadd | |||
| a6e4235bb0 | |||
| 9ba408086e | |||
| bbb3bca1c7 | |||
| 564036a166 | |||
| abf99ce5ea | |||
| f0f5c34acb | |||
| ed319531bf | |||
| d8d0e0e5d1 | |||
| 27c91bbd2d | |||
| f76d9740c6 | |||
| f29443a0fc | |||
| 35b022d6bc | |||
| 0dd1faf57f | |||
| b57f096b27 | |||
| 4c8876f032 | |||
| f92e890aa1 | |||
| 849de5e8ab | |||
| 7585bc557b | |||
| 4021d93168 | |||
| 28e06be26f | |||
| 39861ec1e8 | |||
| e3ae84b80d | |||
| 09c02954ba | |||
| 66b661660b | |||
| c26559a2d3 | |||
| c5da46f8b0 | |||
| 0b72269e18 | |||
| a232d1b779 | |||
| 3cab4415b7 | |||
| d494d99c06 | |||
| 163f437582 | |||
| 1e0d967bb5 | |||
| a86deb2675 | |||
| d51c508b40 | |||
| af8b3081fa | |||
| 1dbe7daac1 | |||
| e56f91a239 | |||
| 0179141b2e | |||
| f0abfea55d | |||
| 77e223be52 | |||
| c96df72cd0 | |||
| ce6eb39009 | |||
| eeac84e2d9 | |||
| 1ee1e671d1 | |||
| 2ef7c0b736 | |||
| f2b563e42a | |||
| 7a718643a3 | |||
| 1f0f0c93b7 | |||
| 030e3521a9 | |||
| fdf5d1928d | |||
| 65011a67d4 | |||
| ec09a8a6fc | |||
| 5e94980aaa | |||
| 8b619756b6 | |||
| 35b43edb20 | |||
| 02cbde2fc1 | |||
| a868fce036 | |||
| 079e35b205 | |||
| 8c91b75b98 | |||
| 55bfd7cafe | |||
| a8552686b4 | |||
| 12a2f78dcb | |||
| cce6d5ddab | |||
| 088346c4fc | |||
| 7fa7b9e199 | |||
| cac15c147f | |||
| c54dd1e7bb | |||
| c9c56a4b26 | |||
| acbdb800d3 | |||
| 49711c92b7 | |||
| c4797eb121 | |||
| bea4e9e6d1 | |||
| 9687ec2c1a | |||
| 09da4a3002 | |||
| 93004306f2 | |||
| aed894246f | |||
| fa63a16591 | |||
| 40643663cb | |||
| d590e4423b | |||
| cdbf75e0ec | |||
| 8216e05784 | |||
| 2d4c51aa16 | |||
| cc43846d42 | |||
| 3bdec3b71a | |||
| a22a435690 | |||
| a681d47bce | |||
| 4bb06147c1 | |||
| 6b61b7e9c1 | |||
| 91033c7221 | |||
| ab9f005885 | |||
| 3da5724853 | |||
| c12362486f | |||
| d16eafae05 | |||
| bb1fbba161 | |||
| adb7206639 | |||
| 96143ac496 | |||
| 1df804e7df | |||
| 0ea278f633 | |||
| 7ed46260b3 | |||
| 9c58627372 | |||
| 07ba65d88d | |||
| cf9638e7b2 | |||
| a548863a09 | |||
| d5e40e1853 | |||
| a4708b3b86 | |||
| 81c8cc62a2 | |||
| e8b3d53faf | |||
| 2889799f10 | |||
| e24063caff | |||
| c595003481 | |||
| 05a4eef6ae | |||
| ac68986404 | |||
| 3f71050c47 | |||
| d12aeec1ff | |||
| addf1c0666 | |||
| d4b8542207 | |||
| fd97fb268a | |||
| 4f722621fd | |||
| 8ad6a5b5e7 | |||
| 2d6e860175 | |||
| 86e4146126 | |||
| cd0c7bc971 |
@@ -0,0 +1,41 @@
|
||||
name: 🐛 Bug Report
|
||||
description: Create a report to help us reproduce and fix the bug
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
#### Before submitting a bug, please make sure the issue hasn't been already addressed by searching through [the existing and past issues](https://github.com/embedchain/embedchain/issues?q=is%3Aissue+sort%3Acreated-desc+).
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 🐛 Describe the bug
|
||||
description: |
|
||||
Please provide a clear and concise description of what the bug is.
|
||||
|
||||
If relevant, add a minimal example so that we can reproduce the error by running the code. It is very important for the snippet to be as succinct (minimal) as possible, so please take time to trim down any irrelevant code to help us debug efficiently. We are going to copy-paste your code and we expect to get the same result as you did: avoid any external data, and include the relevant imports, etc. For example:
|
||||
|
||||
```python
|
||||
# All necessary imports at the beginning
|
||||
import embedchain as ec
|
||||
# Your code goes here
|
||||
|
||||
|
||||
```
|
||||
|
||||
Please also paste or describe the results you observe instead of the expected results. If you observe an error, please paste the error message including the **full** traceback of the exception. It may be relevant to wrap error messages in ```` ```triple quotes blocks``` ````.
|
||||
placeholder: |
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
```python
|
||||
Sample code to reproduce the problem
|
||||
```
|
||||
|
||||
```
|
||||
The error message you got, with the full traceback.
|
||||
````
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
Thanks for contributing 🎉!
|
||||
@@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: 1-on-1 Session
|
||||
url: https://cal.com/taranjeetio/ec
|
||||
about: Speak directly with Taranjeet, the founder, to discuss issues, share feedback, or explore improvements for Embedchain
|
||||
- name: Discord
|
||||
url: https://discord.gg/6PzXDgEjG5
|
||||
about: General community discussions
|
||||
@@ -0,0 +1,11 @@
|
||||
name: Documentation
|
||||
description: Report an issue related to the Embedchain docs.
|
||||
title: "DOC: <Please write a comprehensive title after the 'DOC: ' prefix>"
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Issue with current documentation:"
|
||||
description: >
|
||||
Please make sure to leave a reference to the document/code you're
|
||||
referring to.
|
||||
@@ -0,0 +1,23 @@
|
||||
name: 🚀 Feature request
|
||||
description: Submit a proposal/request for a new Embedchain feature
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
id: feature-request
|
||||
attributes:
|
||||
label: 🚀 The feature
|
||||
description: >
|
||||
A clear and concise description of the feature proposal
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Motivation, pitch
|
||||
description: >
|
||||
Please outline the motivation for the proposal. Is your feature request related to a specific problem? e.g., *"I'm working on X and would like Y to be possible"*. If this is related to another GitHub issue, please link here too.
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
Thanks for contributing 🎉!
|
||||
@@ -0,0 +1,41 @@
|
||||
## Description
|
||||
|
||||
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
|
||||
|
||||
Fixes # (issue)
|
||||
|
||||
## Type of change
|
||||
|
||||
Please delete options that are not relevant.
|
||||
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] Refactor (does not change functionality, e.g. code style improvements, linting)
|
||||
- [ ] Documentation update
|
||||
|
||||
## How Has This Been Tested?
|
||||
|
||||
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
|
||||
|
||||
Please delete options that are not relevant.
|
||||
|
||||
- [ ] Unit Test
|
||||
- [ ] Test Script (please provide)
|
||||
|
||||
## Checklist:
|
||||
|
||||
- [ ] My code follows the style guidelines of this project
|
||||
- [ ] I have performed a self-review of my own code
|
||||
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||
- [ ] I have made corresponding changes to the documentation
|
||||
- [ ] My changes generate no new warnings
|
||||
- [ ] I have added tests that prove my fix is effective or that my feature works
|
||||
- [ ] New and existing unit tests pass locally with my changes
|
||||
- [ ] Any dependent changes have been merged and published in downstream modules
|
||||
- [ ] I have checked my code and corrected any misspellings
|
||||
|
||||
## Maintainer Checklist
|
||||
|
||||
- [ ] closes #xxxx (Replace xxxx with the GitHub issue number)
|
||||
- [ ] Made sure Checks passed
|
||||
@@ -0,0 +1,46 @@
|
||||
name: Publish Python 🐍 distributions 📦 to PyPI and TestPyPI
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
build-n-publish:
|
||||
name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Install Poetry
|
||||
run: |
|
||||
curl -sSL https://install.python-poetry.org | python3 -
|
||||
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd embedchain
|
||||
poetry install
|
||||
|
||||
- name: Build a binary wheel and a source tarball
|
||||
run: |
|
||||
cd embedchain
|
||||
poetry build
|
||||
|
||||
- name: Publish distribution 📦 to Test PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
repository_url: https://test.pypi.org/legacy/
|
||||
packages_dir: embedchain/dist/
|
||||
|
||||
- name: Publish distribution 📦 to PyPI
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
packages_dir: embedchain/dist/
|
||||
@@ -0,0 +1,102 @@
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'mem0/**'
|
||||
- 'tests/**'
|
||||
- 'embedchain/**'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'mem0/**'
|
||||
- 'tests/**'
|
||||
- 'embedchain/**'
|
||||
|
||||
jobs:
|
||||
check_changes:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
mem0_changed: ${{ steps.filter.outputs.mem0 }}
|
||||
embedchain_changed: ${{ steps.filter.outputs.embedchain }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: dorny/paths-filter@v2
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
mem0:
|
||||
- 'mem0/**'
|
||||
- 'tests/**'
|
||||
embedchain:
|
||||
- 'embedchain/**'
|
||||
|
||||
build_mem0:
|
||||
needs: check_changes
|
||||
if: needs.check_changes.outputs.mem0_changed == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.10", "3.11"]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install poetry
|
||||
uses: snok/install-poetry@v1
|
||||
with:
|
||||
version: 1.4.2
|
||||
virtualenvs-create: true
|
||||
virtualenvs-in-project: true
|
||||
- name: Load cached venv
|
||||
id: cached-poetry-dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: .venv
|
||||
key: venv-mem0-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
|
||||
- name: Install dependencies
|
||||
run: make install_all
|
||||
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
|
||||
- name: Run tests and generate coverage report
|
||||
run: make test
|
||||
|
||||
build_embedchain:
|
||||
needs: check_changes
|
||||
if: needs.check_changes.outputs.embedchain_changed == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.9", "3.10", "3.11"]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install poetry
|
||||
uses: snok/install-poetry@v1
|
||||
with:
|
||||
version: 1.4.2
|
||||
virtualenvs-create: true
|
||||
virtualenvs-in-project: true
|
||||
- name: Load cached venv
|
||||
id: cached-poetry-dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: .venv
|
||||
key: venv-embedchain-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
|
||||
- name: Install dependencies
|
||||
run: cd embedchain && make install_all
|
||||
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
|
||||
- name: Lint with ruff
|
||||
run: cd embedchain && make lint
|
||||
- name: Run tests and generate coverage report
|
||||
run: cd embedchain && make coverage
|
||||
- name: Upload coverage reports to Codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
file: coverage.xml
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
+21
-3
@@ -76,7 +76,6 @@ docs/_build/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
@@ -104,7 +103,7 @@ ipython_config.py
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended not to include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
@@ -165,5 +164,24 @@ cython_debug/
|
||||
|
||||
# Database
|
||||
db
|
||||
test-db
|
||||
!embedchain/embedchain/core/db/
|
||||
|
||||
.vscode
|
||||
.vscode
|
||||
.idea/
|
||||
|
||||
.DS_Store
|
||||
|
||||
notebooks/*.yaml
|
||||
.ipynb_checkpoints/
|
||||
|
||||
!configs/*.yaml
|
||||
|
||||
# cache db
|
||||
*.db
|
||||
|
||||
# local directories for testing
|
||||
eval/
|
||||
qdrant_storage/
|
||||
.crossnote
|
||||
testing.ipynb
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
repos:
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: ruff
|
||||
name: Ruff
|
||||
entry: ruff check
|
||||
language: system
|
||||
types: [python]
|
||||
args: [--fix]
|
||||
|
||||
- id: isort
|
||||
name: isort
|
||||
entry: isort
|
||||
language: system
|
||||
types: [python]
|
||||
args: ["--profile", "black"]
|
||||
@@ -0,0 +1,55 @@
|
||||
# Contributing to mem0
|
||||
|
||||
Let us make contribution easy, collaborative and fun.
|
||||
|
||||
## Submit your Contribution through PR
|
||||
|
||||
To make a contribution, follow these steps:
|
||||
|
||||
1. Fork and clone this repository
|
||||
2. Do the changes on your fork with dedicated feature branch `feature/f1`
|
||||
3. If you modified the code (new feature or bug-fix), please add tests for it
|
||||
4. Include proper documentation / docstring and examples to run the feature
|
||||
5. Ensure that all tests pass
|
||||
6. Submit a pull request
|
||||
|
||||
For more details about pull requests, please read [GitHub's guides](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request).
|
||||
|
||||
|
||||
### 📦 Package manager
|
||||
|
||||
We use `poetry` as our package manager. You can install poetry by following the instructions [here](https://python-poetry.org/docs/#installation).
|
||||
|
||||
Please DO NOT use pip or conda to install the dependencies. Instead, use poetry:
|
||||
|
||||
```bash
|
||||
make install_all
|
||||
|
||||
#activate
|
||||
|
||||
poetry shell
|
||||
```
|
||||
|
||||
### 📌 Pre-commit
|
||||
|
||||
To ensure our standards, make sure to install pre-commit before starting to contribute.
|
||||
|
||||
```bash
|
||||
pre-commit install
|
||||
```
|
||||
|
||||
### 🧪 Testing
|
||||
|
||||
We use `pytest` to test our code. You can run the tests by running the following command:
|
||||
|
||||
```bash
|
||||
poetry run pytest tests
|
||||
|
||||
# or
|
||||
|
||||
make test
|
||||
```
|
||||
|
||||
Several packages have been removed from Poetry to make the package lighter. Therefore, it is recommended to run `make install_all` to install the remaining packages and ensure all tests pass. Make sure that all tests pass before submitting a pull request.
|
||||
|
||||
We look forward to your pull requests and can't wait to see your contributions!
|
||||
@@ -1,24 +1,43 @@
|
||||
# Variables
|
||||
PYTHON := python3
|
||||
PIP := $(PYTHON) -m pip
|
||||
PROJECT_NAME := embedchain
|
||||
.PHONY: format sort lint
|
||||
|
||||
# Targets
|
||||
.PHONY: install format lint clean test
|
||||
# Variables
|
||||
ISORT_OPTIONS = --profile black
|
||||
PROJECT_NAME := mem0ai
|
||||
|
||||
# Default target
|
||||
all: format sort lint
|
||||
|
||||
install:
|
||||
$(PIP) install --upgrade pip
|
||||
$(PIP) install -e .[dev]
|
||||
poetry install
|
||||
|
||||
install_all:
|
||||
poetry install
|
||||
poetry run pip install groq together boto3 litellm ollama chromadb sentence_transformers vertexai \
|
||||
google-generativeai
|
||||
|
||||
# Format code with ruff
|
||||
format:
|
||||
$(PYTHON) -m black .
|
||||
$(PYTHON) -m isort .
|
||||
poetry run ruff format mem0/
|
||||
|
||||
# Sort imports with isort
|
||||
sort:
|
||||
poetry run isort mem0/
|
||||
|
||||
# Lint code with ruff
|
||||
lint:
|
||||
$(PYTHON) -m ruff .
|
||||
poetry run ruff check mem0/
|
||||
|
||||
docs:
|
||||
cd docs && mintlify dev
|
||||
|
||||
build:
|
||||
poetry build
|
||||
|
||||
publish:
|
||||
poetry publish
|
||||
|
||||
clean:
|
||||
rm -rf dist build *.egg-info
|
||||
poetry run rm -rf dist
|
||||
|
||||
test:
|
||||
$(PYTHON) -m pytest
|
||||
poetry run pytest tests
|
||||
|
||||
@@ -1,635 +1,218 @@
|
||||
# embedchain
|
||||
<p align="center">
|
||||
<a href="https://github.com/mem0ai/mem0">
|
||||
<img src="docs/images/banner-sm.png" width="800px" alt="Mem0 - The Memory Layer for Personalized AI">
|
||||
</a>
|
||||
<p align="center"><a href=https://www.ycombinator.com/launches/LpA-mem0-open-source-memory-layer-for-ai-apps target='_blank'><img alt=Launch YC: Mem0 - Open Source Memory Layer for AI Apps src=https://www.ycombinator.com/launches/LpA-mem0-open-source-memory-layer-for-ai-apps/upvote_embed.svg/></a></p>
|
||||
|
||||
[](https://pypi.org/project/embedchain/)
|
||||
[](https://discord.gg/6PzXDgEjG5)
|
||||
[](https://twitter.com/embedchain)
|
||||
[](https://embedchain.substack.com/)
|
||||
|
||||
embedchain is a framework to easily create LLM powered bots over any dataset. If you want a javascript version, check out [embedchain-js](https://github.com/embedchain/embedchainjs)
|
||||
<p align="center">
|
||||
<a href="https://mem0.ai">Learn more</a>
|
||||
·
|
||||
<a href="https://mem0.dev/DiG">Join Discord</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
# Table of Contents
|
||||
<p align="center">
|
||||
<a href="https://mem0.dev/DiG">
|
||||
<img src="https://dcbadge.vercel.app/api/server/6PzXDgEjG5?style=flat" alt="Mem0 Discord">
|
||||
</a>
|
||||
<a href="https://pepy.tech/project/mem0ai">
|
||||
<img src="https://img.shields.io/pypi/dm/mem0ai" alt="Mem0 PyPI - Downloads" >
|
||||
</a>
|
||||
<a href="https://pypi.org/project/mem0ai" target="_blank">
|
||||
<img src="https://img.shields.io/pypi/v/mem0ai?color=%2334D058&label=pypi%20package" alt="Package version">
|
||||
</a>
|
||||
<a href="https://www.npmjs.com/package/mem0ai" target="_blank">
|
||||
<img src="https://img.shields.io/npm/v/mem0ai" alt="Npm package">
|
||||
</a>
|
||||
<a href="https://www.ycombinator.com/companies/mem0">
|
||||
<img src="https://img.shields.io/badge/Y%20Combinator-S24-orange?style=flat-square" alt="Y Combinator S24">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
- [Latest Updates](#latest-updates)
|
||||
- [What is embedchain?](#what-is-embedchain)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Installation](#installation)
|
||||
- [Usage](#usage)
|
||||
- [App Types](#app-types)
|
||||
- [1. App (uses OpenAI models, paid)](#1-app-uses-openai-models-paid)
|
||||
- [2. OpenSourceApp (uses opensource models, free)](#2-opensourceapp-uses-opensource-models-free)
|
||||
- [3. PersonApp (uses OpenAI models, paid)](#3-personapp-uses-openai-models-paid)
|
||||
- [Add Dataset](#add-dataset)
|
||||
- [Interface Types](#interface-types)
|
||||
- [Query Interface](#query-interface)
|
||||
- [Chat Interface](#chat-interface)
|
||||
- [Format supported](#format-supported)
|
||||
- [Youtube Video](#youtube-video)
|
||||
- [PDF File](#pdf-file)
|
||||
- [Web Page](#web-page)
|
||||
- [Doc File](#doc-file)
|
||||
- [Text](#text)
|
||||
- [QnA Pair](#qna-pair)
|
||||
- [Reusing a Vector DB](#reusing-a-vector-db)
|
||||
- [More Formats coming soon](#more-formats-coming-soon)
|
||||
- [Testing](#testing)
|
||||
- [Advanced](#advanced)
|
||||
- [Configuration](#configuration)
|
||||
- [Example](#example)
|
||||
- [Configs](#configs)
|
||||
- [InitConfig](#initconfig)
|
||||
- [Add Config](#add-config)
|
||||
- [Query Config](#query-config)
|
||||
- [Chat Config](#chat-config)
|
||||
- [Other methods](#other-methods)
|
||||
- [Reset](#reset)
|
||||
- [Count](#count)
|
||||
- [How does it work?](#how-does-it-work)
|
||||
- [Contribution Guidelines](#contribution-guidelines)
|
||||
- [Tech Stack](#tech-stack)
|
||||
- [Team](#team)
|
||||
- [Author](#author)
|
||||
- [Maintainer](#maintainer)
|
||||
- [Citation](#citation)
|
||||
|
||||
# Latest Updates
|
||||
# Introduction
|
||||
|
||||
- Introduce a new interface called `chat`. It remembers the history (last 5 messages) and can be used to powerful stateful bots. You can use it by calling `.chat` on any app instance. Works for both OpenAI and OpenSourceApp.
|
||||
[Mem0](https://mem0.ai) (pronounced as "mem-zero") enhances AI assistants and agents with an intelligent memory layer, enabling personalized AI interactions. Mem0 remembers user preferences, adapts to individual needs, and continuously improves over time, making it ideal for customer support chatbots, AI assistants, and autonomous systems.
|
||||
|
||||
- Introduce a new app type called `OpenSourceApp`. It uses `gpt4all` as the LLM and `sentence transformers` all-MiniLM-L6-v2 as the embedding model. If you use this app, you dont have to pay for anything.
|
||||
<!-- Start of Selection -->
|
||||
<p style="display: flex;">
|
||||
<span style="font-size: 1.2em;">New Feature: Introducing Graph Memory. Check out our <a href="https://docs.mem0.ai/open-source/graph-memory" target="_blank">documentation</a>.</span>
|
||||
</p>
|
||||
<!-- End of Selection -->
|
||||
|
||||
# What is embedchain?
|
||||
|
||||
Embedchain abstracts the entire process of loading a dataset, chunking it, creating embeddings and then storing in a vector database.
|
||||
### Core Features
|
||||
|
||||
You can add a single or multiple dataset using `.add` and `.add_local` function and then use `.query` function to find an answer from the added datasets.
|
||||
- **Multi-Level Memory**: User, Session, and AI Agent memory retention
|
||||
- **Adaptive Personalization**: Continuous improvement based on interactions
|
||||
- **Developer-Friendly API**: Simple integration into various applications
|
||||
- **Cross-Platform Consistency**: Uniform behavior across devices
|
||||
- **Managed Service**: Hassle-free hosted solution
|
||||
|
||||
If you want to create a Naval Ravikant bot which has 1 youtube video, 1 book as pdf and 2 of his blog posts, as well as a question and answer pair you supply, all you need to do is add the links to the videos, pdf and blog posts and the QnA pair and embedchain will create a bot for you.
|
||||
### How Mem0 works?
|
||||
|
||||
```python
|
||||
Mem0 leverages a hybrid database approach to manage and retrieve long-term memories for AI agents and assistants. Each memory is associated with a unique identifier, such as a user ID or agent ID, allowing Mem0 to organize and access memories specific to an individual or context.
|
||||
|
||||
from embedchain import App
|
||||
When a message is added to the Mem0 using add() method, the system extracts relevant facts and preferences and stores it across data stores: a vector database, a key-value database, and a graph database. This hybrid approach ensures that different types of information are stored in the most efficient manner, making subsequent searches quick and effective.
|
||||
|
||||
naval_chat_bot = App()
|
||||
When an AI agent or LLM needs to recall memories, it uses the search() method. Mem0 then performs search across these data stores, retrieving relevant information from each source. This information is then passed through a scoring layer, which evaluates their importance based on relevance, importance, and recency. This ensures that only the most personalized and useful context is surfaced.
|
||||
|
||||
# Embed Online Resources
|
||||
naval_chat_bot.add("youtube_video", "https://www.youtube.com/watch?v=3qHkcs3kG44")
|
||||
naval_chat_bot.add("pdf_file", "https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Almanack-of-Naval-Ravikant_Final.pdf")
|
||||
naval_chat_bot.add("web_page", "https://nav.al/feedback")
|
||||
naval_chat_bot.add("web_page", "https://nav.al/agi")
|
||||
The retrieved memories can then be appended to the LLM's prompt as needed, enhancing the personalization and relevance of its responses.
|
||||
|
||||
# Embed Local Resources
|
||||
naval_chat_bot.add_local("qna_pair", ("Who is Naval Ravikant?", "Naval Ravikant is an Indian-American entrepreneur and investor."))
|
||||
### Use Cases
|
||||
|
||||
naval_chat_bot.query("What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?")
|
||||
# answer: Naval argues that humans possess the unique capacity to understand explanations or concepts to the maximum extent possible in this physical reality.
|
||||
```
|
||||
Mem0 empowers organizations and individuals to enhance:
|
||||
|
||||
# Getting Started
|
||||
- **AI Assistants and agents**: Seamless conversations with a touch of déjà vu
|
||||
- **Personalized Learning**: Tailored content recommendations and progress tracking
|
||||
- **Customer Support**: Context-aware assistance with user preference memory
|
||||
- **Healthcare**: Patient history and treatment plan management
|
||||
- **Virtual Companions**: Deeper user relationships through conversation memory
|
||||
- **Productivity**: Streamlined workflows based on user habits and task history
|
||||
- **Gaming**: Adaptive environments reflecting player choices and progress
|
||||
|
||||
## Installation
|
||||
## Get Started
|
||||
|
||||
First make sure that you have the package installed. If not, then install it using `pip`
|
||||
The easiest way to set up Mem0 is through the managed [Mem0 Platform](https://app.mem0.ai). This hosted solution offers automatic updates, advanced analytics, and dedicated support. [Sign up](https://app.mem0.ai) to get started.
|
||||
|
||||
If you prefer to self-host, use the open-source Mem0 package. Follow the [installation instructions](#install) to get started.
|
||||
|
||||
## Installation Instructions <a name="install"></a>
|
||||
|
||||
Install the Mem0 package via pip:
|
||||
|
||||
```bash
|
||||
pip install embedchain
|
||||
pip install mem0ai
|
||||
```
|
||||
|
||||
## Usage
|
||||
Alternatively, you can use Mem0 with one click on the hosted platform [here](https://app.mem0.ai/).
|
||||
|
||||
Creating a chatbot involves 3 steps:
|
||||
### Basic Usage
|
||||
|
||||
- Import the App instance (App Types)
|
||||
- Add Dataset (Add Dataset)
|
||||
- Query or Chat on the dataset and get answers (Interface Types)
|
||||
Mem0 requires an LLM to function, with `gpt-4o` from OpenAI as the default. However, it supports a variety of LLMs; for details, refer to our [Supported LLMs documentation](https://docs.mem0.ai/llms).
|
||||
|
||||
### App Types
|
||||
|
||||
We have three types of App.
|
||||
|
||||
#### 1. App (uses OpenAI models, paid)
|
||||
First step is to instantiate the memory:
|
||||
|
||||
```python
|
||||
from embedchain import App
|
||||
from mem0 import Memory
|
||||
|
||||
naval_chat_bot = App()
|
||||
m = Memory()
|
||||
```
|
||||
|
||||
- `App` uses OpenAI's model, so these are paid models. You will be charged for embedding model usage and LLM usage.
|
||||
|
||||
- `App` uses OpenAI's embedding model to create embeddings for chunks and ChatGPT API as LLM to get answer given the relevant docs. Make sure that you have an OpenAI account and an API key. If you have don't have an API key, you can create one by visiting [this link](https://platform.openai.com/account/api-keys).
|
||||
|
||||
- Once you have the API key, set it in an environment variable called `OPENAI_API_KEY`
|
||||
<details>
|
||||
<summary>How to set OPENAI_API_KEY</summary>
|
||||
|
||||
```python
|
||||
import os
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xxxx"
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xxx"
|
||||
```
|
||||
</details>
|
||||
|
||||
#### 2. OpenSourceApp (uses opensource models, free)
|
||||
|
||||
You can perform the following task on the memory:
|
||||
|
||||
1. Add: Store a memory from any unstructured text
|
||||
2. Update: Update memory of a given memory_id
|
||||
3. Search: Fetch memories based on a query
|
||||
4. Get: Return memories for a certain user/agent/session
|
||||
5. History: Describe how a memory has changed over time for a specific memory ID
|
||||
|
||||
```python
|
||||
from embedchain import OpenSourceApp
|
||||
# 1. Add: Store a memory from any unstructured text
|
||||
result = m.add("I am working on improving my tennis skills. Suggest some online courses.", user_id="alice", metadata={"category": "hobbies"})
|
||||
|
||||
naval_chat_bot = OpenSourceApp()
|
||||
# Created memory --> 'Improving her tennis skills.' and 'Looking for online suggestions.'
|
||||
```
|
||||
|
||||
- `OpenSourceApp` uses open source embedding and LLM model. It uses `all-MiniLM-L6-v2` from Sentence Transformers library as the embedding model and `gpt4all` as the LLM.
|
||||
|
||||
- Here there is no need to setup any api keys. You just need to install embedchain package and these will get automatically installed.
|
||||
|
||||
- Once you have imported and instantiated the app, every functionality from here onwards is the same for either type of app.
|
||||
|
||||
#### 3. PersonApp (uses OpenAI models, paid)
|
||||
|
||||
```python
|
||||
from embedchain import PersonApp
|
||||
# 2. Update: update the memory
|
||||
result = m.update(memory_id=<memory_id_1>, data="Likes to play tennis on weekends")
|
||||
|
||||
naval_chat_bot = PersonApp("name_of_person_or_character") #Like "Yoda"
|
||||
# Updated memory --> 'Likes to play tennis on weekends.' and 'Looking for online suggestions.'
|
||||
```
|
||||
|
||||
- `PersonApp` uses OpenAI's model, so these are paid models. You will be charged for embedding model usage and LLM usage.
|
||||
|
||||
- `PersonApp` uses OpenAI's embedding model to create embeddings for chunks and ChatGPT API as LLM to get answer given the relevant docs. Make sure that you have an OpenAI account and an API key. If you have don't have an API key, you can create one by visiting [this link](https://platform.openai.com/account/api-keys).
|
||||
|
||||
- Once you have the API key, set it in an environment variable called `OPENAI_API_KEY`
|
||||
|
||||
```python
|
||||
import os
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xxxx"
|
||||
# 3. Search: search related memories
|
||||
related_memories = m.search(query="What are Alice's hobbies?", user_id="alice")
|
||||
|
||||
# Retrieved memory --> 'Likes to play tennis on weekends'
|
||||
```
|
||||
|
||||
### Add Dataset
|
||||
|
||||
- This step assumes that you have already created an `app` instance by either using `App` or `OpenSourceApp`. We are calling our app instance as `naval_chat_bot`
|
||||
|
||||
- Now use `.add` function to add any dataset.
|
||||
|
||||
```python
|
||||
# 4. Get all memories
|
||||
all_memories = m.get_all()
|
||||
memory_id = all_memories["memories"][0] ["id"] # get a memory_id
|
||||
|
||||
# naval_chat_bot = App() or
|
||||
# naval_chat_bot = OpenSourceApp()
|
||||
|
||||
# Embed Online Resources
|
||||
naval_chat_bot.add("youtube_video", "https://www.youtube.com/watch?v=3qHkcs3kG44")
|
||||
naval_chat_bot.add("pdf_file", "https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Almanack-of-Naval-Ravikant_Final.pdf")
|
||||
naval_chat_bot.add("web_page", "https://nav.al/feedback")
|
||||
naval_chat_bot.add("web_page", "https://nav.al/agi")
|
||||
|
||||
# Embed Local Resources
|
||||
naval_chat_bot.add_local("qna_pair", ("Who is Naval Ravikant?", "Naval Ravikant is an Indian-American entrepreneur and investor."))
|
||||
# All memory items --> 'Likes to play tennis on weekends.' and 'Looking for online suggestions.'
|
||||
```
|
||||
|
||||
- If there is any other app instance in your script or app, you can change the import as
|
||||
|
||||
```python
|
||||
from embedchain import App as EmbedChainApp
|
||||
from embedchain import OpenSourceApp as EmbedChainOSApp
|
||||
from embedchain import PersonApp as EmbedChainPersonApp
|
||||
# 5. Get memory history for a particular memory_id
|
||||
history = m.history(memory_id=<memory_id_1>)
|
||||
|
||||
# or
|
||||
|
||||
from embedchain import App as ECApp
|
||||
from embedchain import OpenSourceApp as ECOSApp
|
||||
from embedchain import PersonApp as ECPApp
|
||||
# Logs corresponding to memory_id_1 --> {'prev_value': 'Working on improving tennis skills and interested in online courses for tennis.', 'new_value': 'Likes to play tennis on weekends' }
|
||||
```
|
||||
|
||||
## Interface Types
|
||||
> [!TIP]
|
||||
> If you prefer a hosted version without the need to set up infrastructure yourself, check out the [Mem0 Platform](https://app.mem0.ai/) to get started in minutes.
|
||||
|
||||
### Query Interface
|
||||
|
||||
- This interface is like a question answering bot. It takes a question and gets the answer. It does not maintain context about the previous chats.
|
||||
|
||||
- To use this, call `.query` function to get the answer for any query.
|
||||
### Graph Memory
|
||||
To initialize Graph Memory you'll need to set up your configuration with graph store providers.
|
||||
Currently, we support Neo4j as a graph store provider. You can setup [Neo4j](https://neo4j.com/) locally or use the hosted [Neo4j AuraDB](https://neo4j.com/product/auradb/).
|
||||
Moreover, you also need to set the version to `v1.1` (*prior versions are not supported*).
|
||||
Here's how you can do it:
|
||||
|
||||
```python
|
||||
print(naval_chat_bot.query("What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?"))
|
||||
# answer: Naval argues that humans possess the unique capacity to understand explanations or concepts to the maximum extent possible in this physical reality.
|
||||
```
|
||||
|
||||
### Chat Interface
|
||||
|
||||
- This interface is chat interface where it remembers previous conversation. Right now it remembers 5 conversation by default.
|
||||
|
||||
- To use this, call `.chat` function to get the answer for any query.
|
||||
|
||||
```python
|
||||
print(naval_chat_bot.chat("How to be happy in life?"))
|
||||
# answer: The most important trick to being happy is to realize happiness is a skill you develop and a choice you make. You choose to be happy, and then you work at it. It's just like building muscles or succeeding at your job. It's about recognizing the abundance and gifts around you at all times.
|
||||
|
||||
print(naval_chat_bot.chat("who is naval ravikant?"))
|
||||
# answer: Naval Ravikant is an Indian-American entrepreneur and investor.
|
||||
|
||||
print(naval_chat_bot.chat("what did the author say about happiness?"))
|
||||
# answer: The author, Naval Ravikant, believes that happiness is a choice you make and a skill you develop. He compares the mind to the body, stating that just as the body can be molded and changed, so can the mind. He emphasizes the importance of being present in the moment and not getting caught up in regrets of the past or worries about the future. By being present and grateful for where you are, you can experience true happiness.
|
||||
```
|
||||
|
||||
### Stream Response
|
||||
|
||||
- You can add config to your query method to stream responses like ChatGPT does. You would require a downstream handler to render the chunk in your desirable format. Supports both OpenAI model and OpenSourceApp.
|
||||
|
||||
- To use this, instantiate a `QueryConfig` or `ChatConfig` object with `stream=True`. Then pass it to the `.chat()` or `.query()` method. The following example iterates through the chunks and prints them as they appear.
|
||||
|
||||
```python
|
||||
app = App()
|
||||
query_config = QueryConfig(stream = True)
|
||||
resp = app.query("What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?", query_config)
|
||||
|
||||
for chunk in resp:
|
||||
print(chunk, end="", flush=True)
|
||||
# answer: Naval argues that humans possess the unique capacity to understand explanations or concepts to the maximum extent possible in this physical reality.
|
||||
```
|
||||
|
||||
## Format supported
|
||||
|
||||
We support the following formats:
|
||||
|
||||
### Youtube Video
|
||||
|
||||
To add any youtube video to your app, use the data_type (first argument to `.add`) as `youtube_video`. Eg:
|
||||
|
||||
```python
|
||||
app.add('youtube_video', 'a_valid_youtube_url_here')
|
||||
```
|
||||
|
||||
### PDF File
|
||||
|
||||
To add any pdf file, use the data_type as `pdf_file`. Eg:
|
||||
|
||||
```python
|
||||
app.add('pdf_file', 'a_valid_url_where_pdf_file_can_be_accessed')
|
||||
```
|
||||
|
||||
Note that we do not support password protected pdfs.
|
||||
|
||||
### Web Page
|
||||
|
||||
To add any web page, use the data_type as `web_page`. Eg:
|
||||
|
||||
```python
|
||||
app.add('web_page', 'a_valid_web_page_url')
|
||||
```
|
||||
|
||||
### Doc File
|
||||
|
||||
To add any doc/docx file, use the data_type as `docx`. Eg:
|
||||
|
||||
```python
|
||||
app.add('docx', 'a_local_docx_file_path')
|
||||
```
|
||||
|
||||
### Text
|
||||
|
||||
To supply your own text, use the data_type as `text` and enter a string. The text is not processed, this can be very versatile. Eg:
|
||||
|
||||
```python
|
||||
app.add_local('text', 'Seek wealth, not money or status. Wealth is having assets that earn while you sleep. Money is how we transfer time and wealth. Status is your place in the social hierarchy.')
|
||||
```
|
||||
|
||||
Note: This is not used in the examples because in most cases you will supply a whole paragraph or file, which did not fit.
|
||||
|
||||
### QnA Pair
|
||||
|
||||
To supply your own QnA pair, use the data_type as `qna_pair` and enter a tuple. Eg:
|
||||
|
||||
```python
|
||||
app.add_local('qna_pair', ("Question", "Answer"))
|
||||
```
|
||||
### Sitemap
|
||||
|
||||
To add a XML site map containing list of all urls, use the data_type as `sitemap` and enter the sitemap url. Eg:
|
||||
|
||||
```python
|
||||
app.add('sitemap', 'a_valid_sitemap_url/sitemap.xml')
|
||||
```
|
||||
|
||||
### Reusing a Vector DB
|
||||
|
||||
Default behavior is to create a persistent vector DB in the directory **./db**. You can split your application into two Python scripts: one to create a local vector DB and the other to reuse this local persistent vector DB. This is useful when you want to index hundreds of documents and separately implement a chat interface.
|
||||
|
||||
Create a local index:
|
||||
|
||||
```python
|
||||
|
||||
from embedchain import App
|
||||
|
||||
naval_chat_bot = App()
|
||||
naval_chat_bot.add("youtube_video", "https://www.youtube.com/watch?v=3qHkcs3kG44")
|
||||
naval_chat_bot.add("pdf_file", "https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Almanack-of-Naval-Ravikant_Final.pdf")
|
||||
```
|
||||
|
||||
You can reuse the local index with the same code, but without adding new documents:
|
||||
|
||||
```python
|
||||
|
||||
from embedchain import App
|
||||
|
||||
naval_chat_bot = App()
|
||||
print(naval_chat_bot.query("What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?"))
|
||||
```
|
||||
|
||||
### More Formats coming soon
|
||||
|
||||
- If you want to add any other format, please create an [issue](https://github.com/embedchain/embedchain/issues) and we will add it to the list of supported formats.
|
||||
|
||||
## Testing
|
||||
|
||||
Before you consume valueable tokens, you should make sure that the embedding you have done works and that it's receiving the correct document from the database.
|
||||
|
||||
For this you can use the `dry_run` method.
|
||||
|
||||
Following the example above, add this to your script:
|
||||
|
||||
```python
|
||||
print(naval_chat_bot.dry_run('Can you tell me who Naval Ravikant is?'))
|
||||
|
||||
'''
|
||||
Use the following pieces of context to answer the query at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.
|
||||
Q: Who is Naval Ravikant?
|
||||
A: Naval Ravikant is an Indian-American entrepreneur and investor.
|
||||
Query: Can you tell me who Naval Ravikant is?
|
||||
Helpful Answer:
|
||||
'''
|
||||
```
|
||||
|
||||
_The embedding is confirmed to work as expected. It returns the right document, even if the question is asked slightly different. No prompt tokens have been consumed._
|
||||
|
||||
**The dry run will still consume tokens to embed your query, but it is only ~1/15 of the prompt.**
|
||||
|
||||
## Colab Notebook and Video Tutorials
|
||||
|
||||
Chinese Colab Tutorial:https://colab.research.google.com/drive/10_7Y0x4YXWVjuhhYwVraGQLpKAatTQTm?usp=sharing
|
||||
|
||||
Chinese Video Tutorial:https://www.bilibili.com/video/BV1YX4y1H7oN
|
||||
|
||||
# Advanced
|
||||
|
||||
## Configuration
|
||||
|
||||
Embedchain is made to work out of the box. However, for advanced users we're also offering configuration options. All of these configuration options are optional and have sane defaults.
|
||||
|
||||
### Example
|
||||
|
||||
Here's the readme example with configuration options.
|
||||
|
||||
```python
|
||||
import os
|
||||
from embedchain import App
|
||||
from embedchain.config import InitConfig, AddConfig, QueryConfig
|
||||
from chromadb.utils import embedding_functions
|
||||
|
||||
# Example: use your own embedding function
|
||||
config = InitConfig(ef=embedding_functions.OpenAIEmbeddingFunction(
|
||||
api_key=os.getenv("OPENAI_API_KEY"),
|
||||
organization_id=os.getenv("OPENAI_ORGANIZATION"),
|
||||
model_name="text-embedding-ada-002"
|
||||
))
|
||||
naval_chat_bot = App(config)
|
||||
|
||||
# Example: define your own chunker config for `youtube_video`
|
||||
youtube_add_config = {
|
||||
"chunker": {
|
||||
"chunk_size": 1000,
|
||||
"chunk_overlap": 100,
|
||||
"length_function": len,
|
||||
from mem0 import Memory
|
||||
|
||||
config = {
|
||||
"graph_store": {
|
||||
"provider": "neo4j",
|
||||
"config": {
|
||||
"url": "neo4j+s://xxx",
|
||||
"username": "neo4j",
|
||||
"password": "xxx"
|
||||
}
|
||||
},
|
||||
"version": "v1.1"
|
||||
}
|
||||
naval_chat_bot.add("youtube_video", "https://www.youtube.com/watch?v=3qHkcs3kG44", AddConfig(**youtube_add_config))
|
||||
|
||||
add_config = AddConfig()
|
||||
naval_chat_bot.add("pdf_file", "https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Almanack-of-Naval-Ravikant_Final.pdf", add_config)
|
||||
naval_chat_bot.add("web_page", "https://nav.al/feedback", add_config)
|
||||
naval_chat_bot.add("web_page", "https://nav.al/agi", add_config)
|
||||
m = Memory.from_config(config_dict=config)
|
||||
|
||||
naval_chat_bot.add_local("qna_pair", ("Who is Naval Ravikant?", "Naval Ravikant is an Indian-American entrepreneur and investor."), add_config)
|
||||
|
||||
query_config = QueryConfig() # Currently no options
|
||||
print(naval_chat_bot.query("What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?", query_config))
|
||||
```
|
||||
|
||||
Here's the example of using custom prompt template with `.query`
|
||||
## Documentation
|
||||
|
||||
```python
|
||||
from embedchain.config import QueryConfig
|
||||
from embedchain.embedchain import App
|
||||
from string import Template
|
||||
import wikipedia
|
||||
For detailed usage instructions and API reference, visit our documentation at [docs.mem0.ai](https://docs.mem0.ai). Here, you can find more information on both the open-source version and the hosted [Mem0 Platform](https://app.mem0.ai).
|
||||
|
||||
einstein_chat_bot = App()
|
||||
## Star History
|
||||
|
||||
# Embed Wikipedia page
|
||||
page = wikipedia.page("Albert Einstein")
|
||||
einstein_chat_bot.add("text", page.content)
|
||||
[](https://star-history.com/#mem0ai/mem0&Date)
|
||||
|
||||
# Example: use your own custom template with `$context` and `$query`
|
||||
einstein_chat_template = Template("""
|
||||
You are Albert Einstein, a German-born theoretical physicist,
|
||||
widely ranked among the greatest and most influential scientists of all time.
|
||||
## Support
|
||||
|
||||
Use the following information about Albert Einstein to respond to
|
||||
the human's query acting as Albert Einstein.
|
||||
Context: $context
|
||||
Join our community for support and discussions. If you have any questions, feel free to reach out to us using one of the following methods:
|
||||
|
||||
Keep the response brief. If you don't know the answer, just say that you don't know, don't try to make up an answer.
|
||||
- [Join our Discord](https://mem0.dev/DiG)
|
||||
- [Follow us on Twitter](https://x.com/mem0ai)
|
||||
- [Email founders](mailto:founders@mem0.ai)
|
||||
|
||||
Human: $query
|
||||
Albert Einstein:""")
|
||||
query_config = QueryConfig(einstein_chat_template)
|
||||
queries = [
|
||||
"Where did you complete your studies?",
|
||||
"Why did you win nobel prize?",
|
||||
"Why did you divorce your first wife?",
|
||||
]
|
||||
for query in queries:
|
||||
response = einstein_chat_bot.query(query, query_config)
|
||||
print("Query: ", query)
|
||||
print("Response: ", response)
|
||||
## Contributors
|
||||
|
||||
# Output
|
||||
# Query: Where did you complete your studies?
|
||||
# Response: I completed my secondary education at the Argovian cantonal school in Aarau, Switzerland.
|
||||
# Query: Why did you win nobel prize?
|
||||
# Response: I won the Nobel Prize in Physics in 1921 for my services to Theoretical Physics, particularly for my discovery of the law of the photoelectric effect.
|
||||
# Query: Why did you divorce your first wife?
|
||||
# Response: We divorced due to living apart for five years.
|
||||
```
|
||||
Join our [Discord community](https://mem0.dev/DiG) to learn about memory management for AI agents and LLMs, and connect with Mem0 users and contributors. Share your ideas, questions, or feedback in our [GitHub Issues](https://github.com/mem0ai/mem0/issues).
|
||||
|
||||
**Client Mode**. By defining a (ChromaDB) server, you can run EmbedChain as a client only.
|
||||
We value and appreciate the contributions of our community. Special thanks to our contributors for helping us improve Mem0.
|
||||
|
||||
```python
|
||||
from embedchain import App
|
||||
config = InitConfig(host="localhost", port="8080")
|
||||
app = App(config)
|
||||
```
|
||||
This is useful for scalability. Say you have EmbedChain behind an API with multiple workers. If you separate clients and server, all clients can connect to the server, which only has to keep one instance of the database in memory. You also don't have to worry about replication.
|
||||
<a href="https://github.com/mem0ai/mem0/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=mem0ai/mem0" />
|
||||
</a>
|
||||
|
||||
To run a chroma db server, run `git clone https://github.com/chroma-core/chroma.git`, navigate to the directory (`cd chroma`) and then start the server with `docker-compose up -d --build`.
|
||||
## Anonymous Telemetry
|
||||
|
||||
### Configs
|
||||
We collect anonymous usage metrics to enhance our package's quality and user experience. This includes data like feature usage frequency and system info, but never personal details. The data helps us prioritize improvements and ensure compatibility. If you wish to opt-out, set the environment variable MEM0_TELEMETRY=false. We prioritize data security and don't share this data externally.
|
||||
|
||||
This section describes all possible config options.
|
||||
## License
|
||||
|
||||
#### **InitConfig**
|
||||
|
||||
|option|description|type|default|
|
||||
|---|---|---|---|
|
||||
|log_level|log level|string|WARNING|
|
||||
|ef|embedding function|chromadb.utils.embedding_functions|{text-embedding-ada-002}|
|
||||
|db|vector database (experimental)|BaseVectorDB|ChromaDB|
|
||||
|host|hostname for (Chroma) DB server|string|None|
|
||||
|port|port number for (Chroma) DB server|string, int|None|
|
||||
|
||||
#### **Add Config**
|
||||
|
||||
|option|description|type|default|
|
||||
|---|---|---|---|
|
||||
|chunker|chunker config|ChunkerConfig|Default values for chunker depends on the `data_type`. Please refer [ChunkerConfig](#chunker-config)|
|
||||
|loader|loader config|LoaderConfig|None|
|
||||
|
||||
##### **Chunker Config**
|
||||
|
||||
|option|description|type|default|
|
||||
|---|---|---|---|
|
||||
|chunk_size|Maximum size of chunks to return|int|Default value for various `data_type` mentioned below|
|
||||
|chunk_overlap|Overlap in characters between chunks|int|Default value for various `data_type` mentioned below|
|
||||
|length_function|Function that measures the length of given chunks|typing.Callable|Default value for various `data_type` mentioned below|
|
||||
|
||||
Default values of chunker config parameters for different `data_type`:
|
||||
|
||||
|data_type|chunk_size|chunk_overlap|length_function|
|
||||
|---|---|---|---|
|
||||
|docx|1000|0|len|
|
||||
|text|300|0|len|
|
||||
|qna_pair|300|0|len|
|
||||
|web_page|500|0|len|
|
||||
|pdf_file|1000|0|len|
|
||||
|youtube_video|2000|0|len|
|
||||
|
||||
##### **Loader Config**
|
||||
|
||||
_coming soon_
|
||||
|
||||
#### **Query Config**
|
||||
|
||||
|option|description|type|default|
|
||||
|---|---|---|---|
|
||||
|number_documents|number of documents to be retrieved as context|int|1|
|
||||
|template|custom template for prompt|Template|Template("Use the following pieces of context to answer the query at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer. \$context Query: $query Helpful Answer:")|
|
||||
|history|include conversation history from your client or database|any (recommendation: list[str])|None
|
||||
|stream|control if response is streamed back to the user|bool|False|
|
||||
|model|OpenAI model|string|gpt-3.5-turbo-0613|
|
||||
|temperature|creativity of the model (0-1)|float|0|
|
||||
|max_tokens|limit maximum tokens used|int|1000|
|
||||
|top_p|diversity of words used by the model (0-1)|float|1|
|
||||
|
||||
#### **Chat Config**
|
||||
|
||||
All options for query and...
|
||||
|
||||
_coming soon_
|
||||
|
||||
history is handled automatically, the config option is not supported.
|
||||
|
||||
## Other methods
|
||||
|
||||
### Reset
|
||||
|
||||
Resets the database and deletes all embeddings. Irreversible. Requires reinitialization afterwards.
|
||||
|
||||
```python
|
||||
app.reset()
|
||||
```
|
||||
|
||||
### Count
|
||||
|
||||
Counts the number of embeddings (chunks) in the database.
|
||||
|
||||
```python
|
||||
print(app.count())
|
||||
# returns: 481
|
||||
```
|
||||
|
||||
# How does it work?
|
||||
|
||||
Creating a chat bot over any dataset needs the following steps to happen
|
||||
|
||||
- load the data
|
||||
- create meaningful chunks
|
||||
- create embeddings for each chunk
|
||||
- store the chunks in vector database
|
||||
|
||||
Whenever a user asks any query, following process happens to find the answer for the query
|
||||
|
||||
- create the embedding for query
|
||||
- find similar documents for this query from vector database
|
||||
- pass similar documents as context to LLM to get the final answer.
|
||||
|
||||
The process of loading the dataset and then querying involves multiple steps and each steps has nuances of it is own.
|
||||
|
||||
- How should I chunk the data? What is a meaningful chunk size?
|
||||
- How should I create embeddings for each chunk? Which embedding model should I use?
|
||||
- How should I store the chunks in vector database? Which vector database should I use?
|
||||
- Should I store meta data along with the embeddings?
|
||||
- How should I find similar documents for a query? Which ranking model should I use?
|
||||
|
||||
These questions may be trivial for some but for a lot of us, it needs research, experimentation and time to find out the accurate answers.
|
||||
|
||||
embedchain is a framework which takes care of all these nuances and provides a simple interface to create bots over any dataset.
|
||||
|
||||
In the first release, we are making it easier for anyone to get a chatbot over any dataset up and running in less than a minute. All you need to do is create an app instance, add the data sets using `.add` function and then use `.query` function to get the relevant answer.
|
||||
|
||||
# Contribution Guidelines
|
||||
|
||||
Thank you for your interest in contributing to the EmbedChain project! We welcome your ideas and contributions to help improve the project. Please follow the instructions below to get started:
|
||||
|
||||
1. **Fork the repository**: Click on the "Fork" button at the top right corner of this repository page. This will create a copy of the repository in your own GitHub account.
|
||||
|
||||
2. **Install the required dependencies**: Ensure that you have the necessary dependencies installed in your Python environment. You can do this by running the following command:
|
||||
|
||||
```bash
|
||||
make install
|
||||
```
|
||||
|
||||
3. **Make changes in the code**: Create a new branch in your forked repository and make your desired changes in the codebase.
|
||||
4. **Format code**: Before creating a pull request, it's important to ensure that your code follows our formatting guidelines. Run the following commands to format the code:
|
||||
|
||||
```bash
|
||||
make lint format
|
||||
```
|
||||
|
||||
5. **Create a pull request**: When you are ready to contribute your changes, submit a pull request to the EmbedChain repository. Provide a clear and descriptive title for your pull request, along with a detailed description of the changes you have made.
|
||||
|
||||
# Tech Stack
|
||||
|
||||
embedchain is built on the following stack:
|
||||
|
||||
- [Langchain](https://github.com/hwchase17/langchain) as an LLM framework to load, chunk and index data
|
||||
- [OpenAI's Ada embedding model](https://platform.openai.com/docs/guides/embeddings) to create embeddings
|
||||
- [OpenAI's ChatGPT API](https://platform.openai.com/docs/guides/gpt/chat-completions-api) as LLM to get answers given the context
|
||||
- [Chroma](https://github.com/chroma-core/chroma) as the vector database to store embeddings
|
||||
- [gpt4all](https://github.com/nomic-ai/gpt4all) as an open source LLM
|
||||
- [sentence-transformers](https://huggingface.co/sentence-transformers) as open source embedding model
|
||||
|
||||
# Team
|
||||
|
||||
## Author
|
||||
|
||||
- Taranjeet Singh ([@taranjeetio](https://twitter.com/taranjeetio))
|
||||
|
||||
## Maintainer
|
||||
|
||||
- [cachho](https://github.com/cachho)
|
||||
|
||||
## Citation
|
||||
|
||||
If you utilize this repository, please consider citing it with:
|
||||
|
||||
```
|
||||
@misc{embedchain,
|
||||
author = {Taranjeet Singh},
|
||||
title = {Embechain: Framework to easily create LLM powered bots over any dataset},
|
||||
year = {2023},
|
||||
publisher = {GitHub},
|
||||
journal = {GitHub repository},
|
||||
howpublished = {\url{https://github.com/embedchain/embedchain}},
|
||||
}
|
||||
```
|
||||
This project is licensed under the Apache 2.0 License - see the [LICENSE](LICENSE) file for details.
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"from typing import List, Dict\n",
|
||||
"from mem0 import Memory\n",
|
||||
"from datetime import datetime\n",
|
||||
"import anthropic\n",
|
||||
"\n",
|
||||
"# Set up environment variables\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"your_openai_api_key\" # needed for embedding model\n",
|
||||
"os.environ[\"ANTHROPIC_API_KEY\"] = \"your_anthropic_api_key\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class SupportChatbot:\n",
|
||||
" def __init__(self):\n",
|
||||
" # Initialize Mem0 with Anthropic's Claude\n",
|
||||
" self.config = {\n",
|
||||
" \"llm\": {\n",
|
||||
" \"provider\": \"anthropic\",\n",
|
||||
" \"config\": {\n",
|
||||
" \"model\": \"claude-3-5-sonnet-latest\",\n",
|
||||
" \"temperature\": 0.1,\n",
|
||||
" \"max_tokens\": 2000,\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
" self.client = anthropic.Client(api_key=os.environ[\"ANTHROPIC_API_KEY\"])\n",
|
||||
" self.memory = Memory.from_config(self.config)\n",
|
||||
"\n",
|
||||
" # Define support context\n",
|
||||
" self.system_context = \"\"\"\n",
|
||||
" You are a helpful customer support agent. Use the following guidelines:\n",
|
||||
" - Be polite and professional\n",
|
||||
" - Show empathy for customer issues\n",
|
||||
" - Reference past interactions when relevant\n",
|
||||
" - Maintain consistent information across conversations\n",
|
||||
" - If you're unsure about something, ask for clarification\n",
|
||||
" - Keep track of open issues and follow-ups\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
" def store_customer_interaction(self,\n",
|
||||
" user_id: str,\n",
|
||||
" message: str,\n",
|
||||
" response: str,\n",
|
||||
" metadata: Dict = None):\n",
|
||||
" \"\"\"Store customer interaction in memory.\"\"\"\n",
|
||||
" if metadata is None:\n",
|
||||
" metadata = {}\n",
|
||||
"\n",
|
||||
" # Add timestamp to metadata\n",
|
||||
" metadata[\"timestamp\"] = datetime.now().isoformat()\n",
|
||||
"\n",
|
||||
" # Format conversation for storage\n",
|
||||
" conversation = [\n",
|
||||
" {\"role\": \"user\", \"content\": message},\n",
|
||||
" {\"role\": \"assistant\", \"content\": response}\n",
|
||||
" ]\n",
|
||||
"\n",
|
||||
" # Store in Mem0\n",
|
||||
" self.memory.add(\n",
|
||||
" conversation,\n",
|
||||
" user_id=user_id,\n",
|
||||
" metadata=metadata\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" def get_relevant_history(self, user_id: str, query: str) -> List[Dict]:\n",
|
||||
" \"\"\"Retrieve relevant past interactions.\"\"\"\n",
|
||||
" return self.memory.search(\n",
|
||||
" query=query,\n",
|
||||
" user_id=user_id,\n",
|
||||
" limit=5 # Adjust based on needs\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" def handle_customer_query(self, user_id: str, query: str) -> str:\n",
|
||||
" \"\"\"Process customer query with context from past interactions.\"\"\"\n",
|
||||
"\n",
|
||||
" # Get relevant past interactions\n",
|
||||
" relevant_history = self.get_relevant_history(user_id, query)\n",
|
||||
"\n",
|
||||
" # Build context from relevant history\n",
|
||||
" context = \"Previous relevant interactions:\\n\"\n",
|
||||
" for memory in relevant_history:\n",
|
||||
" context += f\"Customer: {memory['memory']}\\n\"\n",
|
||||
" context += f\"Support: {memory['memory']}\\n\"\n",
|
||||
" context += \"---\\n\"\n",
|
||||
"\n",
|
||||
" # Prepare prompt with context and current query\n",
|
||||
" prompt = f\"\"\"\n",
|
||||
" {self.system_context}\n",
|
||||
"\n",
|
||||
" {context}\n",
|
||||
"\n",
|
||||
" Current customer query: {query}\n",
|
||||
"\n",
|
||||
" Provide a helpful response that takes into account any relevant past interactions.\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
" # Generate response using Claude\n",
|
||||
" response = self.client.messages.create(\n",
|
||||
" model=\"claude-3-5-sonnet-latest\",\n",
|
||||
" messages=[{\"role\": \"user\", \"content\": prompt}],\n",
|
||||
" max_tokens=2000,\n",
|
||||
" temperature=0.1\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" # Store interaction\n",
|
||||
" self.store_customer_interaction(\n",
|
||||
" user_id=user_id,\n",
|
||||
" message=query,\n",
|
||||
" response=response,\n",
|
||||
" metadata={\"type\": \"support_query\"}\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" return response.content[0].text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Welcome to Customer Support! Type 'exit' to end the conversation.\n",
|
||||
"Customer: Hi, I'm having trouble connecting my new smartwatch to the mobile app. It keeps showing a connection error.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/var/folders/5x/9kmqjfm947g5yh44m7fjk75r0000gn/T/ipykernel_99777/1076713094.py:55: DeprecationWarning: The current get_all API output format is deprecated. To use the latest format, set `api_version='v1.1'`. The current format will be removed in mem0ai 1.1.0 and later versions.\n",
|
||||
" return self.memory.search(\n",
|
||||
"/var/folders/5x/9kmqjfm947g5yh44m7fjk75r0000gn/T/ipykernel_99777/1076713094.py:47: DeprecationWarning: The current add API output format is deprecated. To use the latest format, set `api_version='v1.1'`. The current format will be removed in mem0ai 1.1.0 and later versions.\n",
|
||||
" self.memory.add(\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Support: Hello! Thank you for reaching out about the connection issue with your smartwatch. I understand how frustrating it can be when a new device won't connect properly. I'll be happy to help you resolve this.\n",
|
||||
"\n",
|
||||
"To better assist you, could you please provide me with:\n",
|
||||
"1. The model of your smartwatch\n",
|
||||
"2. The type of phone you're using (iOS or Android)\n",
|
||||
"3. Whether you've already installed the companion app on your phone\n",
|
||||
"4. If you've tried pairing the devices before\n",
|
||||
"\n",
|
||||
"These details will help me provide you with the most accurate troubleshooting steps. In the meantime, here are some general tips that might help:\n",
|
||||
"- Make sure Bluetooth is enabled on your phone\n",
|
||||
"- Keep your smartwatch and phone within close range (within 3 feet) during pairing\n",
|
||||
"- Ensure both devices have sufficient battery power\n",
|
||||
"- Check if your phone's operating system meets the minimum requirements for the smartwatch\n",
|
||||
"\n",
|
||||
"Please provide the requested information, and I'll guide you through the specific steps to resolve the connection error.\n",
|
||||
"\n",
|
||||
"Is there anything else you'd like to share about the issue? \n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Customer: The connection issue is still happening even after trying the steps you suggested.\n",
|
||||
"Support: I apologize that you're still experiencing connection issues with your smartwatch. I understand how frustrating it must be to have this problem persist even after trying the initial troubleshooting steps. Let's try some additional solutions to resolve this.\n",
|
||||
"\n",
|
||||
"Before we proceed, could you please confirm:\n",
|
||||
"1. Which specific steps you've already attempted?\n",
|
||||
"2. Are you seeing any particular error message?\n",
|
||||
"3. What model of smartwatch and phone are you using?\n",
|
||||
"\n",
|
||||
"This information will help me provide more targeted solutions and avoid suggesting steps you've already tried. In the meantime, here are a few advanced troubleshooting steps we can consider:\n",
|
||||
"\n",
|
||||
"1. Completely resetting the Bluetooth connection\n",
|
||||
"2. Checking for any software updates for both the watch and phone\n",
|
||||
"3. Testing the connection with a different mobile device to isolate the issue\n",
|
||||
"\n",
|
||||
"Would you be able to provide those details so I can better assist you? I'll make sure to document this ongoing issue to help track its resolution. \n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Customer: exit\n",
|
||||
"Thank you for using our support service. Goodbye!\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"chatbot = SupportChatbot()\n",
|
||||
"user_id = \"customer_bot\"\n",
|
||||
"print(\"Welcome to Customer Support! Type 'exit' to end the conversation.\")\n",
|
||||
"\n",
|
||||
"while True:\n",
|
||||
" # Get user input\n",
|
||||
" query = input()\n",
|
||||
" print(\"Customer:\", query)\n",
|
||||
" \n",
|
||||
" # Check if user wants to exit\n",
|
||||
" if query.lower() == 'exit':\n",
|
||||
" print(\"Thank you for using our support service. Goodbye!\")\n",
|
||||
" break\n",
|
||||
" \n",
|
||||
" # Handle the query and print the response\n",
|
||||
" response = chatbot.handle_customer_query(user_id, query)\n",
|
||||
" print(\"Support:\", response, \"\\n\\n\")"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.12.4"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
# Copyright (c) 2023 - 2024, Owners of https://github.com/autogen-ai
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Portions derived from https://github.com/microsoft/autogen are under the MIT License.
|
||||
# SPDX-License-Identifier: MIT
|
||||
# forked from autogen.agentchat.contrib.capabilities.teachability.Teachability
|
||||
|
||||
from typing import Dict, Optional, Union
|
||||
from autogen.agentchat.assistant_agent import ConversableAgent
|
||||
from autogen.agentchat.contrib.capabilities.agent_capability import AgentCapability
|
||||
from autogen.agentchat.contrib.text_analyzer_agent import TextAnalyzerAgent
|
||||
from termcolor import colored
|
||||
from mem0 import Memory
|
||||
|
||||
|
||||
class Mem0Teachability(AgentCapability):
|
||||
def __init__(
|
||||
self,
|
||||
verbosity: Optional[int] = 0,
|
||||
reset_db: Optional[bool] = False,
|
||||
recall_threshold: Optional[float] = 1.5,
|
||||
max_num_retrievals: Optional[int] = 10,
|
||||
llm_config: Optional[Union[Dict, bool]] = None,
|
||||
agent_id: Optional[str] = None,
|
||||
memory_client: Optional[Memory] = None,
|
||||
):
|
||||
self.verbosity = verbosity
|
||||
self.recall_threshold = recall_threshold
|
||||
self.max_num_retrievals = max_num_retrievals
|
||||
self.llm_config = llm_config
|
||||
self.analyzer = None
|
||||
self.teachable_agent = None
|
||||
self.agent_id = agent_id
|
||||
self.memory = memory_client if memory_client else Memory()
|
||||
|
||||
if reset_db:
|
||||
self.memory.reset()
|
||||
|
||||
def add_to_agent(self, agent: ConversableAgent):
|
||||
self.teachable_agent = agent
|
||||
agent.register_hook(hookable_method="process_last_received_message", hook=self.process_last_received_message)
|
||||
|
||||
if self.llm_config is None:
|
||||
self.llm_config = agent.llm_config
|
||||
assert self.llm_config, "Teachability requires a valid llm_config."
|
||||
|
||||
self.analyzer = TextAnalyzerAgent(llm_config=self.llm_config)
|
||||
|
||||
agent.update_system_message(
|
||||
agent.system_message
|
||||
+ "\nYou've been given the special ability to remember user teachings from prior conversations."
|
||||
)
|
||||
|
||||
def process_last_received_message(self, text: Union[Dict, str]):
|
||||
expanded_text = text
|
||||
if self.memory.get_all(agent_id=self.agent_id):
|
||||
expanded_text = self._consider_memo_retrieval(text)
|
||||
self._consider_memo_storage(text)
|
||||
return expanded_text
|
||||
|
||||
def _consider_memo_storage(self, comment: Union[Dict, str]):
|
||||
response = self._analyze(
|
||||
comment,
|
||||
"Does any part of the TEXT ask the agent to perform a task or solve a problem? Answer with just one word, yes or no.",
|
||||
)
|
||||
|
||||
if "yes" in response.lower():
|
||||
advice = self._analyze(
|
||||
comment,
|
||||
"Briefly copy any advice from the TEXT that may be useful for a similar but different task in the future. But if no advice is present, just respond with 'none'.",
|
||||
)
|
||||
|
||||
if "none" not in advice.lower():
|
||||
task = self._analyze(
|
||||
comment,
|
||||
"Briefly copy just the task from the TEXT, then stop. Don't solve it, and don't include any advice.",
|
||||
)
|
||||
|
||||
general_task = self._analyze(
|
||||
task,
|
||||
"Summarize very briefly, in general terms, the type of task described in the TEXT. Leave out details that might not appear in a similar problem.",
|
||||
)
|
||||
|
||||
if self.verbosity >= 1:
|
||||
print(colored("\nREMEMBER THIS TASK-ADVICE PAIR", "light_yellow"))
|
||||
self.memory.add(
|
||||
[{"role": "user", "content": f"Task: {general_task}\nAdvice: {advice}"}], agent_id=self.agent_id
|
||||
)
|
||||
|
||||
response = self._analyze(
|
||||
comment,
|
||||
"Does the TEXT contain information that could be committed to memory? Answer with just one word, yes or no.",
|
||||
)
|
||||
|
||||
if "yes" in response.lower():
|
||||
question = self._analyze(
|
||||
comment,
|
||||
"Imagine that the user forgot this information in the TEXT. How would they ask you for this information? Include no other text in your response.",
|
||||
)
|
||||
|
||||
answer = self._analyze(
|
||||
comment, "Copy the information from the TEXT that should be committed to memory. Add no explanation."
|
||||
)
|
||||
|
||||
if self.verbosity >= 1:
|
||||
print(colored("\nREMEMBER THIS QUESTION-ANSWER PAIR", "light_yellow"))
|
||||
self.memory.add(
|
||||
[{"role": "user", "content": f"Question: {question}\nAnswer: {answer}"}], agent_id=self.agent_id
|
||||
)
|
||||
|
||||
def _consider_memo_retrieval(self, comment: Union[Dict, str]):
|
||||
if self.verbosity >= 1:
|
||||
print(colored("\nLOOK FOR RELEVANT MEMOS, AS QUESTION-ANSWER PAIRS", "light_yellow"))
|
||||
memo_list = self._retrieve_relevant_memos(comment)
|
||||
|
||||
response = self._analyze(
|
||||
comment,
|
||||
"Does any part of the TEXT ask the agent to perform a task or solve a problem? Answer with just one word, yes or no.",
|
||||
)
|
||||
|
||||
if "yes" in response.lower():
|
||||
if self.verbosity >= 1:
|
||||
print(colored("\nLOOK FOR RELEVANT MEMOS, AS TASK-ADVICE PAIRS", "light_yellow"))
|
||||
task = self._analyze(
|
||||
comment, "Copy just the task from the TEXT, then stop. Don't solve it, and don't include any advice."
|
||||
)
|
||||
|
||||
general_task = self._analyze(
|
||||
task,
|
||||
"Summarize very briefly, in general terms, the type of task described in the TEXT. Leave out details that might not appear in a similar problem.",
|
||||
)
|
||||
|
||||
memo_list.extend(self._retrieve_relevant_memos(general_task))
|
||||
|
||||
memo_list = list(set(memo_list))
|
||||
return comment + self._concatenate_memo_texts(memo_list)
|
||||
|
||||
def _retrieve_relevant_memos(self, input_text: str) -> list:
|
||||
search_results = self.memory.search(input_text, agent_id=self.agent_id, limit=self.max_num_retrievals)
|
||||
memo_list = [result["memory"] for result in search_results if result["score"] <= self.recall_threshold]
|
||||
|
||||
if self.verbosity >= 1 and not memo_list:
|
||||
print(colored("\nTHE CLOSEST MEMO IS BEYOND THE THRESHOLD:", "light_yellow"))
|
||||
if search_results["results"]:
|
||||
print(search_results["results"][0])
|
||||
print()
|
||||
|
||||
return memo_list
|
||||
|
||||
def _concatenate_memo_texts(self, memo_list: list) -> str:
|
||||
memo_texts = ""
|
||||
if memo_list:
|
||||
info = "\n# Memories that might help\n"
|
||||
for memo in memo_list:
|
||||
info += f"- {memo}\n"
|
||||
if self.verbosity >= 1:
|
||||
print(colored(f"\nMEMOS APPENDED TO LAST MESSAGE...\n{info}\n", "light_yellow"))
|
||||
memo_texts += "\n" + info
|
||||
return memo_texts
|
||||
|
||||
def _analyze(self, text_to_analyze: Union[Dict, str], analysis_instructions: Union[Dict, str]):
|
||||
self.analyzer.reset()
|
||||
self.teachable_agent.send(
|
||||
recipient=self.analyzer, message=text_to_analyze, request_reply=False, silent=(self.verbosity < 2)
|
||||
)
|
||||
self.teachable_agent.send(
|
||||
recipient=self.analyzer, message=analysis_instructions, request_reply=True, silent=(self.verbosity < 2)
|
||||
)
|
||||
return self.teachable_agent.last_message(self.analyzer)["content"]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,32 @@
|
||||
# Mintlify Starter Kit
|
||||
|
||||
Click on `Use this template` to copy the Mintlify starter kit. The starter kit contains examples including
|
||||
|
||||
- Guide pages
|
||||
- Navigation
|
||||
- Customizations
|
||||
- API Reference pages
|
||||
- Use of popular components
|
||||
|
||||
### Development
|
||||
|
||||
Install the [Mintlify CLI](https://www.npmjs.com/package/mintlify) to preview the documentation changes locally. To install, use the following command
|
||||
|
||||
```
|
||||
npm i -g mintlify
|
||||
```
|
||||
|
||||
Run the following command at the root of your documentation (where mint.json is)
|
||||
|
||||
```
|
||||
mintlify dev
|
||||
```
|
||||
|
||||
### Publishing Changes
|
||||
|
||||
Install our Github App to auto propagate changes from your repo to your deployment. Changes will be deployed to production automatically after pushing to the default branch. Find the link to install on your dashboard.
|
||||
|
||||
#### Troubleshooting
|
||||
|
||||
- Mintlify dev isn't running - Run `mintlify install` it'll re-install dependencies.
|
||||
- Page loads as a 404 - Make sure you are running in a folder with `mint.json`
|
||||
@@ -0,0 +1,11 @@
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Discord" icon="discord" href="https://mem0.dev/DiD" color="#7289DA">
|
||||
Join our community
|
||||
</Card>
|
||||
<Card title="GitHub" icon="github" href="https://github.com/mem0ai/mem0/discussions/new?category=q-a">
|
||||
Ask questions on GitHub
|
||||
</Card>
|
||||
<Card title="Support" icon="calendar" href="https://cal.com/taranjeetio/meet">
|
||||
Talk to founders
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Delete User'
|
||||
openapi: delete /v1/entities/{entity_type}/{entity_id}/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Get Users'
|
||||
openapi: get /v1/entities/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Add Memories'
|
||||
openapi: post /v1/memories/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Batch Delete Memories'
|
||||
openapi: delete /v1/memories/batch/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Batch Update Memories'
|
||||
openapi: put /v1/memories/batch/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Delete Memories'
|
||||
openapi: delete /v1/memories/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Delete Memory'
|
||||
openapi: delete /v1/memories/{memory_id}/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Get Memory'
|
||||
openapi: get /v1/memories/{memory_id}/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Memory History'
|
||||
openapi: get /v1/memories/{memory_id}/history/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Update Memory'
|
||||
openapi: put /v1/memories/{memory_id}/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'V1 Get Memories'
|
||||
openapi: get /v1/memories/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'V1 Search Memories'
|
||||
openapi: post /v1/memories/search/
|
||||
---
|
||||
@@ -0,0 +1,74 @@
|
||||
---
|
||||
title: 'V2 Get Memories'
|
||||
openapi: post /v2/memories/
|
||||
---
|
||||
|
||||
|
||||
Mem0 offers two versions of the get memories API: v1 and v2. Here's how they differ:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="v1 Get Memories">
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
memories = m.get_all(user_id="alex")
|
||||
```
|
||||
|
||||
```json Output
|
||||
[
|
||||
{
|
||||
"id":"f38b689d-6b24-45b7-bced-17fbb4d8bac7",
|
||||
"memory":"travelling to Paris",
|
||||
"user_id":"alex",
|
||||
"hash":"62bc074f56d1f909f1b4c2b639f56f6a",
|
||||
"metadata":null,
|
||||
"created_at":"2023-02-25T23:57:00.108347-07:00",
|
||||
"updated_at":"2024-07-25T23:57:00.108367-07:00"
|
||||
}
|
||||
]
|
||||
```
|
||||
</CodeGroup>
|
||||
</Tab>
|
||||
|
||||
<Tab title="v2 Get Memories">
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
memories = m.get_all(
|
||||
filters={
|
||||
"AND": [
|
||||
{
|
||||
"user_id": "alex"
|
||||
},
|
||||
{
|
||||
"created_at": {
|
||||
"gte": "2024-07-01",
|
||||
"lte": "2024-07-31"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
version="v2"
|
||||
)
|
||||
```
|
||||
|
||||
```json Output
|
||||
[
|
||||
{
|
||||
"id":"f38b689d-6b24-45b7-bced-17fbb4d8bac7",
|
||||
"memory":"Name: Alex. Vegetarian. Allergic to nuts.",
|
||||
"user_id":"alex",
|
||||
"hash":"62bc074f56d1f909f1b4c2b639f56f6a",
|
||||
"metadata":null,
|
||||
"created_at":"2024-07-25T23:57:00.108347-07:00",
|
||||
"updated_at":"2024-07-25T23:57:00.108367-07:00"
|
||||
}
|
||||
]
|
||||
```
|
||||
</CodeGroup>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
Key difference between v1 and v2 get memories:
|
||||
|
||||
• **Filters**: v2 allows you to apply filters to narrow down memory retrieval based on specific criteria. This includes support for complex logical operations (AND, OR) and comparison operators (IN, gte, lte, gt, lt, ne, icontains) for advanced filtering capabilities.
|
||||
|
||||
The v2 get memories API is more powerful and flexible, allowing for more precise memory retrieval without the need for a search query.
|
||||
@@ -0,0 +1,85 @@
|
||||
---
|
||||
title: 'V2 Search Memories'
|
||||
openapi: post /v2/memories/search/
|
||||
---
|
||||
|
||||
Mem0 offers two versions of the search API: v1 and v2. Here's how they differ:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="v1 Search">
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
related_memories = m.search(query="What are Alice's hobbies?", user_id="alice")
|
||||
```
|
||||
|
||||
```json Output
|
||||
[
|
||||
{
|
||||
"id":"ea925981-272f-40dd-b576-be64e4871429",
|
||||
"memory":"Likes to play cricket and plays cricket on weekends.",
|
||||
"hash":"c8809002-25c1-4c97-a3a2-227ce9c20c53",
|
||||
"metadata":{
|
||||
"category":"hobbies"
|
||||
},
|
||||
"score":0.32116443111457704,
|
||||
"created_at":"2024-07-26T10:29:36.630547-07:00",
|
||||
"updated_at":"None",
|
||||
"user_id":"alice"
|
||||
}
|
||||
]
|
||||
```
|
||||
</CodeGroup>
|
||||
</Tab>
|
||||
|
||||
<Tab title="v2 Search">
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
related_memories = m.vsearch(
|
||||
query="What are Alice's hobbies?",
|
||||
filters={
|
||||
"AND":[
|
||||
{
|
||||
"user_id":"alice"
|
||||
},
|
||||
{
|
||||
"agent_id":{
|
||||
"in":[
|
||||
"travelling",
|
||||
"sports"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
version="v2"
|
||||
)
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"memories": [
|
||||
{
|
||||
"id": "ea925981-272f-40dd-b576-be64e4871429",
|
||||
"memory": "Likes to play cricket and plays cricket on weekends.",
|
||||
"hash": "c8809002-25c1-4c97-a3a2-227ce9c20c53",
|
||||
"metadata": {
|
||||
"category": "hobbies"
|
||||
},
|
||||
"score": 0.32116443111457704,
|
||||
"created_at": "2024-07-26T10:29:36.630547-07:00",
|
||||
"updated_at": null,
|
||||
"user_id": "alice",
|
||||
"agent_id": "sports"
|
||||
}
|
||||
],
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
Key difference between v1 and v2 search:
|
||||
|
||||
• **Filters**: v2 allows you to apply filters to narrow down search results based on specific criteria. This includes support for complex logical operations (AND, OR) and comparison operators (IN, gte, lte, gt, lt, ne, icontains) for advanced filtering capabilities.
|
||||
|
||||
The v2 search API is more powerful and flexible, allowing for more precise memory retrieval.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: 'Add Member'
|
||||
openapi: post /api/v1/orgs/organizations/{org_id}/members/
|
||||
---
|
||||
|
||||
The API provides two roles for organization members:
|
||||
|
||||
- `READER`: Allows viewing of organization resources.
|
||||
- `OWNER`: Grants full administrative access to manage the organization and its resources.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Create Organization'
|
||||
openapi: post /api/v1/orgs/organizations/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Delete Member'
|
||||
openapi: delete /api/v1/orgs/organizations/{org_id}/members/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Delete Organization'
|
||||
openapi: delete /api/v1/orgs/organizations/{org_id}/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Get Members'
|
||||
openapi: get /api/v1/orgs/organizations/{org_id}/members/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Get Organization'
|
||||
openapi: get /api/v1/orgs/organizations/{org_id}/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Get Organizations'
|
||||
openapi: get /api/v1/orgs/organizations/
|
||||
---
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: 'Update Member'
|
||||
openapi: put /api/v1/orgs/organizations/{org_id}/members/
|
||||
---
|
||||
|
||||
The API provides two roles for organization members:
|
||||
|
||||
- `READER`: Allows viewing of organization resources.
|
||||
- `OWNER`: Grants full administrative access to manage the organization and its resources.
|
||||
@@ -0,0 +1,69 @@
|
||||
# Mem0 API Overview
|
||||
|
||||
Mem0 provides a powerful set of APIs that allow you to integrate advanced memory management capabilities into your applications. Our APIs are designed to be intuitive, efficient, and scalable, enabling you to create, retrieve, update, and delete memories across various entities such as users, agents, apps, and runs.
|
||||
|
||||
## Key Features
|
||||
|
||||
- **Memory Management**: Add, retrieve, update, and delete memories with ease.
|
||||
- **Entity-based Operations**: Perform operations on memories associated with specific users, agents, apps, or runs.
|
||||
- **Advanced Search**: Utilize our search API to find relevant memories based on various criteria.
|
||||
- **History Tracking**: Access the history of memory interactions for comprehensive analysis.
|
||||
- **User Management**: Manage user entities and their associated memories.
|
||||
|
||||
## API Structure
|
||||
|
||||
Our API is organized into several main categories:
|
||||
|
||||
1. **Memory APIs**: Core operations for managing individual memories and collections.
|
||||
2. **Entities APIs**: Manage different entity types (users, agents, etc.) and their associated memories.
|
||||
3. **Search API**: Advanced search functionality to retrieve relevant memories.
|
||||
4. **History API**: Track and retrieve the history of memory interactions.
|
||||
|
||||
## Authentication
|
||||
|
||||
All API requests require authentication using HTTP Basic Auth. Ensure you include your API key in the Authorization header of each request.
|
||||
|
||||
## Organizations and projects (optional)
|
||||
|
||||
Organizations and projects provide the following capabilities:
|
||||
|
||||
- **Multi-org/project Support**: Specify organization and project when initializing the Mem0 client to attribute API usage appropriately
|
||||
- **Member Management**: Control access to data through organization and project membership
|
||||
- **Access Control**: Only members can access memories and data within their organization/project scope
|
||||
- **Team Isolation**: Maintain data separation between different teams and projects for secure collaboration
|
||||
|
||||
Example with the mem0 Python package:
|
||||
|
||||
```python
|
||||
from mem0 import MemoryClient
|
||||
|
||||
# Recommended: Using organization and project IDs
|
||||
client = MemoryClient(
|
||||
org_id='YOUR_ORG_ID', # It can be found on the organization settings page in dashboard
|
||||
project_id='YOUR_PROJECT_ID',
|
||||
)
|
||||
```
|
||||
> **Note**: The use of `organization` and `project` parameters is deprecated and will be removed in version `0.1.40`. Please use `org_id` and `project_id` instead.
|
||||
|
||||
|
||||
Example with the mem0 Node.js package:
|
||||
|
||||
```javascript
|
||||
import { MemoryClient } from "mem0ai";
|
||||
|
||||
# Recommended: Using organization and project IDs
|
||||
const client = new MemoryClient({
|
||||
organizationId: "YOUR_ORG_ID",
|
||||
projectId: "YOUR_PROJECT_ID"
|
||||
});
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
To begin using the Mem0 API, you'll need to:
|
||||
|
||||
1. Sign up for a [Mem0 account](https://app.mem0.ai) and obtain your API key.
|
||||
2. Familiarize yourself with the API endpoints and their functionalities.
|
||||
3. Make your first API call to add or retrieve a memory.
|
||||
|
||||
Explore the detailed documentation for each API endpoint to learn more about request/response formats, parameters, and example usage.
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: 'Add Member'
|
||||
openapi: post /api/v1/orgs/organizations/{org_id}/projects/{project_id}/members/
|
||||
---
|
||||
|
||||
The API provides two roles for project members:
|
||||
|
||||
- `READER`: Allows viewing of project resources.
|
||||
- `OWNER`: Grants full administrative access to manage the project and its resources.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Create Project'
|
||||
openapi: post /api/v1/orgs/organizations/{org_id}/projects/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Delete Member'
|
||||
openapi: delete /api/v1/orgs/organizations/{org_id}/projects/{project_id}/members/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Delete Project'
|
||||
openapi: delete /api/v1/orgs/organizations/{org_id}/projects/{project_id}/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Get Members'
|
||||
openapi: get /api/v1/orgs/organizations/{org_id}/projects/{project_id}/members/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Get Project'
|
||||
openapi: get /api/v1/orgs/organizations/{org_id}/projects/{project_id}/
|
||||
---
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Get Projects'
|
||||
openapi: get /api/v1/orgs/organizations/{org_id}/projects/
|
||||
---
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: 'Update Member'
|
||||
openapi: put /api/v1/orgs/organizations/{org_id}/projects/{project_id}/members/
|
||||
---
|
||||
|
||||
The API provides two roles for project members:
|
||||
|
||||
- `READER`: Allows viewing of project resources.
|
||||
- `OWNER`: Grants full administrative access to manage the project and its resources.
|
||||
@@ -0,0 +1,61 @@
|
||||
## What is Config?
|
||||
|
||||
Config in mem0 is a dictionary that specifies the settings for your embedding models. It allows you to customize the behavior and connection details of your chosen embedder.
|
||||
|
||||
## How to Define Config
|
||||
|
||||
The config is defined as a Python dictionary with two main keys:
|
||||
- `embedder`: Specifies the embedder provider and its configuration
|
||||
- `provider`: The name of the embedder (e.g., "openai", "ollama")
|
||||
- `config`: A nested dictionary containing provider-specific settings
|
||||
|
||||
## How to Use Config
|
||||
|
||||
Here's a general example of how to use the config with mem0:
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx"
|
||||
|
||||
config = {
|
||||
"embedder": {
|
||||
"provider": "your_chosen_provider",
|
||||
"config": {
|
||||
# Provider-specific settings go here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Your text here", user_id="user", metadata={"category": "example"})
|
||||
```
|
||||
|
||||
## Why is Config Needed?
|
||||
|
||||
Config is essential for:
|
||||
1. Specifying which embedding model to use.
|
||||
2. Providing necessary connection details (e.g., model, api_key, embedding_dims).
|
||||
3. Ensuring proper initialization and connection to your chosen embedder.
|
||||
|
||||
## Master List of All Params in Config
|
||||
|
||||
Here's a comprehensive list of all parameters that can be used across different embedders:
|
||||
|
||||
| Parameter | Description |
|
||||
|-----------|-------------|
|
||||
| `model` | Embedding model to use |
|
||||
| `api_key` | API key of the provider |
|
||||
| `embedding_dims` | Dimensions of the embedding model |
|
||||
| `http_client_proxies` | Allow proxy server settings |
|
||||
| `ollama_base_url` | Base URL for the Ollama embedding model |
|
||||
| `model_kwargs` | Key-Value arguments for the Huggingface embedding model |
|
||||
| `azure_kwargs` | Key-Value arguments for the AzureOpenAI embedding model |
|
||||
| `openai_base_url` | Base URL for OpenAI API | OpenAI |
|
||||
| `vertex_credentials_json` | Path to the Google Cloud credentials JSON file for VertexAI |
|
||||
|
||||
|
||||
## Supported Embedding Models
|
||||
|
||||
For detailed information on configuring specific embedders, please visit the [Embedding Models](./models) section. There you'll find information for each supported embedder with provider-specific usage examples and configuration details.
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
title: Azure OpenAI
|
||||
---
|
||||
|
||||
To use Azure OpenAI embedding models, set the `EMBEDDING_AZURE_OPENAI_API_KEY`, `EMBEDDING_AZURE_DEPLOYMENT`, `EMBEDDING_AZURE_ENDPOINT` and `EMBEDDING_AZURE_API_VERSION` environment variables. You can obtain the Azure OpenAI API key from the Azure.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["EMBEDDING_AZURE_OPENAI_API_KEY"] = "your-api-key"
|
||||
os.environ["EMBEDDING_AZURE_DEPLOYMENT"] = "your-deployment-name"
|
||||
os.environ["EMBEDDING_AZURE_ENDPOINT"] = "your-api-base-url"
|
||||
os.environ["EMBEDDING_AZURE_API_VERSION"] = "version-to-use"
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your_api_key" # For LLM
|
||||
|
||||
|
||||
config = {
|
||||
"embedder": {
|
||||
"provider": "azure_openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-large"
|
||||
"azure_kwargs": {
|
||||
"api_version": "",
|
||||
"azure_deployment": "",
|
||||
"azure_endpoint": "",
|
||||
"api_key": "",
|
||||
"default_headers": {
|
||||
"CustomHeader": "your-custom-header",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("I'm visiting Paris", user_id="john")
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Azure OpenAI embedder:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `model` | The name of the embedding model to use | `text-embedding-3-small` |
|
||||
| `embedding_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `azure_kwargs` | The Azure OpenAI configs | `config_keys` |
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: Gemini
|
||||
---
|
||||
|
||||
To use Gemini embedding models, set the `GOOGLE_API_KEY` environment variables. You can obtain the Gemini API key from [here](https://aistudio.google.com/app/apikey).
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["GOOGLE_API_KEY"] = "key"
|
||||
os.environ["OPENAI_API_KEY"] = "your_api_key" # For LLM
|
||||
|
||||
config = {
|
||||
"embedder": {
|
||||
"provider": "gemini",
|
||||
"config": {
|
||||
"model": "models/text-embedding-004",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("I'm visiting Paris", user_id="john")
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Gemini embedder:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `model` | The name of the embedding model to use | `models/text-embedding-004` |
|
||||
| `embedding_dims` | Dimensions of the embedding model | `768` |
|
||||
| `api_key` | The Gemini API key | `None` |
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
title: Hugging Face
|
||||
---
|
||||
|
||||
You can use embedding models from Huggingface to run Mem0 locally.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your_api_key" # For LLM
|
||||
|
||||
config = {
|
||||
"embedder": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "multi-qa-MiniLM-L6-cos-v1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("I'm visiting Paris", user_id="john")
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Huggingface embedder:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `model` | The name of the model to use | `multi-qa-MiniLM-L6-cos-v1` |
|
||||
| `embedding_dims` | Dimensions of the embedding model | `selected_model_dimensions` |
|
||||
| `model_kwargs` | Additional arguments for the model | `None` |
|
||||
@@ -0,0 +1,32 @@
|
||||
You can use embedding models from Ollama to run Mem0 locally.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your_api_key" # For LLM
|
||||
|
||||
config = {
|
||||
"embedder": {
|
||||
"provider": "ollama",
|
||||
"config": {
|
||||
"model": "mxbai-embed-large"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("I'm visiting Paris", user_id="john")
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Ollama embedder:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `model` | The name of the OpenAI model to use | `nomic-embed-text` |
|
||||
| `embedding_dims` | Dimensions of the embedding model | `512` |
|
||||
| `ollama_base_url` | Base URL for ollama connection | `None` |
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
title: OpenAI
|
||||
---
|
||||
|
||||
To use OpenAI embedding models, set the `OPENAI_API_KEY` environment variable. You can obtain the OpenAI API key from the [OpenAI Platform](https://platform.openai.com/account/api-keys).
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your_api_key"
|
||||
|
||||
config = {
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-large"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("I'm visiting Paris", user_id="john")
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring OpenAI embedder:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `model` | The name of the embedding model to use | `text-embedding-3-small` |
|
||||
| `embedding_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `api_key` | The OpenAI API key | `None` |
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: Together
|
||||
---
|
||||
|
||||
To use Together embedding models, set the `TOGETHER_API_KEY` environment variable. You can obtain the Together API key from the [Together Platform](https://api.together.xyz/settings/api-keys).
|
||||
|
||||
### Usage
|
||||
|
||||
<Note> The `embedding_model_dims` parameter for `vector_store` should be set to `768` for Together embedder. </Note>
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["TOGETHER_API_KEY"] = "your_api_key"
|
||||
os.environ["OPENAI_API_KEY"] = "your_api_key" # For LLM
|
||||
|
||||
config = {
|
||||
"embedder": {
|
||||
"provider": "together",
|
||||
"config": {
|
||||
"model": "togethercomputer/m2-bert-80M-8k-retrieval"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("I'm visiting Paris", user_id="john")
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Together embedder:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `model` | The name of the embedding model to use | `togethercomputer/m2-bert-80M-8k-retrieval` |
|
||||
| `embedding_dims` | Dimensions of the embedding model | `768` |
|
||||
| `api_key` | The Together API key | `None` |
|
||||
@@ -0,0 +1,36 @@
|
||||
### Vertex AI
|
||||
|
||||
To use Google Cloud's Vertex AI for text embedding models, set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable to point to the path of your service account's credentials JSON file. These credentials can be created in the [Google Cloud Console](https://console.cloud.google.com/).
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
# Set the path to your Google Cloud credentials JSON file
|
||||
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "/path/to/your/credentials.json"
|
||||
os.environ["OPENAI_API_KEY"] = "your_api_key" # For LLM
|
||||
|
||||
config = {
|
||||
"embedder": {
|
||||
"provider": "vertexai",
|
||||
"config": {
|
||||
"model": "text-embedding-004"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("I'm visiting Paris", user_id="john")
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring the Vertex AI embedder:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| ------------------------- | ------------------------------------------------ | -------------------- |
|
||||
| `model` | The name of the Vertex AI embedding model to use | `text-embedding-004` |
|
||||
| `vertex_credentials_json` | Path to the Google Cloud credentials JSON file | `None` |
|
||||
| `embedding_dims` | Dimensions of the embedding model | `256` |
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: Overview
|
||||
---
|
||||
|
||||
Mem0 offers support for various embedding models, allowing users to choose the one that best suits their needs.
|
||||
|
||||
## Supported Embedders
|
||||
|
||||
See the list of supported embedders below.
|
||||
|
||||
<CardGroup cols={4}>
|
||||
<Card title="OpenAI" href="/components/embedders/models/openai"></Card>
|
||||
<Card title="Azure OpenAI" href="/components/embedders/models/azure_openai"></Card>
|
||||
<Card title="Ollama" href="/components/embedders/models/ollama"></Card>
|
||||
<Card title="Hugging Face" href="/components/embedders/models/huggingface"></Card>
|
||||
<Card title="Gemini" href="/components/embedders/models/gemini"></Card>
|
||||
<Card title="Vertex AI" href="/components/embedders/models/vertexai"></Card>
|
||||
<Card title="Together" href="/components/embedders/models/together"></Card>
|
||||
</CardGroup>
|
||||
|
||||
## Usage
|
||||
|
||||
To utilize a embedder, you must provide a configuration to customize its usage. If no configuration is supplied, a default configuration will be applied, and `OpenAI` will be used as the embedder.
|
||||
|
||||
For a comprehensive list of available parameters for embedder configuration, please refer to [Config](./config).
|
||||
@@ -0,0 +1,79 @@
|
||||
## What is Config?
|
||||
|
||||
Config in mem0 is a dictionary that specifies the settings for your llms. It allows you to customize the behavior and connection details of your chosen llm.
|
||||
|
||||
## How to Define Config
|
||||
|
||||
The config is defined as a Python dictionary with two main keys:
|
||||
- `llm`: Specifies the llm provider and its configuration
|
||||
- `provider`: The name of the llm (e.g., "openai", "groq")
|
||||
- `config`: A nested dictionary containing provider-specific settings
|
||||
|
||||
### Config Values Precedence
|
||||
|
||||
Config values are applied in the following order of precedence (from highest to lowest):
|
||||
|
||||
1. Values explicitly set in the `config` dictionary
|
||||
2. Environment variables (e.g., `OPENAI_API_KEY`, `OPENAI_API_BASE`)
|
||||
3. Default values defined in the LLM implementation
|
||||
|
||||
This means that values specified in the `config` dictionary will override corresponding environment variables, which in turn override default values.
|
||||
|
||||
## How to Use Config
|
||||
|
||||
Here's a general example of how to use the config with mem0:
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx" # for embedder
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "your_chosen_provider",
|
||||
"config": {
|
||||
# Provider-specific settings go here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Your text here", user_id="user", metadata={"category": "example"})
|
||||
```
|
||||
|
||||
## Why is Config Needed?
|
||||
|
||||
Config is essential for:
|
||||
1. Specifying which llm to use.
|
||||
2. Providing necessary connection details (e.g., model, api_key, temperature).
|
||||
3. Ensuring proper initialization and connection to your chosen llm.
|
||||
|
||||
## Master List of All Params in Config
|
||||
|
||||
Here's a comprehensive list of all parameters that can be used across different llms:
|
||||
|
||||
Here's the table based on the provided parameters:
|
||||
|
||||
| Parameter | Description | Provider |
|
||||
|----------------------|-----------------------------------------------|-------------------|
|
||||
| `model` | Embedding model to use | All |
|
||||
| `temperature` | Temperature of the model | All |
|
||||
| `api_key` | API key to use | All |
|
||||
| `max_tokens` | Tokens to generate | All |
|
||||
| `top_p` | Probability threshold for nucleus sampling | All |
|
||||
| `top_k` | Number of highest probability tokens to keep | All |
|
||||
| `http_client_proxies`| Allow proxy server settings | AzureOpenAI |
|
||||
| `models` | List of models | Openrouter |
|
||||
| `route` | Routing strategy | Openrouter |
|
||||
| `openrouter_base_url`| Base URL for Openrouter API | Openrouter |
|
||||
| `site_url` | Site URL | Openrouter |
|
||||
| `app_name` | Application name | Openrouter |
|
||||
| `ollama_base_url` | Base URL for Ollama API | Ollama |
|
||||
| `openai_base_url` | Base URL for OpenAI API | OpenAI |
|
||||
| `azure_kwargs` | Azure LLM args for initialization | AzureOpenAI |
|
||||
|
||||
|
||||
## Supported LLMs
|
||||
|
||||
For detailed information on configuring specific llms, please visit the [LLMs](./models) section. There you'll find information for each supported llm with provider-specific usage examples and configuration details.
|
||||
@@ -0,0 +1,29 @@
|
||||
To use anthropic's models, please set the `ANTHROPIC_API_KEY` which you find on their [Account Settings Page](https://console.anthropic.com/account/keys).
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key" # used for embedding model
|
||||
os.environ["ANTHROPIC_API_KEY"] = "your-api-key"
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "anthropic",
|
||||
"config": {
|
||||
"model": "claude-3-5-sonnet-latest",
|
||||
"temperature": 0.1,
|
||||
"max_tokens": 2000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `anthropic` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
title: AWS Bedrock
|
||||
---
|
||||
|
||||
### Setup
|
||||
- Before using the AWS Bedrock LLM, make sure you have the appropriate model access from [Bedrock Console](https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/modelaccess).
|
||||
- You will also need to authenticate the `boto3` client by using a method in the [AWS documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html#configuring-credentials)
|
||||
- You will have to export `AWS_REGION`, `AWS_ACCESS_KEY`, and `AWS_SECRET_ACCESS_KEY` to set environment variables.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key" # used for embedding model
|
||||
os.environ['AWS_REGION'] = 'us-east-1'
|
||||
os.environ["AWS_ACCESS_KEY"] = "xx"
|
||||
os.environ["AWS_SECRET_ACCESS_KEY"] = "xx"
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "aws_bedrock",
|
||||
"config": {
|
||||
"model": "arn:aws:bedrock:us-east-1:123456789012:model/your-model-name",
|
||||
"temperature": 0.2,
|
||||
"max_tokens": 1500,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
All available parameters for the `aws_bedrock` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
title: Azure OpenAI
|
||||
---
|
||||
|
||||
To use Azure OpenAI models, you have to set the `LLM_AZURE_OPENAI_API_KEY`, `LLM_AZURE_ENDPOINT`, `LLM_AZURE_DEPLOYMENT` and `LLM_AZURE_API_VERSION` environment variables. You can obtain the Azure API key from the [Azure](https://azure.microsoft.com/).
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["LLM_AZURE_OPENAI_API_KEY"] = "your-api-key"
|
||||
os.environ["LLM_AZURE_DEPLOYMENT"] = "your-deployment-name"
|
||||
os.environ["LLM_AZURE_ENDPOINT"] = "your-api-base-url"
|
||||
os.environ["LLM_AZURE_API_VERSION"] = "version-to-use"
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "azure_openai",
|
||||
"config": {
|
||||
"model": "your-deployment-name",
|
||||
"temperature": 0.1,
|
||||
"max_tokens": 2000,
|
||||
"azure_kwargs": {
|
||||
"azure_deployment": "",
|
||||
"api_version": "",
|
||||
"azure_endpoint": "",
|
||||
"api_key": "",
|
||||
"default_headers": {
|
||||
"CustomHeader": "your-custom-header",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
We also support the new [OpenAI structured-outputs](https://platform.openai.com/docs/guides/structured-outputs/introduction) model.
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["LLM_AZURE_OPENAI_API_KEY"] = "your-api-key"
|
||||
os.environ["LLM_AZURE_DEPLOYMENT"] = "your-deployment-name"
|
||||
os.environ["LLM_AZURE_ENDPOINT"] = "your-api-base-url"
|
||||
os.environ["LLM_AZURE_API_VERSION"] = "version-to-use"
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "azure_openai_structured",
|
||||
"config": {
|
||||
"model": "your-deployment-name",
|
||||
"temperature": 0.1,
|
||||
"max_tokens": 2000,
|
||||
"azure_kwargs": {
|
||||
"azure_deployment": "",
|
||||
"api_version": "",
|
||||
"azure_endpoint": "",
|
||||
"api_key": "",
|
||||
"default_headers": {
|
||||
"CustomHeader": "your-custom-header",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `azure_openai` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
title: Gemini
|
||||
---
|
||||
|
||||
To use Gemini model, you have to set the `GEMINI_API_KEY` environment variable. You can obtain the Gemini API key from the [Google AI Studio](https://aistudio.google.com/app/apikey)
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key" # used for embedding model
|
||||
os.environ["GEMINI_API_KEY"] = "your-api-key"
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "gemini",
|
||||
"config": {
|
||||
"model": "gemini-1.5-flash-latest",
|
||||
"temperature": 0.2,
|
||||
"max_tokens": 1500,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `Gemini` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
title: Google AI
|
||||
---
|
||||
|
||||
To use Google AI model, you have to set the `GOOGLE_API_KEY` environment variable. You can obtain the Google API key from the [Google Maker Suite](https://makersuite.google.com/app/apikey)
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key" # used for embedding model
|
||||
os.environ["GEMINI_API_KEY"] = "your-api-key"
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "litellm",
|
||||
"config": {
|
||||
"model": "gemini/gemini-pro",
|
||||
"temperature": 0.2,
|
||||
"max_tokens": 1500,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `litellm` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -0,0 +1,31 @@
|
||||
[Groq](https://groq.com/) is the creator of the world's first Language Processing Unit (LPU), providing exceptional speed performance for AI workloads running on their LPU Inference Engine.
|
||||
|
||||
In order to use LLMs from Groq, go to their [platform](https://console.groq.com/keys) and get the API key. Set the API key as `GROQ_API_KEY` environment variable to use the model as given below in the example.
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key" # used for embedding model
|
||||
os.environ["GROQ_API_KEY"] = "your-api-key"
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "groq",
|
||||
"config": {
|
||||
"model": "mixtral-8x7b-32768",
|
||||
"temperature": 0.1,
|
||||
"max_tokens": 1000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `groq` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -0,0 +1,28 @@
|
||||
[Litellm](https://litellm.vercel.app/docs/) is compatible with over 100 large language models (LLMs), all using a standardized input/output format. You can explore the [available models](https://litellm.vercel.app/docs/providers) to use with Litellm. Ensure you set the `API_KEY` for the model you choose to use.
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key"
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "litellm",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
"temperature": 0.2,
|
||||
"max_tokens": 1500,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `litellm` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
title: Mistral AI
|
||||
---
|
||||
|
||||
To use mistral's models, please Obtain the Mistral AI api key from their [console](https://console.mistral.ai/). Set the `MISTRAL_API_KEY` environment variable to use the model as given below in the example.
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key" # used for embedding model
|
||||
os.environ["MISTRAL_API_KEY"] = "your-api-key"
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "litellm",
|
||||
"config": {
|
||||
"model": "open-mixtral-8x7b",
|
||||
"temperature": 0.1,
|
||||
"max_tokens": 2000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `litellm` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -0,0 +1,28 @@
|
||||
You can use LLMs from Ollama to run Mem0 locally. These [models](https://ollama.com/search?c=tools) support tool support.
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key" # for embedder
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "ollama",
|
||||
"config": {
|
||||
"model": "mixtral:8x7b",
|
||||
"temperature": 0.1,
|
||||
"max_tokens": 2000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `ollama` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
title: OpenAI
|
||||
---
|
||||
|
||||
To use OpenAI LLM models, you have to set the `OPENAI_API_KEY` environment variable. You can obtain the OpenAI API key from the [OpenAI Platform](https://platform.openai.com/account/api-keys).
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key"
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4o",
|
||||
"temperature": 0.2,
|
||||
"max_tokens": 1500,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Use Openrouter by passing it's api key
|
||||
# os.environ["OPENROUTER_API_KEY"] = "your-api-key"
|
||||
# config = {
|
||||
# "llm": {
|
||||
# "provider": "openai",
|
||||
# "config": {
|
||||
# "model": "meta-llama/llama-3.1-70b-instruct",
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
We also support the new [OpenAI structured-outputs](https://platform.openai.com/docs/guides/structured-outputs/introduction) model.
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key"
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "openai_structured",
|
||||
"config": {
|
||||
"model": "gpt-4o-2024-08-06",
|
||||
"temperature": 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `openai` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -0,0 +1,29 @@
|
||||
To use TogetherAI LLM models, you have to set the `TOGETHER_API_KEY` environment variable. You can obtain the TogetherAI API key from their [Account settings page](https://api.together.xyz/settings/api-keys).
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key" # used for embedding model
|
||||
os.environ["TOGETHER_API_KEY"] = "your-api-key"
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "together",
|
||||
"config": {
|
||||
"model": "mistralai/Mixtral-8x7B-Instruct-v0.1",
|
||||
"temperature": 0.2,
|
||||
"max_tokens": 1500,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `togetherai` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
title: Overview
|
||||
---
|
||||
|
||||
Mem0 includes built-in support for various popular large language models. Memory can utilize the LLM provided by the user, ensuring efficient use for specific needs.
|
||||
|
||||
## Usage
|
||||
|
||||
To use a llm, you must provide a configuration to customize its usage. If no configuration is supplied, a default configuration will be applied, and `OpenAI` will be used as the llm.
|
||||
|
||||
For a comprehensive list of available parameters for llm configuration, please refer to [Config](./config).
|
||||
|
||||
To view all supported llms, visit the [Supported LLMs](./models).
|
||||
|
||||
<CardGroup cols={4}>
|
||||
<Card title="OpenAI" href="/components/llms/models/openai"></Card>
|
||||
<Card title="Ollama" href="/components/llms/models/ollama"></Card>
|
||||
<Card title="Azure OpenAI" href="/components/llms/models/azure_openai"></Card>
|
||||
<Card title="Anthropic" href="/components/llms/models/anthropic"></Card>
|
||||
<Card title="Together" href="/components/llms/models/together"></Card>
|
||||
<Card title="Groq" href="/components/llms/models/groq"></Card>
|
||||
<Card title="Litellm" href="/components/llms/models/litellm"></Card>
|
||||
<Card title="Mistral AI" href="/components/llms/models/mistral_ai"></Card>
|
||||
<Card title="Google AI" href="/components/llms/models/google_ai"></Card>
|
||||
<Card title="AWS bedrock" href="/components/llms/models/aws_bedrock"></Card>
|
||||
<Card title="Gemini" href="/components/llms/models/gemini"></Card>
|
||||
</CardGroup>
|
||||
|
||||
## Structured vs Unstructured Outputs
|
||||
|
||||
Mem0 supports two types of OpenAI LLM formats, each with its own strengths and use cases:
|
||||
|
||||
### Structured Outputs
|
||||
|
||||
Structured outputs are LLMs that align with OpenAI's structured outputs model:
|
||||
|
||||
- **Optimized for:** Returning structured responses (e.g., JSON objects)
|
||||
- **Benefits:** Precise, easily parseable data
|
||||
- **Ideal for:** Data extraction, form filling, API responses
|
||||
- **Learn more:** [OpenAI Structured Outputs Guide](https://platform.openai.com/docs/guides/structured-outputs/introduction)
|
||||
|
||||
### Unstructured Outputs
|
||||
|
||||
Unstructured outputs correspond to OpenAI's standard, free-form text model:
|
||||
|
||||
- **Flexibility:** Returns open-ended, natural language responses
|
||||
- **Customization:** Use the `response_format` parameter to guide output
|
||||
- **Trade-off:** Less efficient than structured outputs for specific data needs
|
||||
- **Best for:** Creative writing, explanations, general conversation
|
||||
|
||||
Choose the format that best suits your application's requirements for optimal performance and usability.
|
||||
@@ -0,0 +1,72 @@
|
||||
## What is Config?
|
||||
|
||||
Config in mem0 is a dictionary that specifies the settings for your vector database. It allows you to customize the behavior and connection details of your chosen vector store.
|
||||
|
||||
## How to Define Config
|
||||
|
||||
The config is defined as a Python dictionary with two main keys:
|
||||
- `vector_store`: Specifies the vector database provider and its configuration
|
||||
- `provider`: The name of the vector database (e.g., "chroma", "pgvector", "qdrant", "milvus","azure_ai_search")
|
||||
- `config`: A nested dictionary containing provider-specific settings
|
||||
|
||||
## How to Use Config
|
||||
|
||||
Here's a general example of how to use the config with mem0:
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx"
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "your_chosen_provider",
|
||||
"config": {
|
||||
# Provider-specific settings go here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Your text here", user_id="user", metadata={"category": "example"})
|
||||
```
|
||||
|
||||
## Why is Config Needed?
|
||||
|
||||
Config is essential for:
|
||||
1. Specifying which vector database to use.
|
||||
2. Providing necessary connection details (e.g., host, port, credentials).
|
||||
3. Customizing database-specific settings (e.g., collection name, path).
|
||||
4. Ensuring proper initialization and connection to your chosen vector store.
|
||||
|
||||
## Master List of All Params in Config
|
||||
|
||||
Here's a comprehensive list of all parameters that can be used across different vector databases:
|
||||
|
||||
| Parameter | Description |
|
||||
|-----------|-------------|
|
||||
| `collection_name` | Name of the collection |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model |
|
||||
| `client` | Custom client for the database |
|
||||
| `path` | Path for the database |
|
||||
| `host` | Host where the server is running |
|
||||
| `port` | Port where the server is running |
|
||||
| `user` | Username for database connection |
|
||||
| `password` | Password for database connection |
|
||||
| `dbname` | Name of the database |
|
||||
| `url` | Full URL for the server |
|
||||
| `api_key` | API key for the server |
|
||||
| `on_disk` | Enable persistent storage |
|
||||
|
||||
## Customizing Config
|
||||
|
||||
Each vector database has its own specific configuration requirements. To customize the config for your chosen vector store:
|
||||
|
||||
1. Identify the vector database you want to use from [supported vector databases](./dbs).
|
||||
2. Refer to the `Config` section in the respective vector database's documentation.
|
||||
3. Include only the relevant parameters for your chosen database in the `config` dictionary.
|
||||
|
||||
## Supported Vector Databases
|
||||
|
||||
For detailed information on configuring specific vector databases, please visit the [Supported Vector Databases](./dbs) section. There you'll find individual pages for each supported vector store with provider-specific usage examples and configuration details.
|
||||
@@ -0,0 +1,38 @@
|
||||
[Azure AI Search](https://learn.microsoft.com/en-us/azure/search/search-what-is-azure-search/) (formerly known as "Azure Cognitive Search") provides secure information retrieval at scale over user-owned content in traditional and generative AI search applications.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx" #this key is used for embedding purpose
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "azure_ai_search",
|
||||
"config": {
|
||||
"service_name": "ai-search-test",
|
||||
"api_key": "*****",
|
||||
"collection_name": "mem0",
|
||||
"embedding_model_dims": 1536 ,
|
||||
"use_compression": False
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Let's see the available parameters for the `qdrant` config:
|
||||
service_name (str): Azure Cognitive Search service name.
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `service_name` | Azure AI Search service name | `None` |
|
||||
| `api_key` | API key of the Azure AI Search service | `None` |
|
||||
| `collection_name` | The name of the collection/index to store the vectors, it will be created automatically if not exist | `mem0` |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `use_compression` | Use scalar quantization vector compression | False |
|
||||
@@ -0,0 +1,35 @@
|
||||
[Chroma](https://www.trychroma.com/) is an AI-native open-source vector database that simplifies building LLM apps by providing tools for storing, embedding, and searching embeddings with a focus on simplicity and speed.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx"
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "test",
|
||||
"path": "db",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Chroma:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `collection_name` | The name of the collection | `mem0` |
|
||||
| `client` | Custom client for Chroma | `None` |
|
||||
| `path` | Path for the Chroma database | `db` |
|
||||
| `host` | The host where the Chroma server is running | `None` |
|
||||
| `port` | The port where the Chroma server is running | `None` |
|
||||
@@ -0,0 +1,35 @@
|
||||
[Milvus](https://milvus.io/) Milvus is an open-source vector database that suits AI applications of every size from running a demo chatbot in Jupyter notebook to building web-scale search that serves billions of users.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "milvus",
|
||||
"config": {
|
||||
"collection_name": "test",
|
||||
"embedding_model_dims": "123",
|
||||
"url": "127.0.0.1",
|
||||
"token": "8e4b8ca8cf2c67",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Here's the parameters available for configuring Milvus Database:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `url` | Full URL/Uri for Milvus/Zilliz server | `http://localhost:19530` |
|
||||
| `token` | Token for Zilliz server / for local setup defaults to None. | `None` |
|
||||
| `collection_name` | The name of the collection | `mem0` |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `metric_type` | Metric type for similarity search | `L2` |
|
||||
@@ -0,0 +1,40 @@
|
||||
[pgvector](https://github.com/pgvector/pgvector) is open-source vector similarity search for Postgres. After connecting with postgres run `CREATE EXTENSION IF NOT EXISTS vector;` to create the vector extension.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx"
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "pgvector",
|
||||
"config": {
|
||||
"user": "test",
|
||||
"password": "123",
|
||||
"host": "127.0.0.1",
|
||||
"port": "5432",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Here's the parameters available for configuring pgvector:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `dbname` | The name of the database | `postgres` |
|
||||
| `collection_name` | The name of the collection | `mem0` |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `user` | User name to connect to the database | `None` |
|
||||
| `password` | Password to connect to the database | `None` |
|
||||
| `host` | The host where the Postgres server is running | `None` |
|
||||
| `port` | The port where the Postgres server is running | `None` |
|
||||
| `diskann` | Whether to use diskann for vector similarity search (requires pgvectorscale) | `True` |
|
||||
@@ -0,0 +1,40 @@
|
||||
[Qdrant](https://qdrant.tech/) is an open-source vector search engine. It is designed to work with large-scale datasets and provides a high-performance search engine for vector data.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx"
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "qdrant",
|
||||
"config": {
|
||||
"collection_name": "test",
|
||||
"host": "localhost",
|
||||
"port": 6333,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Let's see the available parameters for the `qdrant` config:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `collection_name` | The name of the collection to store the vectors | `mem0` |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `client` | Custom client for qdrant | `None` |
|
||||
| `host` | The host where the qdrant server is running | `None` |
|
||||
| `port` | The port where the qdrant server is running | `None` |
|
||||
| `path` | Path for the qdrant database | `/tmp/qdrant` |
|
||||
| `url` | Full URL for the qdrant server | `None` |
|
||||
| `api_key` | API key for the qdrant server | `None` |
|
||||
| `on_disk` | For enabling persistent storage | `False` |
|
||||
@@ -0,0 +1,44 @@
|
||||
[Redis](https://redis.io/) is a scalable, real-time database that can store, search, and analyze vector data.
|
||||
|
||||
### Installation
|
||||
```bash
|
||||
pip install redis redisvl
|
||||
```
|
||||
|
||||
Redis Stack using Docker:
|
||||
```bash
|
||||
docker run -d --name redis-stack -p 6379:6379 -p 8001:8001 redis/redis-stack:latest
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx"
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "redis",
|
||||
"config": {
|
||||
"collection_name": "mem0",
|
||||
"embedding_model_dims": 1536,
|
||||
"redis_url": "redis://localhost:6379"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Let's see the available parameters for the `redis` config:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `collection_name` | The name of the collection to store the vectors | `mem0` |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `redis_url` | The URL of the Redis server | `None` |
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
title: Overview
|
||||
---
|
||||
|
||||
Mem0 includes built-in support for various popular databases. Memory can utilize the database provided by the user, ensuring efficient use for specific needs.
|
||||
|
||||
## Supported Vector Databases
|
||||
|
||||
See the list of supported vector databases below.
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Qdrant" href="/components/vectordbs/dbs/qdrant"></Card>
|
||||
<Card title="Chroma" href="/components/vectordbs/dbs/chroma"></Card>
|
||||
<Card title="Pgvector" href="/components/vectordbs/dbs/pgvector"></Card>
|
||||
<Card title="Milvus" href="/components/vectordbs/dbs/milvus"></Card>
|
||||
<Card title="Azure AI Search" href="/components/vectordbs/dbs/azure_ai_search"></Card>
|
||||
<Card title="Redis" href="/components/vectordbs/dbs/redis"></Card>
|
||||
</CardGroup>
|
||||
|
||||
## Usage
|
||||
|
||||
To utilize a vector database, you must provide a configuration to customize its usage. If no configuration is supplied, a default configuration will be applied, and `Qdrant` will be used as the vector database.
|
||||
|
||||
For a comprehensive list of available parameters for vector database configuration, please refer to [Config](./config).
|
||||
|
||||
## Common issues
|
||||
|
||||
### Using model with different dimensions
|
||||
|
||||
If you are using customized model, which is having different dimensions other than 1536
|
||||
for example 768, you may encounter below error:
|
||||
|
||||
`ValueError: shapes (0,1536) and (768,) not aligned: 1536 (dim 1) != 768 (dim 0)`
|
||||
|
||||
you could add `"embedding_model_dims": 768,` to the config of the vector_store to overcome this issue.
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
---
|
||||
title: AI Companion
|
||||
---
|
||||
|
||||
You can create a personalised AI Companion using Mem0. This guide will walk you through the necessary steps and provide the complete code to get you started.
|
||||
|
||||
## Overview
|
||||
|
||||
The Personalized AI Companion leverages Mem0 to retain information across interactions, enabling a tailored learning experience. It creates separate memories for both the user and the companion. By integrating with OpenAI's GPT-4 model, the companion can provide detailed and context-aware responses to user queries.
|
||||
|
||||
## Setup
|
||||
Before you begin, ensure you have the required dependencies installed. You can install the necessary packages using pip:
|
||||
|
||||
```bash
|
||||
pip install openai mem0ai
|
||||
```
|
||||
|
||||
## Full Code Example
|
||||
|
||||
Below is the complete code to create and interact with an AI Companion using Mem0:
|
||||
|
||||
```python
|
||||
from openai import OpenAI
|
||||
from mem0 import Memory
|
||||
import os
|
||||
|
||||
# Set the OpenAI API key
|
||||
os.environ['OPENAI_API_KEY'] = 'sk-xxx'
|
||||
|
||||
# Initialize the OpenAI client
|
||||
client = OpenAI()
|
||||
|
||||
class Companion:
|
||||
def __init__(self, user_id, companion_id):
|
||||
"""
|
||||
Initialize the Companion with memory configuration, OpenAI client, and user IDs.
|
||||
:param user_id: ID for storing user-related memories
|
||||
:param companion_id: ID for storing companion-related memories
|
||||
"""
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "qdrant",
|
||||
"config": {
|
||||
"host": "localhost",
|
||||
"port": 6333,
|
||||
}
|
||||
},
|
||||
}
|
||||
self.memory = Memory.from_config(config)
|
||||
self.client = client
|
||||
self.app_id = "app-1"
|
||||
self.USER_ID = user_id
|
||||
self.companion_id = companion_id
|
||||
|
||||
def analyze_question(self, question):
|
||||
"""
|
||||
Analyze the question to determine whether it's about the user or the companion.
|
||||
"""
|
||||
check_prompt = f"""
|
||||
Analyze the given input and determine whether the user is primarily:
|
||||
1) Talking about themselves or asking for personal advice. They may use words like "I" for this.
|
||||
2) Inquiring about the AI companions's capabilities or characteristics They may use words like "you" for this.
|
||||
|
||||
Respond with a single word:
|
||||
- 'user' if the input is focused on the user
|
||||
- 'companion' if the input is focused on the AI companion
|
||||
|
||||
If the input is ambiguous or doesn't clearly fit either category, respond with 'user'.
|
||||
|
||||
Input: {question}
|
||||
"""
|
||||
response = self.client.chat.completions.create(
|
||||
model="gpt-4",
|
||||
messages=[{"role": "user", "content": check_prompt}]
|
||||
)
|
||||
return response.choices[0].message.content
|
||||
|
||||
def ask(self, question):
|
||||
"""
|
||||
Ask a question to the AI and store the relevant facts in memory
|
||||
:param question: The question to ask the AI.
|
||||
"""
|
||||
check_answer = self.analyze_question(question)
|
||||
user_id_to_use = self.USER_ID if check_answer == "user" else self.companion_id
|
||||
|
||||
previous_memories = self.memory.search(question, user_id=user_id_to_use)
|
||||
relevant_memories_text = ""
|
||||
if previous_memories:
|
||||
relevant_memories_text = '\n'.join(mem["memory"] for mem in previous_memories)
|
||||
|
||||
prompt = f"User input: {question}\nPrevious {check_answer} memories: {relevant_memories_text}"
|
||||
|
||||
messages = [
|
||||
{
|
||||
"role": "system",
|
||||
"content": "You are the user's romantic companion. Use the user's input and previous memories to respond. Answer based on the context provided."
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": prompt
|
||||
}
|
||||
]
|
||||
|
||||
stream = self.client.chat.completions.create(
|
||||
model="gpt-4",
|
||||
stream=True,
|
||||
messages=messages
|
||||
)
|
||||
|
||||
answer = ""
|
||||
for chunk in stream:
|
||||
if chunk.choices[0].delta.content is not None:
|
||||
content = chunk.choices[0].delta.content
|
||||
print(content, end="")
|
||||
answer += content
|
||||
# Store the question and answer in memory
|
||||
self.memory.add(question, user_id=self.USER_ID, metadata={"app_id": self.app_id})
|
||||
self.memory.add(answer, user_id=self.companion_id, metadata={"app_id": self.app_id})
|
||||
|
||||
def get_memories(self, user_id=None):
|
||||
"""
|
||||
Retrieve all memories associated with the given user ID.
|
||||
:param user_id: Optional user ID to filter memories.
|
||||
:return: List of memories.
|
||||
"""
|
||||
return self.memory.get_all(user_id=user_id)
|
||||
|
||||
# Example usage:
|
||||
user_id = "user"
|
||||
companion_id = "companion"
|
||||
ai_companion = Companion(user_id, companion_id)
|
||||
|
||||
# Ask a question
|
||||
ai_companion.ask("Ive been missing you. What have you been up to off late?")
|
||||
```
|
||||
|
||||
### Fetching Memories
|
||||
|
||||
You can fetch all the memories at any point in time using the following code:
|
||||
|
||||
```python
|
||||
def print_memories(user_id, label):
|
||||
print(f"\n{label} Memories:")
|
||||
memories = ai_companion.get_memories(user_id=user_id)
|
||||
if memories:
|
||||
for m in memories:
|
||||
print(f"- {m['text']}")
|
||||
else:
|
||||
print("No memories found.")
|
||||
|
||||
# Print user memories
|
||||
print_memories(user_id, "User")
|
||||
|
||||
# Print companion memories
|
||||
print_memories(companion_id, "Companion")
|
||||
```
|
||||
|
||||
### Key Points
|
||||
|
||||
- **Initialization**: The Companion class is initialized with the necessary memory configuration and OpenAI client setup.
|
||||
- **Asking Questions**: The ask method sends a question to the AI and stores the relevant information in memory.
|
||||
- **Retrieving Memories**: The get_memories method fetches all stored memories associated with a user.
|
||||
|
||||
### Conclusion
|
||||
|
||||
As the conversation progresses, Mem0's memory automatically updates based on the interactions, providing a continuously improving personalized experience. This setup ensures that the AI Companion can offer contextually relevant and accurate responses, enhancing the user's experience.
|
||||
@@ -0,0 +1,109 @@
|
||||
---
|
||||
title: Customer Support AI Agent
|
||||
---
|
||||
|
||||
You can create a personalized Customer Support AI Agent using Mem0. This guide will walk you through the necessary steps and provide the complete code to get you started.
|
||||
|
||||
## Overview
|
||||
|
||||
The Customer Support AI Agent leverages Mem0 to retain information across interactions, enabling a personalized and efficient support experience.
|
||||
|
||||
## Setup
|
||||
|
||||
Install the necessary packages using pip:
|
||||
|
||||
```bash
|
||||
pip install openai mem0ai
|
||||
```
|
||||
|
||||
## Full Code Example
|
||||
|
||||
Below is the simplified code to create and interact with a Customer Support AI Agent using Mem0:
|
||||
|
||||
```python
|
||||
from openai import OpenAI
|
||||
from mem0 import Memory
|
||||
|
||||
# Set the OpenAI API key
|
||||
os.environ['OPENAI_API_KEY'] = 'sk-xxx'
|
||||
|
||||
class CustomerSupportAIAgent:
|
||||
def __init__(self):
|
||||
"""
|
||||
Initialize the CustomerSupportAIAgent with memory configuration and OpenAI client.
|
||||
"""
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "qdrant",
|
||||
"config": {
|
||||
"host": "localhost",
|
||||
"port": 6333,
|
||||
}
|
||||
},
|
||||
}
|
||||
self.memory = Memory.from_config(config)
|
||||
self.client = OpenAI()
|
||||
self.app_id = "customer-support"
|
||||
|
||||
def handle_query(self, query, user_id=None):
|
||||
"""
|
||||
Handle a customer query and store the relevant information in memory.
|
||||
|
||||
:param query: The customer query to handle.
|
||||
:param user_id: Optional user ID to associate with the memory.
|
||||
"""
|
||||
# Start a streaming chat completion request to the AI
|
||||
stream = self.client.chat.completions.create(
|
||||
model="gpt-4",
|
||||
stream=True,
|
||||
messages=[
|
||||
{"role": "system", "content": "You are a customer support AI agent."},
|
||||
{"role": "user", "content": query}
|
||||
]
|
||||
)
|
||||
# Store the query in memory
|
||||
self.memory.add(query, user_id=user_id, metadata={"app_id": self.app_id})
|
||||
|
||||
# Print the response from the AI in real-time
|
||||
for chunk in stream:
|
||||
if chunk.choices[0].delta.content is not None:
|
||||
print(chunk.choices[0].delta.content, end="")
|
||||
|
||||
def get_memories(self, user_id=None):
|
||||
"""
|
||||
Retrieve all memories associated with the given customer ID.
|
||||
|
||||
:param user_id: Optional user ID to filter memories.
|
||||
:return: List of memories.
|
||||
"""
|
||||
return self.memory.get_all(user_id=user_id)
|
||||
|
||||
# Instantiate the CustomerSupportAIAgent
|
||||
support_agent = CustomerSupportAIAgent()
|
||||
|
||||
# Define a customer ID
|
||||
customer_id = "jane_doe"
|
||||
|
||||
# Handle a customer query
|
||||
support_agent.handle_query("I need help with my recent order. It hasn't arrived yet.", user_id=customer_id)
|
||||
```
|
||||
|
||||
### Fetching Memories
|
||||
|
||||
You can fetch all the memories at any point in time using the following code:
|
||||
|
||||
```python
|
||||
memories = support_agent.get_memories(user_id=customer_id)
|
||||
for m in memories:
|
||||
print(m['text'])
|
||||
```
|
||||
|
||||
### Key Points
|
||||
|
||||
- **Initialization**: The CustomerSupportAIAgent class is initialized with the necessary memory configuration and OpenAI client setup.
|
||||
- **Handling Queries**: The handle_query method sends a query to the AI and stores the relevant information in memory.
|
||||
- **Retrieving Memories**: The get_memories method fetches all stored memories associated with a customer.
|
||||
|
||||
### Conclusion
|
||||
|
||||
As the conversation progresses, Mem0's memory automatically updates based on the interactions, providing a continuously improving personalized support experience.
|
||||
@@ -0,0 +1,172 @@
|
||||
---
|
||||
title: LlamaIndex ReAct Agent
|
||||
---
|
||||
Create a ReAct Agent with LlamaIndex which uses Mem0 as the memory store.
|
||||
|
||||
### Overview
|
||||
A ReAct agent combines reasoning and action capabilities, making it versatile for tasks requiring both thought processes (reasoning) and interaction with tools or APIs (acting). Mem0 as memory enhances these capabilities by allowing the agent to store and retrieve contextual information from past interactions.
|
||||
|
||||
### Setup
|
||||
```bash
|
||||
pip install llama-index-core llama-index-memory-mem0
|
||||
```
|
||||
|
||||
Initialize the LLM.
|
||||
```python
|
||||
import os
|
||||
from llama_index.llms.openai import OpenAI
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "<your-openai-api-key>"
|
||||
llm = OpenAI(model="gpt-4o")
|
||||
```
|
||||
|
||||
Initialize the Mem0 client. You can find your API key [here](https://app.mem0.ai/dashboard/). Read about Mem0 [Open Source](https://docs.mem0.ai/open-source/quickstart).
|
||||
```python
|
||||
os.environ["MEM0_API_KEY"] = "<your-mem0-api-key>"
|
||||
|
||||
from llama_index.memory.mem0 import Mem0Memory
|
||||
|
||||
context = {"user_id": "david"}
|
||||
memory_from_client = Mem0Memory.from_client(
|
||||
context=context,
|
||||
api_key=os.environ["MEM0_API_KEY"],
|
||||
search_msg_limit=4, # optional, default is 5
|
||||
)
|
||||
```
|
||||
|
||||
Create the tools. These tools will be used by the agent to perform actions.
|
||||
```python
|
||||
from llama_index.core.tools import FunctionTool
|
||||
|
||||
def call_fn(name: str):
|
||||
"""Call the provided name.
|
||||
Args:
|
||||
name: str (Name of the person)
|
||||
"""
|
||||
return f"Calling... {name}"
|
||||
|
||||
def email_fn(name: str):
|
||||
"""Email the provided name.
|
||||
Args:
|
||||
name: str (Name of the person)
|
||||
"""
|
||||
return f"Emailing... {name}"
|
||||
|
||||
def order_food(name: str, dish: str):
|
||||
"""Order food for the provided name.
|
||||
Args:
|
||||
name: str (Name of the person)
|
||||
dish: str (Name of the dish)
|
||||
"""
|
||||
return f"Ordering {dish} for {name}"
|
||||
|
||||
call_tool = FunctionTool.from_defaults(fn=call_fn)
|
||||
email_tool = FunctionTool.from_defaults(fn=email_fn)
|
||||
order_food_tool = FunctionTool.from_defaults(fn=order_food)
|
||||
```
|
||||
|
||||
Initialize the agent with tools and memory.
|
||||
```python
|
||||
from llama_index.core.agent import FunctionCallingAgent
|
||||
|
||||
agent = FunctionCallingAgent.from_tools(
|
||||
[call_tool, email_tool, order_food_tool],
|
||||
llm=llm,
|
||||
memory=memory_from_client, # or memory_from_config
|
||||
verbose=True,
|
||||
)
|
||||
```
|
||||
|
||||
Start the chat.
|
||||
<Note> The agent will use the Mem0 to store the relavant memories from the chat. </Note>
|
||||
|
||||
Input
|
||||
```python
|
||||
response = agent.chat("Hi, My name is David")
|
||||
print(response)
|
||||
```
|
||||
Output
|
||||
```text
|
||||
> Running step bf44a75a-a920-4cf3-944e-b6e6b5695043. Step input: Hi, My name is David
|
||||
Added user message to memory: Hi, My name is David
|
||||
=== LLM Response ===
|
||||
Hello, David! How can I assist you today?
|
||||
```
|
||||
|
||||
Input
|
||||
```python
|
||||
response = agent.chat("I love to eat pizza on weekends")
|
||||
print(response)
|
||||
```
|
||||
Output
|
||||
```text
|
||||
> Running step 845783b0-b85b-487c-baee-8460ebe8b38d. Step input: I love to eat pizza on weekends
|
||||
Added user message to memory: I love to eat pizza on weekends
|
||||
=== LLM Response ===
|
||||
Pizza is a great choice for the weekend! If you'd like, I can help you order some. Just let me know what kind of pizza you prefer!
|
||||
```
|
||||
Input
|
||||
```python
|
||||
response = agent.chat("My preferred way of communication is email")
|
||||
print(response)
|
||||
```
|
||||
Output
|
||||
```text
|
||||
> Running step 345842f0-f8a0-42ea-a1b7-612265d72a92. Step input: My preferred way of communication is email
|
||||
Added user message to memory: My preferred way of communication is email
|
||||
=== LLM Response ===
|
||||
Got it! If you need any assistance or have any requests, feel free to let me know, and I can communicate with you via email.
|
||||
```
|
||||
|
||||
### Using the agent WITHOUT memory
|
||||
Input
|
||||
```python
|
||||
agent = FunctionCallingAgent.from_tools(
|
||||
[call_tool, email_tool, order_food_tool],
|
||||
# memory is not provided
|
||||
llm=llm,
|
||||
verbose=True,
|
||||
)
|
||||
response = agent.chat("I am feeling hungry, order me something and send me the bill")
|
||||
print(response)
|
||||
```
|
||||
Output
|
||||
```text
|
||||
> Running step e89eb75d-75e1-4dea-a8c8-5c3d4b77882d. Step input: I am feeling hungry, order me something and send me the bill
|
||||
Added user message to memory: I am feeling hungry, order me something and send me the bill
|
||||
=== LLM Response ===
|
||||
Please let me know your name and the dish you'd like to order, and I'll take care of it for you!
|
||||
```
|
||||
<Note> The agent is not able to remember the past prefernces that user shared in previous chats. </Note>
|
||||
|
||||
### Using the agent WITH memory
|
||||
Input
|
||||
```python
|
||||
agent = FunctionCallingAgent.from_tools(
|
||||
[call_tool, email_tool, order_food_tool],
|
||||
llm=llm,
|
||||
# memory is provided
|
||||
memory=memory_from_client, # or memory_from_config
|
||||
verbose=True,
|
||||
)
|
||||
response = agent.chat("I am feeling hungry, order me something and send me the bill")
|
||||
print(response)
|
||||
```
|
||||
|
||||
Output
|
||||
```text
|
||||
> Running step 5e473db9-3973-4cb1-a5fd-860be0ab0006. Step input: I am feeling hungry, order me something and send me the bill
|
||||
Added user message to memory: I am feeling hungry, order me something and send me the bill
|
||||
=== Calling Function ===
|
||||
Calling function: order_food with args: {"name": "David", "dish": "pizza"}
|
||||
=== Function Output ===
|
||||
Ordering pizza for David
|
||||
=== Calling Function ===
|
||||
Calling function: email_fn with args: {"name": "David"}
|
||||
=== Function Output ===
|
||||
Emailing... David
|
||||
> Running step 38080544-6b37-4bb2-aab2-7670100d926e. Step input: None
|
||||
=== LLM Response ===
|
||||
I've ordered a pizza for you, and the bill has been sent to your email. Enjoy your meal! If there's anything else you need, feel free to let me know.
|
||||
```
|
||||
<Note> The agent is able to remember the past prefernces that user shared and use them to perform actions. </Note>
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
title: Mem0 with Ollama
|
||||
---
|
||||
|
||||
## Running Mem0 Locally with Ollama
|
||||
|
||||
Mem0 can be utilized entirely locally by leveraging Ollama for both the embedding model and the language model (LLM). This guide will walk you through the necessary steps and provide the complete code to get you started.
|
||||
|
||||
### Overview
|
||||
|
||||
By using Ollama, you can run Mem0 locally, which allows for greater control over your data and models. This setup uses Ollama for both the embedding model and the language model, providing a fully local solution.
|
||||
|
||||
### Setup
|
||||
|
||||
Before you begin, ensure you have Mem0 and Ollama installed and properly configured on your local machine.
|
||||
|
||||
### Full Code Example
|
||||
|
||||
Below is the complete code to set up and use Mem0 locally with Ollama:
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "qdrant",
|
||||
"config": {
|
||||
"collection_name": "test",
|
||||
"host": "localhost",
|
||||
"port": 6333,
|
||||
"embedding_model_dims": 768, # Change this according to your local model's dimensions
|
||||
},
|
||||
},
|
||||
"llm": {
|
||||
"provider": "ollama",
|
||||
"config": {
|
||||
"model": "llama3.1:latest",
|
||||
"temperature": 0,
|
||||
"max_tokens": 8000,
|
||||
"ollama_base_url": "http://localhost:11434", # Ensure this URL is correct
|
||||
},
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "ollama",
|
||||
"config": {
|
||||
"model": "nomic-embed-text:latest",
|
||||
# Alternatively, you can use "snowflake-arctic-embed:latest"
|
||||
"ollama_base_url": "http://localhost:11434",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
# Initialize Memory with the configuration
|
||||
m = Memory.from_config(config)
|
||||
|
||||
# Add a memory
|
||||
m.add("I'm visiting Paris", user_id="john")
|
||||
|
||||
# Retrieve memories
|
||||
memories = m.get_all(user_id="john")
|
||||
```
|
||||
|
||||
### Key Points
|
||||
|
||||
- **Configuration**: The setup involves configuring the vector store, language model, and embedding model to use local resources.
|
||||
- **Vector Store**: Qdrant is used as the vector store, running on localhost.
|
||||
- **Language Model**: Ollama is used as the LLM provider, with the "llama3.1:latest" model.
|
||||
- **Embedding Model**: Ollama is also used for embeddings, with the "nomic-embed-text:latest" model.
|
||||
|
||||
### Conclusion
|
||||
|
||||
This local setup of Mem0 using Ollama provides a fully self-contained solution for memory management and AI interactions. It allows for greater control over your data and models while still leveraging the powerful capabilities of Mem0.
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
title: Overview
|
||||
description: How to use mem0 in your existing applications?
|
||||
---
|
||||
|
||||
|
||||
With Mem0, you can create stateful LLM-based applications such as chatbots, virtual assistants, or AI agents. Mem0 enhances your applications by providing a memory layer that makes responses:
|
||||
|
||||
- More personalized
|
||||
- More reliable
|
||||
- Cost-effective by reducing the number of LLM interactions
|
||||
- More engaging
|
||||
- Enables long-term memory
|
||||
|
||||
Here are some examples of how Mem0 can be integrated into various applications:
|
||||
|
||||
## Examples
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Mem0 with Ollama" icon="square-1" href="/examples/mem0-with-ollama">
|
||||
Run Mem0 locally with Ollama.
|
||||
</Card>
|
||||
<Card title="Personal AI Tutor" icon="square-2" href="/examples/personal-ai-tutor">
|
||||
Create a Personalized AI Tutor that adapts to student progress and learning preferences.
|
||||
</Card>
|
||||
<Card title="Personal Travel Assistant" icon="square-3" href="/examples/personal-travel-assistant">
|
||||
Build a Personalized AI Travel Assistant that understands your travel preferences and past itineraries.
|
||||
</Card>
|
||||
<Card title="Customer Support Agent" icon="square-4" href="/examples/customer-support-agent">
|
||||
Develop a Personal AI Assistant that remembers user preferences, past interactions, and context to provide personalized and efficient assistance.
|
||||
</Card>
|
||||
<Card title="LlamaIndex Mem0" icon="square-5" href="/examples/llama-index-mem0">
|
||||
Create a ReAct Agent with LlamaIndex which uses Mem0 as the memory store.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,111 @@
|
||||
---
|
||||
title: Personalized AI Tutor
|
||||
---
|
||||
|
||||
You can create a personalized AI Tutor using Mem0. This guide will walk you through the necessary steps and provide the complete code to get you started.
|
||||
|
||||
## Overview
|
||||
|
||||
The Personalized AI Tutor leverages Mem0 to retain information across interactions, enabling a tailored learning experience. By integrating with OpenAI's GPT-4 model, the tutor can provide detailed and context-aware responses to user queries.
|
||||
|
||||
## Setup
|
||||
Before you begin, ensure you have the required dependencies installed. You can install the necessary packages using pip:
|
||||
|
||||
```bash
|
||||
pip install openai mem0ai
|
||||
```
|
||||
|
||||
## Full Code Example
|
||||
|
||||
Below is the complete code to create and interact with a Personalized AI Tutor using Mem0:
|
||||
|
||||
```python
|
||||
from openai import OpenAI
|
||||
from mem0 import Memory
|
||||
|
||||
# Set the OpenAI API key
|
||||
os.environ['OPENAI_API_KEY'] = 'sk-xxx'
|
||||
|
||||
# Initialize the OpenAI client
|
||||
client = OpenAI()
|
||||
|
||||
class PersonalAITutor:
|
||||
def __init__(self):
|
||||
"""
|
||||
Initialize the PersonalAITutor with memory configuration and OpenAI client.
|
||||
"""
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "qdrant",
|
||||
"config": {
|
||||
"host": "localhost",
|
||||
"port": 6333,
|
||||
}
|
||||
},
|
||||
}
|
||||
self.memory = Memory.from_config(config)
|
||||
self.client = client
|
||||
self.app_id = "app-1"
|
||||
|
||||
def ask(self, question, user_id=None):
|
||||
"""
|
||||
Ask a question to the AI and store the relevant facts in memory
|
||||
|
||||
:param question: The question to ask the AI.
|
||||
:param user_id: Optional user ID to associate with the memory.
|
||||
"""
|
||||
# Start a streaming chat completion request to the AI
|
||||
stream = self.client.chat.completions.create(
|
||||
model="gpt-4",
|
||||
stream=True,
|
||||
messages=[
|
||||
{"role": "system", "content": "You are a personal AI Tutor."},
|
||||
{"role": "user", "content": question}
|
||||
]
|
||||
)
|
||||
# Store the question in memory
|
||||
self.memory.add(question, user_id=user_id, metadata={"app_id": self.app_id})
|
||||
|
||||
# Print the response from the AI in real-time
|
||||
for chunk in stream:
|
||||
if chunk.choices[0].delta.content is not None:
|
||||
print(chunk.choices[0].delta.content, end="")
|
||||
|
||||
def get_memories(self, user_id=None):
|
||||
"""
|
||||
Retrieve all memories associated with the given user ID.
|
||||
|
||||
:param user_id: Optional user ID to filter memories.
|
||||
:return: List of memories.
|
||||
"""
|
||||
return self.memory.get_all(user_id=user_id)
|
||||
|
||||
# Instantiate the PersonalAITutor
|
||||
ai_tutor = PersonalAITutor()
|
||||
|
||||
# Define a user ID
|
||||
user_id = "john_doe"
|
||||
|
||||
# Ask a question
|
||||
ai_tutor.ask("I am learning introduction to CS. What is queue? Briefly explain.", user_id=user_id)
|
||||
```
|
||||
|
||||
### Fetching Memories
|
||||
|
||||
You can fetch all the memories at any point in time using the following code:
|
||||
|
||||
```python
|
||||
memories = ai_tutor.get_memories(user_id=user_id)
|
||||
for m in memories:
|
||||
print(m['text'])
|
||||
```
|
||||
|
||||
### Key Points
|
||||
|
||||
- **Initialization**: The PersonalAITutor class is initialized with the necessary memory configuration and OpenAI client setup.
|
||||
- **Asking Questions**: The ask method sends a question to the AI and stores the relevant information in memory.
|
||||
- **Retrieving Memories**: The get_memories method fetches all stored memories associated with a user.
|
||||
|
||||
### Conclusion
|
||||
|
||||
As the conversation progresses, Mem0's memory automatically updates based on the interactions, providing a continuously improving personalized learning experience. This setup ensures that the AI Tutor can offer contextually relevant and accurate responses, enhancing the overall educational process.
|
||||
@@ -0,0 +1,195 @@
|
||||
---
|
||||
title: Personal AI Travel Assistant
|
||||
---
|
||||
Create a personalized AI Travel Assistant using Mem0. This guide provides step-by-step instructions and the complete code to get you started.
|
||||
|
||||
## Overview
|
||||
|
||||
The Personalized AI Travel Assistant uses Mem0 to store and retrieve information across interactions, enabling a tailored travel planning experience. It integrates with OpenAI's GPT-4 model to provide detailed and context-aware responses to user queries.
|
||||
|
||||
## Setup
|
||||
|
||||
Install the required dependencies using pip:
|
||||
|
||||
```bash
|
||||
pip install openai mem0ai
|
||||
```
|
||||
|
||||
## Full Code Example
|
||||
|
||||
Here's the complete code to create and interact with a Personalized AI Travel Assistant using Mem0:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python After v1.1
|
||||
import os
|
||||
from openai import OpenAI
|
||||
from mem0 import Memory
|
||||
|
||||
# Set the OpenAI API key
|
||||
os.environ['OPENAI_API_KEY'] = "sk-xxx"
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4o",
|
||||
"temperature": 0.1,
|
||||
"max_tokens": 2000,
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-large"
|
||||
}
|
||||
},
|
||||
"vector_store": {
|
||||
"provider": "qdrant",
|
||||
"config": {
|
||||
"collection_name": "test",
|
||||
"embedding_model_dims": 3072,
|
||||
}
|
||||
},
|
||||
"version": "v1.1",
|
||||
}
|
||||
|
||||
class PersonalTravelAssistant:
|
||||
def __init__(self):
|
||||
self.client = OpenAI()
|
||||
self.memory = Memory.from_config(config)
|
||||
self.messages = [{"role": "system", "content": "You are a personal AI Assistant."}]
|
||||
|
||||
def ask_question(self, question, user_id):
|
||||
# Fetch previous related memories
|
||||
previous_memories = self.search_memories(question, user_id=user_id)
|
||||
prompt = question
|
||||
if previous_memories:
|
||||
prompt = f"User input: {question}\n Previous memories: {previous_memories}"
|
||||
self.messages.append({"role": "user", "content": prompt})
|
||||
|
||||
# Generate response using GPT-4o
|
||||
response = self.client.chat.completions.create(
|
||||
model="gpt-4o",
|
||||
messages=self.messages
|
||||
)
|
||||
answer = response.choices[0].message.content
|
||||
self.messages.append({"role": "assistant", "content": answer})
|
||||
|
||||
# Store the question in memory
|
||||
self.memory.add(question, user_id=user_id)
|
||||
return answer
|
||||
|
||||
def get_memories(self, user_id):
|
||||
memories = self.memory.get_all(user_id=user_id)
|
||||
return [m['memory'] for m in memories['memories']]
|
||||
|
||||
def search_memories(self, query, user_id):
|
||||
memories = self.memory.search(query, user_id=user_id)
|
||||
return [m['memory'] for m in memories['memories']]
|
||||
|
||||
# Usage example
|
||||
user_id = "traveler_123"
|
||||
ai_assistant = PersonalTravelAssistant()
|
||||
|
||||
def main():
|
||||
while True:
|
||||
question = input("Question: ")
|
||||
if question.lower() in ['q', 'exit']:
|
||||
print("Exiting...")
|
||||
break
|
||||
|
||||
answer = ai_assistant.ask_question(question, user_id=user_id)
|
||||
print(f"Answer: {answer}")
|
||||
memories = ai_assistant.get_memories(user_id=user_id)
|
||||
print("Memories:")
|
||||
for memory in memories:
|
||||
print(f"- {memory}")
|
||||
print("-----")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
|
||||
```python Before v1.1
|
||||
import os
|
||||
from openai import OpenAI
|
||||
from mem0 import Memory
|
||||
|
||||
# Set the OpenAI API key
|
||||
os.environ['OPENAI_API_KEY'] = 'sk-xxx'
|
||||
|
||||
class PersonalTravelAssistant:
|
||||
def __init__(self):
|
||||
self.client = OpenAI()
|
||||
self.memory = Memory()
|
||||
self.messages = [{"role": "system", "content": "You are a personal AI Assistant."}]
|
||||
|
||||
def ask_question(self, question, user_id):
|
||||
# Fetch previous related memories
|
||||
previous_memories = self.search_memories(question, user_id=user_id)
|
||||
prompt = question
|
||||
if previous_memories:
|
||||
prompt = f"User input: {question}\n Previous memories: {previous_memories}"
|
||||
self.messages.append({"role": "user", "content": prompt})
|
||||
|
||||
# Generate response using GPT-4o
|
||||
response = self.client.chat.completions.create(
|
||||
model="gpt-4o",
|
||||
messages=self.messages
|
||||
)
|
||||
answer = response.choices[0].message.content
|
||||
self.messages.append({"role": "assistant", "content": answer})
|
||||
|
||||
# Store the question in memory
|
||||
self.memory.add(question, user_id=user_id)
|
||||
return answer
|
||||
|
||||
def get_memories(self, user_id):
|
||||
memories = self.memory.get_all(user_id=user_id)
|
||||
return [m['memory'] for m in memories['memories']]
|
||||
|
||||
def search_memories(self, query, user_id):
|
||||
memories = self.memory.search(query, user_id=user_id)
|
||||
return [m['memory'] for m in memories['memories']]
|
||||
|
||||
# Usage example
|
||||
user_id = "traveler_123"
|
||||
ai_assistant = PersonalTravelAssistant()
|
||||
|
||||
def main():
|
||||
while True:
|
||||
question = input("Question: ")
|
||||
if question.lower() in ['q', 'exit']:
|
||||
print("Exiting...")
|
||||
break
|
||||
|
||||
answer = ai_assistant.ask_question(question, user_id=user_id)
|
||||
print(f"Answer: {answer}")
|
||||
memories = ai_assistant.get_memories(user_id=user_id)
|
||||
print("Memories:")
|
||||
for memory in memories:
|
||||
print(f"- {memory}")
|
||||
print("-----")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
|
||||
## Key Components
|
||||
|
||||
- **Initialization**: The `PersonalTravelAssistant` class is initialized with the OpenAI client and Mem0 memory setup.
|
||||
- **Asking Questions**: The `ask_question` method sends a question to the AI, incorporates previous memories, and stores new information.
|
||||
- **Memory Management**: The `get_memories` and search_memories methods handle retrieval and searching of stored memories.
|
||||
|
||||
## Usage
|
||||
|
||||
1. Set your OpenAI API key in the environment variable.
|
||||
2. Instantiate the `PersonalTravelAssistant`.
|
||||
3. Use the `main()` function to interact with the assistant in a loop.
|
||||
|
||||
## Conclusion
|
||||
|
||||
This Personalized AI Travel Assistant leverages Mem0's memory capabilities to provide context-aware responses. As you interact with it, the assistant learns and improves, offering increasingly personalized travel advice and information.
|
||||
@@ -0,0 +1,49 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.95343 21.1394C4.89586 21.1304 2.25471 19.458 0.987296 16.2895C-0.280118 13.121 0.108924 9.16314 1.74363 5.61505C4.8012 5.62409 7.44235 7.29648 8.70976 10.465C9.97718 13.6335 9.58814 17.5914 7.95343 21.1394Z" fill="white"/>
|
||||
<path d="M7.95343 21.1394C4.89586 21.1304 2.25471 19.458 0.987296 16.2895C-0.280118 13.121 0.108924 9.16314 1.74363 5.61505C4.8012 5.62409 7.44235 7.29648 8.70976 10.465C9.97718 13.6335 9.58814 17.5914 7.95343 21.1394Z" fill="url(#paint0_radial_101_2703)"/>
|
||||
<path d="M7.95343 21.1394C4.89586 21.1304 2.25471 19.458 0.987296 16.2895C-0.280118 13.121 0.108924 9.16314 1.74363 5.61505C4.8012 5.62409 7.44235 7.29648 8.70976 10.465C9.97718 13.6335 9.58814 17.5914 7.95343 21.1394Z" fill="black" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M7.95343 21.1394C4.89586 21.1304 2.25471 19.458 0.987296 16.2895C-0.280118 13.121 0.108924 9.16314 1.74363 5.61505C4.8012 5.62409 7.44235 7.29648 8.70976 10.465C9.97718 13.6335 9.58814 17.5914 7.95343 21.1394Z" fill="url(#paint1_linear_101_2703)" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M8.68359 10.4755C9.94543 13.63 9.56145 17.5723 7.9354 21.1112C4.89702 21.0957 2.27411 19.4306 1.01347 16.279C-0.248375 13.1245 0.135612 9.18218 1.76165 5.64328C4.80004 5.65883 7.42295 7.32386 8.68359 10.4755Z" stroke="url(#paint2_linear_101_2703)" stroke-opacity="0.05" stroke-width="0.056338"/>
|
||||
<path d="M7.31038 21.2574C11.3543 20.2215 14.8836 17.3754 16.6285 13.2361C18.3735 9.09671 17.9448 4.58749 15.8598 0.976291C11.8159 2.01214 8.2866 4.85826 6.54167 8.99762C4.79674 13.137 5.2254 17.6462 7.31038 21.2574Z" fill="white"/>
|
||||
<path d="M7.31038 21.2574C11.3543 20.2215 14.8836 17.3754 16.6285 13.2361C18.3735 9.09671 17.9448 4.58749 15.8598 0.976291C11.8159 2.01214 8.2866 4.85826 6.54167 8.99762C4.79674 13.137 5.2254 17.6462 7.31038 21.2574Z" fill="url(#paint3_radial_101_2703)"/>
|
||||
<path d="M16.6026 13.2251C14.8642 17.349 11.3512 20.1866 7.32411 21.2248C5.25257 17.624 4.82926 13.1324 6.56764 9.00855C8.30603 4.88472 11.819 2.04706 15.8461 1.00889C17.9176 4.60967 18.3409 9.10131 16.6026 13.2251Z" stroke="url(#paint4_linear_101_2703)" stroke-opacity="0.05" stroke-width="0.056338"/>
|
||||
<path d="M7.23368 21.2069C9.78906 23.2373 13.2102 23.9506 16.5772 22.8141C19.9441 21.6775 22.5058 18.9445 23.7304 15.6382C21.175 13.6078 17.7538 12.8944 14.3869 14.031C11.0199 15.1676 8.45822 17.9006 7.23368 21.2069Z" fill="white"/>
|
||||
<path d="M7.23368 21.2069C9.78906 23.2373 13.2102 23.9506 16.5772 22.8141C19.9441 21.6775 22.5058 18.9445 23.7304 15.6382C21.175 13.6078 17.7538 12.8944 14.3869 14.031C11.0199 15.1676 8.45822 17.9006 7.23368 21.2069Z" fill="url(#paint5_radial_101_2703)"/>
|
||||
<path d="M7.23368 21.2069C9.78906 23.2373 13.2102 23.9506 16.5772 22.8141C19.9441 21.6775 22.5058 18.9445 23.7304 15.6382C21.175 13.6078 17.7538 12.8944 14.3869 14.031C11.0199 15.1676 8.45822 17.9006 7.23368 21.2069Z" fill="black" fill-opacity="0.2" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M7.23368 21.2069C9.78906 23.2373 13.2102 23.9506 16.5772 22.8141C19.9441 21.6775 22.5058 18.9445 23.7304 15.6382C21.175 13.6078 17.7538 12.8944 14.3869 14.031C11.0199 15.1676 8.45822 17.9006 7.23368 21.2069Z" fill="url(#paint6_linear_101_2703)" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M16.5682 22.7874C13.2176 23.9184 9.81361 23.2124 7.2672 21.1975C8.49194 17.9068 11.0444 15.189 14.3959 14.0577C17.7465 12.9266 21.1504 13.6326 23.6968 15.6476C22.4721 18.9383 19.9196 21.656 16.5682 22.7874Z" stroke="url(#paint7_linear_101_2703)" stroke-opacity="0.05" stroke-width="0.056338"/>
|
||||
<defs>
|
||||
<radialGradient id="paint0_radial_101_2703" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(-3.00503 15.023) rotate(-10.029) scale(17.9572 17.784)">
|
||||
<stop stop-color="#00B0BB"/>
|
||||
<stop offset="1" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint1_linear_101_2703" x1="7.39036" y1="4.81308" x2="1.62975" y2="18.6894" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#18E299"/>
|
||||
<stop offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_101_2703" x1="7.94816" y1="8.01563" x2="1.7612" y2="18.746" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint3_radial_101_2703" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(8.11404 20.8822) rotate(-75.7542) scale(21.6246 23.7772)">
|
||||
<stop stop-color="#00BBBB"/>
|
||||
<stop offset="0.712616" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint4_linear_101_2703" x1="7.60205" y1="5.8709" x2="15.5561" y2="16.3719" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint5_radial_101_2703" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(7.84537 21.5181) rotate(-20.3525) scale(18.5603 17.32)">
|
||||
<stop stop-color="#00B0BB"/>
|
||||
<stop offset="1" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint6_linear_101_2703" x1="16.8078" y1="13.0071" x2="10.0409" y2="22.9937" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00B1BC"/>
|
||||
<stop offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint7_linear_101_2703" x1="16.8078" y1="13.0071" x2="14.1687" y2="23.841" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
@@ -0,0 +1,59 @@
|
||||
---
|
||||
title: Features
|
||||
---
|
||||
|
||||
## Core features
|
||||
|
||||
- **User, Session, and AI Agent Memory**: Retains information across sessions and interactions for users and AI agents, ensuring continuity and context.
|
||||
- **Adaptive Personalization**: Continuously updates memories based on user interactions and feedback.
|
||||
- **Developer-Friendly API**: Offers a straightforward API for seamless integration into various applications.
|
||||
- **Platform Consistency**: Ensures consistent behavior and data across different platforms and devices.
|
||||
- **Managed Service**: Provides a hosted solution for easy deployment and maintenance.
|
||||
- **Save Costs**: Saves costs by adding relevent memories instead of complete transcripts to context window
|
||||
|
||||
|
||||
|
||||
## How does Mem0 work?
|
||||
|
||||
Mem0 leverages a hybrid database approach to manage and retrieve long-term memories for AI agents and assistants. Each memory is associated with a unique identifier, such as a user ID or agent ID, allowing Mem0 to organize and access memories specific to an individual or context.
|
||||
|
||||
When a message is added to the Mem0 using add() method, the system extracts relevant facts and preferences and stores it across data stores: a vector database, a key-value database, and a graph database. This hybrid approach ensures that different types of information are stored in the most efficient manner, making subsequent searches quick and effective.
|
||||
|
||||
When an AI agent or LLM needs to recall memories, it uses the search() method. Mem0 then performs search across these data stores, retrieving relevant information from each source. This information is then passed through a scoring layer, which evaluates their importance based on relevance, importance, and recency. This ensures that only the most personalized and useful context is surfaced.
|
||||
|
||||
The retrieved memories can then be appended to the LLM's prompt as needed, making responses personalized and relevant.
|
||||
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
- **Personalized Learning Assistants**: Long-term memory allows learning assistants to remember user preferences, strengths and weaknesses, and progress, providing a more tailored and effective learning experience.
|
||||
|
||||
- **Customer Support AI Agents**: By retaining information from previous interactions, customer support bots can offer more accurate and context-aware assistance, improving customer satisfaction and reducing resolution times.
|
||||
|
||||
- **Healthcare Assistants**: Long-term memory enables healthcare assistants to keep track of patient history, medication schedules, and treatment plans, ensuring personalized and consistent care.
|
||||
|
||||
- **Virtual Companions**: Virtual companions can use long-term memory to build deeper relationships with users by remembering personal details, preferences, and past conversations, making interactions more delightful.
|
||||
|
||||
- **Productivity Tools**: Long-term memory helps productivity tools remember user habits, frequently used documents, and task history, streamlining workflows and enhancing efficiency.
|
||||
|
||||
- **Gaming AI**: In gaming, AI with long-term memory can create more immersive experiences by remembering player choices, strategies, and progress, adapting the game environment accordingly.
|
||||
|
||||
## How is Mem0 different from RAG?
|
||||
|
||||
Mem0's memory implementation for Large Language Models (LLMs) offers several advantages over Retrieval-Augmented Generation (RAG):
|
||||
|
||||
- **Entity Relationships**: Mem0 can understand and relate entities across different interactions, unlike RAG which retrieves information from static documents. This leads to a deeper understanding of context and relationships.
|
||||
|
||||
- **Recency, Relevancy, and Decay**: Mem0 uses custom search algorithms to prioritize recent interactions and gradually forgets outdated information, ensuring the memory remains relevant and up-to-date for more accurate responses.
|
||||
|
||||
- **Contextual Continuity**: Mem0 retains information across sessions, maintaining continuity in conversations and interactions, which is essential for long-term engagement applications like virtual companions or personalized learning assistants.
|
||||
|
||||
- **Adaptive Learning**: Mem0 improves its personalization based on user interactions and feedback, making the memory more accurate and tailored to individual users over time.
|
||||
|
||||
- **Dynamic Updates**: Mem0 can dynamically update its memory with new information and interactions, unlike RAG which relies on static data. This allows for real-time adjustments and improvements, enhancing the user experience.
|
||||
|
||||
These advanced memory capabilities make Mem0 a powerful tool for developers aiming to create personalized and context-aware AI applications.
|
||||
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -0,0 +1,172 @@
|
||||
---
|
||||
title: Async Client
|
||||
description: 'Asynchronous client for Mem0'
|
||||
---
|
||||
|
||||
The `AsyncMemoryClient` is an asynchronous client for interacting with the Mem0 API. It provides similar functionality to the synchronous `MemoryClient` but allows for non-blocking operations, which can be beneficial in applications that require high concurrency.
|
||||
|
||||
## Initialization
|
||||
|
||||
To use the async client, you first need to initialize it:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
from mem0 import AsyncMemoryClient
|
||||
client = AsyncMemoryClient(api_key="your-api-key")
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
const { MemoryClient } = require('mem0ai');
|
||||
const client = new MemoryClient('your-api-key');
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## Methods
|
||||
|
||||
The `AsyncMemoryClient` provides the following methods:
|
||||
|
||||
### Add
|
||||
|
||||
Add a new memory asynchronously.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
messages = [
|
||||
{"role": "user", "content": "Alice loves playing badminton"},
|
||||
{"role": "assistant", "content": "That's great! Alice is a fitness freak"},
|
||||
]
|
||||
await client.add(messages, user_id="alice")
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
const messages = [
|
||||
{"role": "user", "content": "Alice loves playing badminton"},
|
||||
{"role": "assistant", "content": "That's great! Alice is a fitness freak"},
|
||||
];
|
||||
await client.add(messages, { user_id: "alice" });
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
### Search
|
||||
|
||||
Search for memories based on a query asynchronously.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
await client.search(query="What is Alice's favorite sport?", user_id="alice")
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
await client.search("What is Alice's favorite sport?", { user_id: "alice" });
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
### Get All
|
||||
|
||||
Retrieve all memories for a user asynchronously.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
await client.get_all(user_id="alice")
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
await client.getAll({ user_id: "alice" });
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
### Delete
|
||||
|
||||
Delete a specific memory asynchronously.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
await client.delete(memory_id="memory-id-here")
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
await client.delete("memory-id-here");
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
### Delete All
|
||||
|
||||
Delete all memories for a user asynchronously.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
await client.delete_all(user_id="alice")
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
await client.deleteAll({ user_id: "alice" });
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
### History
|
||||
|
||||
Get the history of a specific memory asynchronously.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
await client.history(memory_id="memory-id-here")
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
await client.history("memory-id-here");
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
### Users
|
||||
|
||||
Get all users, agents, and runs which have memories associated with them asynchronously.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
await client.users()
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
await client.users();
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
### Reset
|
||||
|
||||
Reset the client, deleting all users and memories asynchronously.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
await client.reset()
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
await client.reset();
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## Conclusion
|
||||
|
||||
The `AsyncMemoryClient` provides a powerful way to interact with the Mem0 API asynchronously, allowing for more efficient and responsive applications. By using this client, you can perform memory operations without blocking your application's execution.
|
||||
|
||||
If you have any questions or need further assistance, please don't hesitate to reach out:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -0,0 +1,71 @@
|
||||
---
|
||||
title: Custom Categories
|
||||
description: 'Enhance your product experience by adding custom categories tailored to your needs'
|
||||
---
|
||||
|
||||
## How to set custom categories?
|
||||
|
||||
Users can now create custom categories tailored to their specific needs, in addition to the default categories such as travel, sports, music, and more.
|
||||
To setup the custom categories, user has to specify the category name and a description of what that category signifies.
|
||||
Here’s how you can do it:
|
||||
|
||||
```python
|
||||
from mem0 import MemoryClient
|
||||
|
||||
m = MemoryClient(api_key="xxx")
|
||||
|
||||
custom_categories = [
|
||||
{"cooking": "For users interested in cooking, including recipes, cooking tips, and culinary experiences."},
|
||||
{"fitness": "Includes content related to fitness, such as workouts, exercises, and fitness tips."}
|
||||
]
|
||||
|
||||
messages = [
|
||||
{"role" : "user", "content" : "Hi, my name is Alice. I love to play badminton."},
|
||||
{"role" : "assistant", "content" : "Hello Alice! It's nice to meet you. Badminton is such an amazing sport. How can I assist you today?"},
|
||||
{"role" : "user", "content" : "I am a fitness freak, I go to gym daily."},
|
||||
{"role" : "assistant", "content" : "That's great! Regular exercise is very beneficial for health."},
|
||||
{"role" : "user", "content" : "Because of my gym plan, I mostly cook at home."},
|
||||
{"role" : "assistant", "content" : "Cooking at home is a good way to ensure you have a balanced diet."}
|
||||
]
|
||||
```
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
client.add(messages, user_id="alice", custom_categories=custom_categories)
|
||||
```
|
||||
|
||||
```markdown Memories with categories
|
||||
User's name is Alice (personal_details)
|
||||
Loves playing badminton (sports)
|
||||
User is a fitness freak. (fitness)
|
||||
Likes to go to gym daily. (fitness)
|
||||
Mostly cook at home because of gym plan. (fitness, cooking)
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
> Note: The more detailed the description of categories is, the better output the user will receive.
|
||||
|
||||
## Default Categories
|
||||
Here is the list of **default categories**. Ensure you review these before creating custom categories to prevent duplication.
|
||||
|
||||
```
|
||||
- personal_details
|
||||
- family
|
||||
- professional_details
|
||||
- sports
|
||||
- travel
|
||||
- food
|
||||
- music
|
||||
- health
|
||||
- technology
|
||||
- hobbies
|
||||
- fashion
|
||||
- entertainment
|
||||
- milestones
|
||||
- user_preferences
|
||||
- misc
|
||||
```
|
||||
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -0,0 +1,109 @@
|
||||
---
|
||||
title: Custom Prompts
|
||||
description: 'Enhance your product experience by adding custom prompts tailored to your needs'
|
||||
---
|
||||
|
||||
## Introduction to Custom Prompts
|
||||
|
||||
Custom prompts allow you to tailor the behavior of your Mem0 instance to specific use cases or domains.
|
||||
By defining a custom prompt, you can control how information is extracted, processed, and stored in your memory system.
|
||||
|
||||
To create an effective custom prompt:
|
||||
1. Be specific about the information to extract.
|
||||
2. Provide few-shot examples to guide the LLM.
|
||||
3. Ensure examples follow the format shown below.
|
||||
|
||||
Example of a custom prompt:
|
||||
|
||||
```python
|
||||
custom_prompt = """
|
||||
Please only extract entities containing customer support information, order details, and user information.
|
||||
Here are some few shot examples:
|
||||
|
||||
Input: Hi.
|
||||
Output: {{"facts" : []}}
|
||||
|
||||
Input: The weather is nice today.
|
||||
Output: {{"facts" : []}}
|
||||
|
||||
Input: My order #12345 hasn't arrived yet.
|
||||
Output: {{"facts" : ["Order #12345 not received"]}}
|
||||
|
||||
Input: I'm John Doe, and I'd like to return the shoes I bought last week.
|
||||
Output: {{"facts" : ["Customer name: John Doe", "Wants to return shoes", "Purchase made last week"]}}
|
||||
|
||||
Input: I ordered a red shirt, size medium, but received a blue one instead.
|
||||
Output: {{"facts" : ["Ordered red shirt, size medium", "Received blue shirt instead"]}}
|
||||
|
||||
Return the facts and customer information in a json format as shown above.
|
||||
"""
|
||||
|
||||
```
|
||||
|
||||
Here we initialize the custom prompt in the config.
|
||||
|
||||
```python
|
||||
from mem0 import Memory
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4o",
|
||||
"temperature": 0.2,
|
||||
"max_tokens": 1500,
|
||||
}
|
||||
},
|
||||
"custom_prompt": custom_prompt,
|
||||
"version": "v1.1"
|
||||
}
|
||||
|
||||
m = Memory.from_config(config_dict=config, user_id="alice")
|
||||
```
|
||||
|
||||
### Example 1
|
||||
|
||||
In this example, we are adding a memory of a user ordering a laptop. As seen in the output, the custom prompt is used to extract the relevant information from the user's message.
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
m.add("Yesterday, I ordered a laptop, the order id is 12345", user_id="alice")
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"memory": "Ordered a laptop",
|
||||
"event": "ADD"
|
||||
},
|
||||
{
|
||||
"memory": "Order ID: 12345",
|
||||
"event": "ADD"
|
||||
},
|
||||
{
|
||||
"memory": "Order placed yesterday",
|
||||
"event": "ADD"
|
||||
}
|
||||
],
|
||||
"relations": []
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Example 2
|
||||
|
||||
In this example, we are adding a memory of a user liking to go on hikes. This add message is not specific to the use-case mentioned in the custom prompt.
|
||||
Hence, the memory is not added.
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
m.add("I like going to hikes", user_id="alice")
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [],
|
||||
"relations": []
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -0,0 +1,102 @@
|
||||
---
|
||||
title: Direct Import
|
||||
description: 'Bypass the memory deduction phase and directly store pre-defined memories for efficient retrieval'
|
||||
---
|
||||
|
||||
## How to use Direct Import?
|
||||
The Direct Import feature allows users to skip the memory deduction phase and directly input pre-defined memories into the system for storage and retrieval.
|
||||
To enable this feature, you need to set the `infer` parameter to `False` in the `add` method.
|
||||
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
|
||||
```python Python
|
||||
messages = [
|
||||
{"role": "user", "content": "Alice loves playing badminton"},
|
||||
{"role": "assistant", "content": "That's great! Alice is a fitness freak"},
|
||||
{"role": "user", "content": "Alice mostly cook at home because of gym plan"},
|
||||
]
|
||||
|
||||
|
||||
client.add(messages, user_id="alice", infer=False)
|
||||
```
|
||||
|
||||
```markdown Output
|
||||
[]
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
You can see that the output of add call is an empty list.
|
||||
|
||||
<Note> Only messages with the role "user" will be used for storage. Messages with roles such as "assistant" or "system" will be ignored during the storage process. </Note>
|
||||
|
||||
|
||||
## How to retrieve memories?
|
||||
|
||||
You can retrieve memories using the `search` method.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
client.search(query="What is Alice's favorite sport?", user_id="alice", output_format="v1.1")
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": "19d6d7aa-2454-4e58-96fc-e74d9e9f8dd1",
|
||||
"memory": "Alice loves playing badminton",
|
||||
"user_id": "pc123",
|
||||
"metadata": null,
|
||||
"categories": null,
|
||||
"created_at": "2024-10-15T21:52:11.474901-07:00",
|
||||
"updated_at": "2024-10-15T21:52:11.474912-07:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## How to retrieve all memories?
|
||||
|
||||
You can retrieve all memories using the `get_all` method.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
client.get_all(query="What is Alice's favorite sport?", user_id="alice", output_format="v1.1")
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": "19d6d7aa-2454-4e58-96fc-e74d9e9f8dd1",
|
||||
"memory": "Alice loves playing badminton",
|
||||
"user_id": "pc123",
|
||||
"metadata": null,
|
||||
"categories": null,
|
||||
"created_at": "2024-10-15T21:52:11.474901-07:00",
|
||||
"updated_at": "2024-10-15T21:52:11.474912-07:00"
|
||||
},
|
||||
{
|
||||
"id": "8557f05d-7b3c-47e5-b409-9886f9e314fc",
|
||||
"memory": "Alice mostly cook at home because of gym plan",
|
||||
"user_id": "pc123",
|
||||
"metadata": null,
|
||||
"categories": null,
|
||||
"created_at": "2024-10-15T21:52:11.474929-07:00",
|
||||
"updated_at": "2024-10-15T21:52:11.474932-07:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -0,0 +1,328 @@
|
||||
---
|
||||
title: Langchain Tools
|
||||
description: 'Integrate Mem0 with LangChain tools to enable AI agents to store, search, and manage memories through structured interfaces'
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Mem0 provides a suite of tools for storing, searching, and retrieving memories, enabling agents to maintain context and learn from past interactions. The tools are built as Langchain tools, making them easily integrable with any AI agent implementation.
|
||||
|
||||
## Installation
|
||||
|
||||
Install the required dependencies:
|
||||
|
||||
```bash
|
||||
pip install langchain_core
|
||||
pip install mem0ai
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
Import the necessary dependencies and initialize the client:
|
||||
|
||||
```python
|
||||
from langchain_core.tools import StructuredTool
|
||||
from mem0 import MemoryClient
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import List, Dict, Any, Optional
|
||||
|
||||
client = MemoryClient(
|
||||
"---",
|
||||
org_id="---",
|
||||
project_id="---"
|
||||
)
|
||||
```
|
||||
|
||||
## Available Tools
|
||||
|
||||
Mem0 provides three main tools for memory management:
|
||||
|
||||
### 1. ADD Memory Tool
|
||||
|
||||
The ADD tool allows you to store new memories with associated metadata. It's particularly useful for saving conversation history and user preferences.
|
||||
|
||||
#### Schema
|
||||
|
||||
```python
|
||||
class Message(BaseModel):
|
||||
role: str = Field(description="Role of the message sender (user or assistant)")
|
||||
content: str = Field(description="Content of the message")
|
||||
|
||||
class AddMemoryInput(BaseModel):
|
||||
messages: List[Message] = Field(description="List of messages to add to memory")
|
||||
user_id: str = Field(description="ID of the user associated with these messages")
|
||||
output_format: str = Field(description="Version format for the output")
|
||||
metadata: Optional[Dict[str, Any]] = Field(description="Additional metadata for the messages", default=None)
|
||||
|
||||
class Config:
|
||||
json_schema_extra = {
|
||||
"examples": [{
|
||||
"messages": [
|
||||
{"role": "user", "content": "Hi, I'm Alex. I'm a vegetarian and I'm allergic to nuts."},
|
||||
{"role": "assistant", "content": "Hello Alex! I've noted that you're a vegetarian and have a nut allergy."}
|
||||
],
|
||||
"user_id": "alex",
|
||||
"output_format": "v1.1",
|
||||
"metadata": {"food": "vegan"}
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
#### Implementation
|
||||
|
||||
```python
|
||||
def add_memory(messages: List[Message], user_id: str, output_format: str, metadata: Optional[Dict[str, Any]] = None) -> Any:
|
||||
"""Add messages to memory with associated user ID and metadata."""
|
||||
message_dicts = [msg.dict() for msg in messages]
|
||||
return client.add(message_dicts, user_id=user_id, output_format=output_format, metadata=metadata)
|
||||
|
||||
add_tool = StructuredTool(
|
||||
name="add_memory",
|
||||
description="Add new messages to memory with associated metadata",
|
||||
func=add_memory,
|
||||
args_schema=AddMemoryInput
|
||||
)
|
||||
```
|
||||
|
||||
#### Example Usage
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
add_input = {
|
||||
"messages": [
|
||||
{"role": "user", "content": "Hi, I'm Alex. I'm a vegetarian and I'm allergic to nuts."},
|
||||
{"role": "assistant", "content": "Hello Alex! I've noted that you're a vegetarian and have a nut allergy."}
|
||||
],
|
||||
"user_id": "alex123",
|
||||
"output_format": "v1.1",
|
||||
"metadata": {"food": "vegan"}
|
||||
}
|
||||
add_result = add_tool.invoke(add_input)
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"memory": "Name is Alex",
|
||||
"event": "ADD"
|
||||
},
|
||||
{
|
||||
"memory": "Is a vegetarian",
|
||||
"event": "ADD"
|
||||
},
|
||||
{
|
||||
"memory": "Is allergic to nuts",
|
||||
"event": "ADD"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### 2. SEARCH Memory Tool
|
||||
|
||||
The SEARCH tool enables querying stored memories using natural language queries and advanced filtering options.
|
||||
|
||||
#### Schema
|
||||
|
||||
```python
|
||||
class SearchMemoryInput(BaseModel):
|
||||
query: str = Field(description="The search query string")
|
||||
filters: Dict[str, Any] = Field(description="Filters to apply to the search")
|
||||
version: str = Field(description="Version of the memory to search")
|
||||
|
||||
class Config:
|
||||
json_schema_extra = {
|
||||
"examples": [{
|
||||
"query": "tell me about my allergies?",
|
||||
"filters": {
|
||||
"AND": [
|
||||
{"user_id": "alex"},
|
||||
{"created_at": {"gte": "2024-01-01", "lte": "2024-12-31"}}
|
||||
]
|
||||
},
|
||||
"version": "v2"
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
#### Implementation
|
||||
|
||||
```python
|
||||
def search_memory(query: str, filters: Dict[str, Any], version: str) -> Any:
|
||||
"""Search memory with the given query and filters."""
|
||||
return client.search(query=query, version=version, filters=filters)
|
||||
|
||||
search_tool = StructuredTool(
|
||||
name="search_memory",
|
||||
description="Search through memories with a query and filters",
|
||||
func=search_memory,
|
||||
args_schema=SearchMemoryInput
|
||||
)
|
||||
```
|
||||
|
||||
#### Example Usage
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
search_input = {
|
||||
"query": "what is my name?",
|
||||
"filters": {
|
||||
"AND": [
|
||||
{"created_at": {"gte": "2024-07-20", "lte": "2024-12-10"}},
|
||||
{"user_id": "alex123"}
|
||||
]
|
||||
},
|
||||
"version": "v2"
|
||||
}
|
||||
result = search_tool.invoke(search_input)
|
||||
```
|
||||
|
||||
```json Output
|
||||
[
|
||||
{
|
||||
"id": "1a75e827-7eca-45ea-8c5c-cfd43299f061",
|
||||
"memory": "Name is Alex",
|
||||
"user_id": "alex123",
|
||||
"hash": "d0fccc8fa47f7a149ee95750c37bb0ca",
|
||||
"metadata": {
|
||||
"food": "vegan"
|
||||
},
|
||||
"categories": [
|
||||
"personal_details"
|
||||
],
|
||||
"created_at": "2024-11-27T16:53:43.276872-08:00",
|
||||
"updated_at": "2024-11-27T16:53:43.276885-08:00",
|
||||
"score": 0.3810526501504994
|
||||
}
|
||||
]
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### 3. GET_ALL Memory Tool
|
||||
|
||||
The GET_ALL tool retrieves all memories matching specified criteria, with support for pagination.
|
||||
|
||||
#### Schema
|
||||
|
||||
```python
|
||||
class GetAllMemoryInput(BaseModel):
|
||||
version: str = Field(description="Version of the memory to retrieve")
|
||||
filters: Dict[str, Any] = Field(description="Filters to apply to the retrieval")
|
||||
page: Optional[int] = Field(description="Page number for pagination", default=1)
|
||||
page_size: Optional[int] = Field(description="Number of items per page", default=50)
|
||||
|
||||
class Config:
|
||||
json_schema_extra = {
|
||||
"examples": [{
|
||||
"version": "v2",
|
||||
"filters": {
|
||||
"AND": [
|
||||
{"user_id": "alex"},
|
||||
{"created_at": {"gte": "2024-07-01", "lte": "2024-07-31"}},
|
||||
{"categories": {"contains": "food_preferences"}}
|
||||
]
|
||||
},
|
||||
"page": 1,
|
||||
"page_size": 50
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
#### Implementation
|
||||
|
||||
```python
|
||||
def get_all_memory(version: str, filters: Dict[str, Any], page: int = 1, page_size: int = 50) -> Any:
|
||||
"""Retrieve all memories matching the specified criteria."""
|
||||
return client.get_all(version=version, filters=filters, page=page, page_size=page_size)
|
||||
|
||||
get_all_tool = StructuredTool(
|
||||
name="get_all_memory",
|
||||
description="Retrieve all memories matching specified filters",
|
||||
func=get_all_memory,
|
||||
args_schema=GetAllMemoryInput
|
||||
)
|
||||
```
|
||||
|
||||
#### Example Usage
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
get_all_input = {
|
||||
"version": "v2",
|
||||
"filters": {
|
||||
"AND": [
|
||||
{"user_id": "alex123"},
|
||||
{"created_at": {"gte": "2024-07-01", "lte": "2024-12-31"}}
|
||||
]
|
||||
},
|
||||
"page": 1,
|
||||
"page_size": 50
|
||||
}
|
||||
get_all_result = get_all_tool.invoke(get_all_input)
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"count": 3,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"id": "1a75e827-7eca-45ea-8c5c-cfd43299f061",
|
||||
"memory": "Name is Alex",
|
||||
"user_id": "alex123",
|
||||
"hash": "d0fccc8fa47f7a149ee95750c37bb0ca",
|
||||
"metadata": {
|
||||
"food": "vegan"
|
||||
},
|
||||
"categories": [
|
||||
"personal_details"
|
||||
],
|
||||
"created_at": "2024-11-27T16:53:43.276872-08:00",
|
||||
"updated_at": "2024-11-27T16:53:43.276885-08:00"
|
||||
},
|
||||
{
|
||||
"id": "91509588-0b39-408a-8df3-84b3bce8c521",
|
||||
"memory": "Is a vegetarian",
|
||||
"user_id": "alex123",
|
||||
"hash": "ce6b1c84586772ab9995a9477032df99",
|
||||
"metadata": {
|
||||
"food": "vegan"
|
||||
},
|
||||
"categories": [
|
||||
"user_preferences",
|
||||
"food"
|
||||
],
|
||||
"created_at": "2024-11-27T16:53:43.308027-08:00",
|
||||
"updated_at": "2024-11-27T16:53:43.308037-08:00"
|
||||
},
|
||||
{
|
||||
"id": "8d74f7a0-6107-4589-bd6f-210f6bf4fbbb",
|
||||
"memory": "Is allergic to nuts",
|
||||
"user_id": "alex123",
|
||||
"hash": "7873cd0e5a29c513253d9fad038e758b",
|
||||
"metadata": {
|
||||
"food": "vegan"
|
||||
},
|
||||
"categories": [
|
||||
"health"
|
||||
],
|
||||
"created_at": "2024-11-27T16:53:43.337253-08:00",
|
||||
"updated_at": "2024-11-27T16:53:43.337262-08:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Integration with AI Agents
|
||||
|
||||
All tools are implemented as Langchain `StructuredTool` instances, making them compatible with any AI agent that supports the Langchain tools interface. To use these tools with your agent:
|
||||
|
||||
1. Initialize the tools as shown above
|
||||
2. Add the tools to your agent's toolset
|
||||
3. The agent can now use these tools to manage memories through natural language interactions
|
||||
|
||||
Each tool provides structured input validation through Pydantic models and returns consistent responses that can be processed by your agent.
|
||||
@@ -0,0 +1,93 @@
|
||||
---
|
||||
title: OpenAI Compatibility
|
||||
---
|
||||
|
||||
Mem0 can be easily integrated into chat applications to enhance conversational agents with structured memory. Mem0's APIs are designed to be compatible with OpenAI's, with the goal of making it easy to leverage Mem0 in applications you may have already built.
|
||||
|
||||
If you have a `Mem0 API key`, you can use it to initialize the client. Alternatively, you can initialize Mem0 without an API key if you're using it locally.
|
||||
|
||||
Mem0 supports several language models (LLMs) through integration with various [providers](https://litellm.vercel.app/docs/providers).
|
||||
|
||||
## Use Mem0 Platform
|
||||
|
||||
```python
|
||||
from mem0.proxy.main import Mem0
|
||||
|
||||
client = Mem0(api_key="m0-xxx")
|
||||
|
||||
# First interaction: Storing user preferences
|
||||
messages = [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "I love indian food but I cannot eat pizza since allergic to cheese."
|
||||
},
|
||||
]
|
||||
user_id = "alice"
|
||||
chat_completion = client.chat.completions.create(
|
||||
messages=messages,
|
||||
model="gpt-4o-mini",
|
||||
user_id=user_id
|
||||
)
|
||||
# Memory saved after this will look like: "Loves Indian food. Allergic to cheese and cannot eat pizza."
|
||||
|
||||
# Second interaction: Leveraging stored memory
|
||||
messages = [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "Suggest restaurants in San Francisco to eat.",
|
||||
}
|
||||
]
|
||||
|
||||
chat_completion = client.chat.completions.create(
|
||||
messages=messages,
|
||||
model="gpt-4o-mini",
|
||||
user_id=user_id
|
||||
)
|
||||
print(chat_completion.choices[0].message.content)
|
||||
# Answer: You might enjoy Indian restaurants in San Francisco, such as Amber India, Dosa, or Curry Up Now, which offer delicious options without cheese.
|
||||
```
|
||||
|
||||
In this example, you can see how the second response is tailored based on the information provided in the first interaction. Mem0 remembers the user's preference for Indian food and their cheese allergy, using this information to provide more relevant and personalized restaurant suggestions in San Francisco.
|
||||
|
||||
### Use Mem0 OSS
|
||||
|
||||
```python
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "qdrant",
|
||||
"config": {
|
||||
"host": "localhost",
|
||||
"port": 6333,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
client = Mem0(config=config)
|
||||
|
||||
chat_completion = client.chat.completions.create(
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": "What's the capital of France?",
|
||||
}
|
||||
],
|
||||
model="gpt-4o",
|
||||
)
|
||||
```
|
||||
|
||||
## Mem0 Params for Chat Completion
|
||||
|
||||
- `user_id` (Optional[str]): Identifier for the user.
|
||||
|
||||
- `agent_id` (Optional[str]): Identifier for the agent.
|
||||
|
||||
- `run_id` (Optional[str]): Identifier for the run.
|
||||
|
||||
- `metadata` (Optional[dict]): Additional metadata to be stored with the memory.
|
||||
|
||||
- `filters` (Optional[dict]): Filters to apply when searching for relevant memories.
|
||||
|
||||
- `limit` (Optional[int]): Maximum number of relevant memories to retrieve. Default is 10.
|
||||
|
||||
|
||||
Other parameters are similar to OpenAI's API, making it easy to integrate Mem0 into your existing applications.
|
||||
@@ -0,0 +1,106 @@
|
||||
---
|
||||
title: Memory Customization
|
||||
description: 'Mem0 supports customizing the memories you store, allowing you to focus on pertinent information while omitting irrelevant data.'
|
||||
---
|
||||
|
||||
## Benefits of Memory Customization
|
||||
|
||||
Memory customization offers several key benefits:
|
||||
|
||||
• **Focused Storage**: Store only relevant information for a streamlined system.
|
||||
|
||||
• **Improved Accuracy**: Curate memories for more accurate and relevant retrieval.
|
||||
|
||||
• **Enhanced Privacy**: Exclude sensitive information for better privacy control.
|
||||
|
||||
• **Resource Efficiency**: Optimize storage and processing by keeping only pertinent data.
|
||||
|
||||
• **Personalization**: Tailor the experience to individual user preferences.
|
||||
|
||||
• **Contextual Relevance**: Improve effectiveness in specialized domains or applications.
|
||||
|
||||
These benefits allow users to fine-tune their memory systems, creating a more powerful and personalized AI assistant experience.
|
||||
|
||||
|
||||
## Memory Inclusion
|
||||
Users can define specific kinds of memories to store. This feature enhances memory management by focusing on relevant information, resulting in a more efficient and personalized experience.
|
||||
Here’s how you can do it:
|
||||
|
||||
```python
|
||||
from mem0 import MemoryClient
|
||||
|
||||
m = MemoryClient(api_key="xxx")
|
||||
|
||||
# Define what to include
|
||||
includes = "sports related things"
|
||||
|
||||
messages = [
|
||||
{"role": "user", "content": "Hi, my name is Alice and I love to play badminton"},
|
||||
{"role": "assistant", "content": "Nice to meet you, Alice! Badminton is a great sport."},
|
||||
{"role": "user", "content": "I love music festivals"},
|
||||
{"role": "assistant", "content": "Music festivals are exciting! Do you have a favorite one?"},
|
||||
{"role": "user", "content": "I love eating spicy food"},
|
||||
{"role": "assistant", "content": "Spicy food is delicious! What's your favorite spicy dish?"},
|
||||
{"role": "user", "content": "I love playing baseball with my friends"},
|
||||
{"role": "assistant", "content": "Baseball with friends sounds fun!"},
|
||||
]
|
||||
```
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
client.add(messages, user_id="alice", includes=includes)
|
||||
```
|
||||
|
||||
```json Stored Memories
|
||||
User's name is Alice.
|
||||
Alice loves to play badminton.
|
||||
User loves playing baseball with friends.
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
|
||||
|
||||
|
||||
## Memory Exclusion
|
||||
|
||||
In addition to specifying what to include, users can also define exclusion rules for their memory management. This feature allows for fine-tuning the memory system by instructing it to omit certain types of information.
|
||||
Here’s how you can do it:
|
||||
|
||||
```python
|
||||
from mem0 import MemoryClient
|
||||
|
||||
m = MemoryClient(api_key="xxx")
|
||||
|
||||
# Define what to exclude
|
||||
excludes = "food preferences"
|
||||
|
||||
messages = [
|
||||
{"role": "user", "content": "Hi, my name is Alice and I love to play badminton"},
|
||||
{"role": "assistant", "content": "Nice to meet you, Alice! Badminton is a great sport."},
|
||||
{"role": "user", "content": "I love music festivals"},
|
||||
{"role": "assistant", "content": "Music festivals are exciting! Do you have a favorite one?"},
|
||||
{"role": "user", "content": "I love eating spicy food"},
|
||||
{"role": "assistant", "content": "Spicy food is delicious! What's your favorite spicy dish?"},
|
||||
{"role": "user", "content": "I love playing baseball with my friends"},
|
||||
{"role": "assistant", "content": "Baseball with friends sounds fun!"},
|
||||
]
|
||||
```
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
client.add(messages, user_id="alice", includes=includes)
|
||||
```
|
||||
|
||||
```json Stored Memories
|
||||
User's name is Alice.
|
||||
Alice loves to play badminton.
|
||||
Loves music festivals.
|
||||
User loves playing baseball with friends.
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
|
||||
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.8 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 843 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 293 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.6 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user