Compare commits
853 Commits
v1.0.0-beta.4
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 9c5d2ea0c8 | |||
| b7a4f69565 | |||
| 7b8a324658 | |||
| 59cfded2bb | |||
| 8dc8c05d7d | |||
| 0e4ec4fb97 | |||
| bb00677568 | |||
| 308b63f576 | |||
| 40819e8e17 | |||
| 0fba50905f | |||
| 419bfe3d78 | |||
| 1847248f12 | |||
| eed4a9597c | |||
| c3452d2170 | |||
| 0a14567776 | |||
| 71573b78d1 | |||
| 722dba875b | |||
| 593419639e | |||
| 8b2f06e305 | |||
| 12e4b7bccf | |||
| 63a6c2d161 | |||
| f0e898e3c0 | |||
| 10bb4af4dc | |||
| 1af3fc2011 | |||
| 781cb072a3 | |||
| 73fe21f02e | |||
| 0947bd7877 | |||
| 07d2a41ecb | |||
| 9a66b677e0 | |||
| fe580cfb92 | |||
| 075f4458a0 | |||
| 094b1218e6 | |||
| b16475766a | |||
| e5fdeba50b | |||
| 12b0fe6525 | |||
| 302e1e11e0 | |||
| 8d5bca0d2b | |||
| 994cca7bf4 | |||
| a03afa78be | |||
| a1f93a6922 | |||
| 2678f6f04a | |||
| 03acb35e84 | |||
| 337854ab02 | |||
| 19c569b76a | |||
| 5b4cd9da81 | |||
| 40069ab5f0 | |||
| 8c89cbf43c | |||
| 5061cac591 | |||
| f660506d98 | |||
| 25f81d3c3c | |||
| d261967920 | |||
| 907fb1a129 | |||
| 7d63108e8d | |||
| 274d7d52fd | |||
| d815ab8bff | |||
| 35da3a388a | |||
| a29296c612 | |||
| b93180a822 | |||
| 9fa0c2e1ba | |||
| 2115054de6 | |||
| f167f64cfb | |||
| abc6b21df2 | |||
| bd66bb5cb7 | |||
| c49f931da4 | |||
| 070f0e1469 | |||
| bf4806c987 | |||
| 37e5ca0e87 | |||
| a6011e3cc6 | |||
| 44882129a7 | |||
| 8282c37a5a | |||
| 26ff4520c8 | |||
| e2f0df2cb6 | |||
| 7259ceda59 | |||
| 7f99372130 | |||
| 0cbd438a34 | |||
| 71b30a7f97 | |||
| bfdc60fa65 | |||
| 99af936803 | |||
| d41e960373 | |||
| ae04ba369c | |||
| afff309d43 | |||
| 16c25c9036 | |||
| cd551197ea | |||
| f6077d58f1 | |||
| eb026cb74a | |||
| 7d6698df17 | |||
| a215fc8770 | |||
| a8e3fb8b87 | |||
| 6820501da6 | |||
| b51bf4b1c2 | |||
| 5369da1734 | |||
| d5d8d56124 | |||
| fbcc089e2b | |||
| 76dacb4f5e | |||
| 24ec0f0927 | |||
| b8aac89c4d | |||
| 72a4f787a3 | |||
| 137032b1c0 | |||
| 5011d906e7 | |||
| 35d171e421 | |||
| 20e7a98241 | |||
| abf811f2e4 | |||
| 4d7c49e1ee | |||
| e182da0048 | |||
| f81255aa20 | |||
| 7aaca4dfc8 | |||
| 4a74ee030a | |||
| 7c76e538ab | |||
| 87ed70d313 | |||
| 98bb70bee6 | |||
| a77f0e2473 | |||
| 03b128a544 | |||
| 9c6a60f92c | |||
| 311923255e | |||
| cb77b4fc95 | |||
| 4883d7723b | |||
| eb72a61bad | |||
| 6dfeb6480f | |||
| 51f9a29679 | |||
| d51bf36566 | |||
| 9c9f944350 | |||
| 7b557da549 | |||
| 849749b900 | |||
| 528da32d03 | |||
| 9ef7476267 | |||
| 0f897942fa | |||
| 885f3738fc | |||
| ab0d88accf | |||
| 1146322196 | |||
| 157e28a063 | |||
| c8bc9ecbb0 | |||
| 18ba094647 | |||
| 31e44cde37 | |||
| 248dbb84f0 | |||
| 609fb676e4 | |||
| 5d866664b2 | |||
| ba09ef10b1 | |||
| 19ce6eb9c2 | |||
| 934689ecf7 | |||
| 2f56a14d68 | |||
| cc05ce3d76 | |||
| 5959b43e0a | |||
| b9a6ee08fe | |||
| b1739bbe6b | |||
| cad6d7f725 | |||
| a08ddb2e26 | |||
| c7aa84f9c4 | |||
| ec10030951 | |||
| b298667e3d | |||
| 69e90c3b5f | |||
| 2ada7f2efa | |||
| 28c15885fd | |||
| 194a9b1bbb | |||
| 4ce9676319 | |||
| fb75b40fb6 | |||
| d973ab4318 | |||
| f8b08f38b1 | |||
| b3b10e326f | |||
| efe865a4c5 | |||
| a37ac96411 | |||
| 8a16a3d97e | |||
| 3d9d9496b7 | |||
| 862112ed5f | |||
| ea76739d88 | |||
| c53feba8f5 | |||
| 62d511f967 | |||
| 664359158e | |||
| 8ecde83b89 | |||
| 420f87daca | |||
| c722050aec | |||
| c434b550a5 | |||
| 06a2adf62b | |||
| bb0cf69659 | |||
| e50fadd142 | |||
| 327cbff184 | |||
| 62853a340f | |||
| 86852a8cac | |||
| efc94a2ac3 | |||
| fd4f429b86 | |||
| f5404920fa | |||
| a0d8c7251c | |||
| 303ebea3f3 | |||
| c38012afcf | |||
| becac3b0f6 | |||
| 0245712e24 | |||
| 4b003a852e | |||
| ddf389ffd1 | |||
| 1d59b0a774 | |||
| 74582899a2 | |||
| 8a91dcb85d | |||
| 8fbc4bb23f | |||
| 61d31d9b52 | |||
| a81e536fd5 | |||
| 25fdaeeab2 | |||
| c4885cb324 | |||
| 71e0f1933c | |||
| 65246dc7cd | |||
| 32fd041495 | |||
| 6c292994fd | |||
| 6e8c326a9c | |||
| a4e9b1e1cc | |||
| 29d7f16b2c | |||
| e3c0a180af | |||
| 360c4d4f6f | |||
| 1a580d1051 | |||
| f13df6ab76 | |||
| 239472b61e | |||
| 83c501dc8d | |||
| 67d07ed7e6 | |||
| 18a728ff4b | |||
| b77e3a99e9 | |||
| daba510755 | |||
| dcc04de6bc | |||
| 38693e42ef | |||
| ceaff26d2d | |||
| db373b66a6 | |||
| fb03359400 | |||
| d8e40c9cce | |||
| ecca030ab9 | |||
| 35322b39e3 | |||
| be079b87c8 | |||
| 2a7b2f45d6 | |||
| 2a48bc6343 | |||
| 5acd22a885 | |||
| 632a048c6b | |||
| e1e4910399 | |||
| 5bd67be2e5 | |||
| 482f7bfbb8 | |||
| 2d6f16a311 | |||
| 3f8027af2a | |||
| da063b73bc | |||
| 3f97a12153 | |||
| 6bee56580b | |||
| ad1708abbb | |||
| bd1671c440 | |||
| e527110b9c | |||
| 0cf39c181f | |||
| c0886c086f | |||
| e459c1011c | |||
| 9928509171 | |||
| 16444ae79f | |||
| 75a351e77d | |||
| 5c02e906fa | |||
| b74e7beb29 | |||
| 03b0d08ae0 | |||
| 2183ffa4f0 | |||
| 6dbdfe7ba5 | |||
| 8ab9c2e4df | |||
| c912b637ee | |||
| fcce24d68c | |||
| 4df23cfe45 | |||
| 76e700e9ce | |||
| 65592b9af5 | |||
| 2463759717 | |||
| 8f9937ddee | |||
| 02c28b85f6 | |||
| 5042bcc95d | |||
| f54e8407c0 | |||
| cc6503e6f7 | |||
| 46a8bc61ea | |||
| 8de9d84f1f | |||
| 9aaa3d740d | |||
| 29c582c89e | |||
| 401f60e05b | |||
| bc53a36cd8 | |||
| a4fbba5fd0 | |||
| 84cdc7fa60 | |||
| 6ea6c84b3d | |||
| 1dc0451f0f | |||
| 6e2790b738 | |||
| 1beebcccd2 | |||
| 92ea9a081e | |||
| b6b42c422c | |||
| 23d6dd5e91 | |||
| bda75915b2 | |||
| b099d53871 | |||
| c6ad1968e7 | |||
| a5cbbf93a9 | |||
| bc37bd1687 | |||
| fc3e36713c | |||
| 7161cd5996 | |||
| 350072cf8c | |||
| 23b7d5b49e | |||
| b0849c0046 | |||
| 599f9561e4 | |||
| 0efed9d5f3 | |||
| bd45220c66 | |||
| 08d7fdf0dd | |||
| 53757651c8 | |||
| 42a3130394 | |||
| bd1bde0814 | |||
| 24c15c73c8 | |||
| ad044814a5 | |||
| 7d7552e95b | |||
| fc2a37a7a6 | |||
| aede3cbf52 | |||
| a863c872b0 | |||
| 79115d1b25 | |||
| e5eeffa2bc | |||
| 404a1d5b3f | |||
| 5e6caf7521 | |||
| 050d1f35b2 | |||
| 8a191b9c91 | |||
| 8a746d7ff8 | |||
| 56a9a796bd | |||
| 39bf7c678a | |||
| 5bc0a7f97b | |||
| 0188dd7ed8 | |||
| 7fe7b2feaa | |||
| adc63c94ba | |||
| ee0134598c | |||
| 47e9c291b4 | |||
| b19e5ad0cb | |||
| ff53b7a3f2 | |||
| de442741e5 | |||
| aafde0543f | |||
| f43e17aad4 | |||
| 4760c4d6de | |||
| ddbe4f0fd1 | |||
| c2865f73fb | |||
| f17a601d8e | |||
| 32ee4fef51 | |||
| 5bace9545a | |||
| 0f348ba48e | |||
| f170a1dd8e | |||
| cb37b4fcd2 | |||
| 91eac5c875 | |||
| 4c19994fed | |||
| 8d4e8ba3a8 | |||
| 6618f3a6a5 | |||
| 518889b459 | |||
| 0df61ae714 | |||
| cc8a32d17d | |||
| b9792d28d7 | |||
| a00b01c041 | |||
| 3f6e6ccdea | |||
| 7db5c064d9 | |||
| 4fcf8dceda | |||
| ed8390a36c | |||
| 3fe89bfda3 | |||
| 1d45c2e715 | |||
| 2b8ac0eb2b | |||
| 784f86f6f3 | |||
| 0ae31f6cc8 | |||
| 9d865291f0 | |||
| cb1a192a6d | |||
| bc7dd0f836 | |||
| 90530e4e60 | |||
| 8d64ad9650 | |||
| 6a4bde6c88 | |||
| b3fdde9d83 | |||
| 7111983ef5 | |||
| ea6fc4108a | |||
| b201f3f1b1 | |||
| 40958f2fb4 | |||
| cace69e9af | |||
| 8e0d18a596 | |||
| 432c590ee7 | |||
| 861d773cdd | |||
| 061f555e11 | |||
| 6bd9f0ef9d | |||
| 7bb9780ab1 | |||
| d69157439c | |||
| 999328819a | |||
| 1a3d4f2204 | |||
| 0e697183b2 | |||
| b59f6a7264 | |||
| 05b62871fb | |||
| bf902fd2d9 | |||
| 9724d7b943 | |||
| a8272e1bf9 | |||
| 109561495c | |||
| b96070085b | |||
| 286892eb30 | |||
| 48688dc6e6 | |||
| 3eea6a8fe8 | |||
| 9dd9b010ed | |||
| 472e388508 | |||
| 0888ae5033 | |||
| 1a953e007d | |||
| 2d7be3348a | |||
| 0fd4dd67c7 | |||
| bee3fbb9e2 | |||
| 6146fa1f15 | |||
| 55db68400d | |||
| 3361d9b37e | |||
| 7d2432c56c | |||
| 39dacb87e0 | |||
| 48731e8ddf | |||
| 2c9b675cae | |||
| 4d0a97f9c2 | |||
| 0d02b2e9fa | |||
| 133310bd7d | |||
| d8b20660a2 | |||
| 69bf9cebb3 | |||
| 5715786be2 | |||
| 91e39a0a37 | |||
| 0a4baf67ac | |||
| 586ca11106 | |||
| 39b605f6f4 | |||
| 20b967b4ea | |||
| a27ab96e18 | |||
| dd9d024975 | |||
| f1dcb07d5b | |||
| 8d1ab6973a | |||
| 38226ca84e | |||
| b7d496e6d6 | |||
| 4d2fb56109 | |||
| f4a53da7fd | |||
| defc70128c | |||
| f68da11f6b | |||
| 0a49cb17fa | |||
| 7081464abc | |||
| 7544534ea4 | |||
| 46c0b579aa | |||
| a80e8ba65d | |||
| 88d86117ac | |||
| f4d625500f | |||
| afec850fc9 | |||
| 9065d713e9 | |||
| 1a4e09f908 | |||
| 4a59ba1d9c | |||
| cc317842d8 | |||
| c65f60e2b7 | |||
| 2378dc37b1 | |||
| 82f6ee80fe | |||
| 84aadc0245 | |||
| a5e48ec9e7 | |||
| e7cb31e706 | |||
| 713ece380b | |||
| 8d3aee8da7 | |||
| f21e43c16a | |||
| 4f1683dc55 | |||
| 74be62b812 | |||
| 8d6a1167da | |||
| c68b16191a | |||
| ef8374d03b | |||
| 285bfa6e78 | |||
| a28eede95b | |||
| 247167202d | |||
| 949138627e | |||
| b7f20710db | |||
| c979a9ea08 | |||
| dabd657acf | |||
| 6f7bcc5e37 | |||
| dbd659d75f | |||
| ed97b9361f | |||
| 35a9f6e0ea | |||
| da0233495d | |||
| ebe31f4b60 | |||
| 6dbe1e514f | |||
| b4909564c7 | |||
| e8b596a8d8 | |||
| 54336cdd01 | |||
| bf065fcbc6 | |||
| e541e32c53 | |||
| 6872ee9735 | |||
| e0bb25b1d9 | |||
| cf563f5f32 | |||
| 891b032543 | |||
| 49ffb0b1f3 | |||
| aa7a152f7b | |||
| 58dc881a83 | |||
| 819e57a2c2 | |||
| d05d572b70 | |||
| e07ec87838 | |||
| cb173a6319 | |||
| ddffd80985 | |||
| e1719115ea | |||
| a903f20d7e | |||
| 783858f811 | |||
| 4e7ee1bb5e | |||
| a79459e5a6 | |||
| 6d836d2d93 | |||
| e905dcc86b | |||
| 4485b97ec2 | |||
| 0ea9bec001 | |||
| be4761602c | |||
| 27bd5a082f | |||
| 019c462bfa | |||
| ba9f3f22f6 | |||
| b9945729bb | |||
| 935246d09a | |||
| ebda0da64e | |||
| 36730025fc | |||
| 6d3d441fbf | |||
| 9e48c5264c | |||
| 844fcc8a86 | |||
| 04c5bedd2b | |||
| 4ca98cdbab | |||
| 9645c3de68 | |||
| 781e072b23 | |||
| 3498293098 | |||
| fa7bc53ee9 | |||
| cb2db411ce | |||
| 0bd07cba5c | |||
| 04b95e20c3 | |||
| 3fb7ed691f | |||
| e4a0a4556e | |||
| 4bf2a9af96 | |||
| 41435b3cbc | |||
| afdb71f766 | |||
| 0580cfc54a | |||
| f507f6f7e4 | |||
| f17b894907 | |||
| 01f7515e6f | |||
| 141c89ecbf | |||
| 81ae87f0d9 | |||
| 5219e41d31 | |||
| bf679495fa | |||
| 65bfa6cf37 | |||
| 58ab0acdd8 | |||
| cb18ed6397 | |||
| fdf0a389b7 | |||
| cfd8f7cbe5 | |||
| a1d390dd3e | |||
| 6e7c0aac57 | |||
| e83a1c4230 | |||
| 79e7df022f | |||
| 244d08c0bd | |||
| 7134c9dbc1 | |||
| 93f09685b5 | |||
| 602604e437 | |||
| 29c5348b5a | |||
| f6461f733b | |||
| f9865b71c3 | |||
| 905d248ebf | |||
| b35a249bf6 | |||
| 76cae42fde | |||
| 239ce6fb36 | |||
| ec77dd0f02 | |||
| fa558a447a | |||
| 7101b8b4b8 | |||
| 02a2f71470 | |||
| aad9f3f1ef | |||
| 99a3f103e0 | |||
| 0f4576c27d | |||
| ae4f69f7c7 | |||
| 7f1f887159 | |||
| 33109a4c8b | |||
| 6ed88a5946 | |||
| eb5ade7684 | |||
| 82df0a3c23 | |||
| 0fe0e9a717 | |||
| e37526d905 | |||
| 899676110a | |||
| 86d5040a7d | |||
| aebe513599 | |||
| 07743657cd | |||
| 68514cbc07 | |||
| ce00989b01 | |||
| f1f8b472b4 | |||
| a1e9011d5d | |||
| e3b20a320d | |||
| a8d82050c8 | |||
| 2e66be25ef | |||
| aa995d46c8 | |||
| 3713521b08 | |||
| dcddacca29 | |||
| 4b5a883510 | |||
| 192dd0a87a | |||
| 573704706c | |||
| fba80966c9 | |||
| af0fdd1e18 | |||
| 843bc428b8 | |||
| be0b345d3f | |||
| c5cc9bdd52 | |||
| 795acc5bdd | |||
| 8377c63db4 | |||
| e1485c2ed3 | |||
| 10d10a1690 | |||
| c5edf6488b | |||
| b69b1fea16 | |||
| 567b030c4f | |||
| 2ac1bc63cc | |||
| fce47cdbd5 | |||
| 9139215971 | |||
| 6712ae5539 | |||
| ceea47ff7d | |||
| f4d782b69e | |||
| 8a33980260 | |||
| a42bf40b93 | |||
| 782a3aaa0a | |||
| f30ddb6be5 | |||
| 6cfbabfe73 | |||
| b1a332bab6 | |||
| e88495a9a9 | |||
| 993d52e868 | |||
| 0acb31a9c6 | |||
| ffe0c8d217 | |||
| 5dbc010fa6 | |||
| f36dd20f82 | |||
| 870ab2e87e | |||
| 0ebc0518e6 | |||
| 7f5e30ac82 | |||
| f4446ef177 | |||
| 035c9d5240 | |||
| 1529c72039 | |||
| 9e242d77d3 | |||
| 250e16e4e4 | |||
| f88305020a | |||
| 27dc801cf5 | |||
| 05e0911009 | |||
| 99681e2577 | |||
| c5b3840082 | |||
| 7a9db1363d | |||
| c988a456f4 | |||
| 5ee57ddf2a | |||
| 6c59f17207 | |||
| b47cbc3a5e | |||
| fa4bd6a8a1 | |||
| 3dd9039678 | |||
| 19e1aa22f6 | |||
| 8b56a1850c | |||
| 8e1868798c | |||
| 875757739f | |||
| 860571bcb6 | |||
| efc2a3a7c0 | |||
| 9d6ae0aecd | |||
| 68e40f65df | |||
| 22e9234b3d | |||
| 8746175eca | |||
| 39f8dc2bae | |||
| 6b37195d9d | |||
| faabc2c7b0 | |||
| 7513aa7d20 | |||
| 9b870010dd | |||
| 9124687eb0 | |||
| 77ebaf4a9c | |||
| 81c7eb83c5 | |||
| e27c1b9c8f | |||
| b6f79e04b9 | |||
| 25adf406c8 | |||
| 1ece25a497 | |||
| 49a7da9117 | |||
| 2a535a8898 | |||
| 8257eb8792 | |||
| 960a6dc71c | |||
| 3bbc2f8a25 | |||
| 6aa60bfbd8 | |||
| 368c57928a | |||
| 1d9b18093b | |||
| 334bf393f2 | |||
| 7e70f41774 | |||
| bc228a6860 | |||
| 95bfcfe422 | |||
| 2b03d981ab | |||
| 969a83e608 | |||
| 1845eed71d | |||
| cbb48213d2 | |||
| 499be77d50 | |||
| d1c2a11d82 | |||
| a9a43ac478 | |||
| bf9bf231f7 | |||
| 1e6835a9e5 | |||
| 9be7c70076 | |||
| fd7234c827 | |||
| 0f7a6f6bed | |||
| 1e988350b4 | |||
| a808742c92 | |||
| cbe89ed6cc | |||
| 006e9fb011 | |||
| 8acb82da9b | |||
| 8476d5fc3c | |||
| 5970ec9e8e | |||
| caa86fc8a6 | |||
| f17db82509 | |||
| 64e8742aad | |||
| 76547d9411 | |||
| 9ce9a8bc4f | |||
| f4f9fff978 | |||
| 0367b44f21 | |||
| 8280c65897 | |||
| d5577b1ef5 | |||
| 28efe6e7d5 | |||
| b0d4bf6e1f | |||
| a853de4558 | |||
| 3ca48265e7 | |||
| 8f2f935b94 | |||
| 29b32f66f2 | |||
| 4372b45fc6 | |||
| 4d255dd1d1 | |||
| 8825d6877c | |||
| 975b8ebcf0 | |||
| 4107932d00 | |||
| cf6340b3ca | |||
| 131659928e | |||
| 4029759ba7 | |||
| 6f04e36342 | |||
| c658425913 | |||
| b19bb0e3eb | |||
| 41c4436924 | |||
| dc4b6ff296 | |||
| 13132279f3 | |||
| 195278f975 | |||
| 3403e8cc12 | |||
| 5fecc1fd85 | |||
| 053d53bb10 | |||
| 9d5ceb03cb | |||
| 3fea149497 | |||
| d49bc5f63f | |||
| 98a0382103 | |||
| 7977d55b81 | |||
| c1afc11cdb | |||
| f5bdf2c888 | |||
| 99b401a668 | |||
| da51f3ee30 | |||
| 4e36843c96 | |||
| 098f3ea85f | |||
| 238d928cac | |||
| 717faf8580 | |||
| 254f2848aa | |||
| 4a5480a3cc | |||
| b775ec4e9d | |||
| 51f14320e9 | |||
| ef0c54b226 | |||
| cad072c3a6 | |||
| 963e4de8df | |||
| dc80135cd0 | |||
| 7d5cadbb82 | |||
| 1a118b718e | |||
| 08e6c9de54 | |||
| 2b547c304b | |||
| 42e2346663 | |||
| 0e3555f1e3 | |||
| 0fc475e572 | |||
| e4d3904cee | |||
| 65398d8231 | |||
| 9a604d7ccc | |||
| d8023308d0 | |||
| db1246735c | |||
| fe90c68ea0 | |||
| 18286800ed | |||
| f24513a223 | |||
| 5edcc679f8 | |||
| 34b2aa5655 | |||
| ca3f5f42da | |||
| 763d19069b | |||
| 8dd7642d3b | |||
| 226468f6ab | |||
| cf2a28aac2 | |||
| a0107d6294 | |||
| 94eebbbf20 | |||
| e14c249826 | |||
| 5544c3c5a2 | |||
| f179e1070c | |||
| 6862778645 | |||
| d265377a43 | |||
| 36b0f68afc | |||
| c6c0129158 | |||
| 2d0b0f1365 | |||
| 699ded22ad | |||
| 5d58f5d918 | |||
| 553d5df070 | |||
| 4e4d1cc136 | |||
| 6b9d53e0cc | |||
| 7bdbd0dcd0 | |||
| 58f5f2d21c | |||
| aa0136baec | |||
| 1535fa67ac | |||
| 62eadb10d4 | |||
| af26ecac0f | |||
| f61eef4882 | |||
| 5c88c134f4 | |||
| 7039918760 | |||
| 79be099cc5 | |||
| 4d644ce3fd | |||
| f563d01d07 | |||
| bd53641a81 | |||
| b9b204d212 | |||
| 3ec38bfb6b | |||
| 706c528334 | |||
| 429dce6f37 | |||
| bfc50154f0 | |||
| 3ce5b74e94 | |||
| 93a138f77c | |||
| b1c6f5c883 | |||
| 04d6228841 | |||
| 86a4816b77 | |||
| cdf4149939 | |||
| e6246d1f8f | |||
| d10a7fa788 | |||
| b6428d0384 | |||
| 115f9c1645 | |||
| 82fb967af8 | |||
| 2e5b2c59da | |||
| cc0fb92351 | |||
| 5b41713a68 | |||
| f1f48757e2 | |||
| 8e45da75ce | |||
| fdeff12762 | |||
| 38d0436101 | |||
| 89e216fd49 | |||
| 7cf7f97912 | |||
| 10f3132d09 | |||
| c86a0df3f4 | |||
| 99e111b52d | |||
| d23ea0e289 | |||
| da2ebdb520 | |||
| dc2d36be95 | |||
| 02f766d6a8 | |||
| c73a26a11e | |||
| aa9a494a4b | |||
| 920b4b2a4f | |||
| 13f5a49f67 | |||
| ddfebb0d74 | |||
| a5769dce6e | |||
| b09eaed63d | |||
| a0dffbedb1 | |||
| b4bb48def0 | |||
| 97b5e2086b | |||
| c16d5b280b | |||
| 065225a7f5 | |||
| acf3f9a0d2 | |||
| 607a51eead | |||
| 1e612f766e | |||
| b3affa0fc1 | |||
| 2f66f1c17b | |||
| cf6d7d0749 | |||
| d13a9e3aa7 | |||
| 2ee57490df | |||
| 7852b8dbac | |||
| de7c3ad68e | |||
| 37946b6a90 | |||
| a7ffdd19bd | |||
| 6b23d23b06 | |||
| 9381fb2916 | |||
| 2f1266764a | |||
| e3427149f6 | |||
| 3b47cb5ee8 | |||
| cd607768ed | |||
| fbbcf2eb50 | |||
| 4128c3a01a | |||
| 2044de408c | |||
| d002610ac7 | |||
| 5066895827 | |||
| 19cd427daa | |||
| fa3eefb220 | |||
| 1775b07bf6 | |||
| 1ce04224b2 | |||
| b39d441177 | |||
| ad701e12a9 | |||
| d60eebd2a0 | |||
| 68b86e1eae | |||
| e780868004 | |||
| 68bcb4269a | |||
| 1ee2ffed4b | |||
| b178a3a8dd | |||
| 3dba8fd713 | |||
| 621fd48591 | |||
| b30940b9fa | |||
| 72ed68599c | |||
| 5f9e9b5ad4 |
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"presets": [
|
||||
["@babel/preset-env", {
|
||||
"targets": {
|
||||
"node": "current"
|
||||
}
|
||||
}]
|
||||
],
|
||||
"plugins": [
|
||||
["module-resolver", {
|
||||
"alias": {
|
||||
"@@": ".",
|
||||
"@": "./server/src"
|
||||
},
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@@": ".",
|
||||
"@": "./server/src"
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
}
|
||||
+9
-4
@@ -1,4 +1,9 @@
|
||||
node_modules/
|
||||
bridges/python/.venv/*
|
||||
|
||||
!bridges/python/.venv/.gitkeep
|
||||
__pycache__/
|
||||
**/dist/*
|
||||
**/build/
|
||||
**/node_modules/
|
||||
**/tmp/*
|
||||
**/src/.venv/*
|
||||
logs/*
|
||||
*.pyc
|
||||
.DS_Store
|
||||
|
||||
+16
-14
@@ -1,5 +1,5 @@
|
||||
# Main settings of Leon
|
||||
# https://docs.getleon.ai/configuration.html
|
||||
# https://docs.getleon.ai/configuration
|
||||
|
||||
# Language currently used
|
||||
LEON_LANG=en-US
|
||||
@@ -17,27 +17,29 @@ LEON_AFTER_SPEECH=false
|
||||
# Enable/disable Leon's speech-to-text
|
||||
LEON_STT=false
|
||||
# Speech-to-text provider
|
||||
LEON_STT_PROVIDER=deepspeech
|
||||
LEON_STT_PROVIDER=coqui-stt
|
||||
|
||||
# Enable/disable Leon's text-to-speech
|
||||
LEON_TTS=false
|
||||
# Text-to-speech provider
|
||||
LEON_TTS_PROVIDER=flite
|
||||
|
||||
# Enable/disable collaborative logger
|
||||
LEON_LOGGER=true
|
||||
# Enable/disable skills to be available over HTTP
|
||||
LEON_OVER_HTTP=true
|
||||
# HTTP API key (use "npm run generate:http-api-key" to regenerate one)
|
||||
LEON_HTTP_API_KEY=
|
||||
# Language used for the HTTP API
|
||||
LEON_HTTP_API_LANG=en-US
|
||||
|
||||
# Enable/disable telemetry
|
||||
LEON_TELEMETRY=true
|
||||
|
||||
# Python TCP server
|
||||
LEON_PY_TCP_SERVER_HOST=0.0.0.0
|
||||
LEON_PY_TCP_SERVER_PORT=1342
|
||||
|
||||
# Path to the Pipfile
|
||||
PIPENV_PIPFILE=bridges/python/Pipfile
|
||||
PIPENV_PIPFILE=bridges/python/src/Pipfile
|
||||
|
||||
# Path to the virtual env in .venv/
|
||||
PIPENV_VENV_IN_PROJECT=true
|
||||
|
||||
# Fix https://click.palletsprojects.com/en/7.x/python3/#python-3-surrogate-handling
|
||||
# If Leon replies you something like "Sorry, it seems I have a problem with the ... module" but
|
||||
# still gives you the right answer, then:
|
||||
## 1. Run `locale -a`
|
||||
## 2. Pick a locale
|
||||
## 3. Replace the LC_ALL and LANG values with the needed locale
|
||||
LC_ALL=C.UTF-8
|
||||
LANG=C.UTF-8
|
||||
|
||||
+62
-32
@@ -1,9 +1,21 @@
|
||||
{
|
||||
"extends": "airbnb-base",
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:import/recommended",
|
||||
"plugin:import/typescript",
|
||||
"prettier"
|
||||
],
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
"typescript": true,
|
||||
"node": true
|
||||
}
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"env": {
|
||||
"node": true,
|
||||
"browser": true,
|
||||
"jest/globals": true
|
||||
"browser": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2021
|
||||
@@ -11,37 +23,55 @@
|
||||
"globals": {
|
||||
"io": true
|
||||
},
|
||||
"plugins": [
|
||||
"import",
|
||||
"jest"
|
||||
],
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
"babel-module": {
|
||||
"alias": {
|
||||
"@@": ".",
|
||||
"@": "./server/src"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": ["@typescript-eslint", "unicorn", "import"],
|
||||
"ignorePatterns": "*.spec.js",
|
||||
"rules": {
|
||||
"no-multi-assign": "off",
|
||||
"no-trailing-spaces": "off",
|
||||
"linebreak-style": "off",
|
||||
"indent": "off",
|
||||
"strict": "off",
|
||||
"no-console": "off",
|
||||
"no-param-reassign": "off",
|
||||
"no-shadow": "off",
|
||||
"import/no-extraneous-dependencies": "off",
|
||||
"import/no-dynamic-require": "off",
|
||||
"prefer-promise-reject-errors": ["off"],
|
||||
"@typescript-eslint/no-non-null-assertion": ["off"],
|
||||
"no-async-promise-executor": ["off"],
|
||||
"no-underscore-dangle": ["error", { "allowAfterThis": true }],
|
||||
"space-before-function-paren": ["error", "always"],
|
||||
"prefer-destructuring": ["error", { "array": true, "object": true }],
|
||||
"prefer-destructuring": ["error"],
|
||||
"comma-dangle": ["error", "never"],
|
||||
"semi": ["error", "never"]
|
||||
}
|
||||
"semi": ["error", "never"],
|
||||
"object-curly-spacing": ["error", "always"],
|
||||
"unicorn/prefer-node-protocol": "error",
|
||||
"@typescript-eslint/member-delimiter-style": [
|
||||
"error",
|
||||
{
|
||||
"multiline": {
|
||||
"delimiter": "none",
|
||||
"requireLast": true
|
||||
},
|
||||
"singleline": {
|
||||
"delimiter": "comma",
|
||||
"requireLast": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/consistent-type-definitions": "error",
|
||||
"import/no-named-as-default": "off",
|
||||
"import/no-named-as-default-member": "off",
|
||||
"import/order": [
|
||||
"error",
|
||||
{
|
||||
"groups": [
|
||||
"builtin",
|
||||
"external",
|
||||
"internal",
|
||||
"parent",
|
||||
"sibling",
|
||||
"index"
|
||||
],
|
||||
"newlines-between": "always"
|
||||
}
|
||||
]
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts"],
|
||||
"rules": {
|
||||
"@typescript-eslint/explicit-function-return-type": "error"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+11
-11
@@ -14,21 +14,21 @@ appearance, race, religion, or sexual identity and orientation.
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
- Using welcoming and inclusive language
|
||||
- Being respectful of differing viewpoints and experiences
|
||||
- Gracefully accepting constructive criticism
|
||||
- Focusing on what is best for the community
|
||||
- Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
- The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
- Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
- Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at <louis.grenard@gmail.com>. All
|
||||
reported by contacting the project team at <louis@getleon.ai>. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
|
||||
+112
-34
@@ -2,7 +2,7 @@
|
||||
|
||||
Thanks a lot for your interest in contributing to Leon! :heart:
|
||||
|
||||
**Leon needs open source to live**, the more modules he has, the more skillful he becomes.
|
||||
**Leon needs open source to live**, the more skills he has, the more skillful he becomes.
|
||||
|
||||
**Before submitting your contribution**, please take a moment to review this document.
|
||||
|
||||
@@ -12,17 +12,16 @@ Please note we have a [code of conduct](https://github.com/leon-ai/leon/blob/dev
|
||||
|
||||
Here are few examples about how you could help on Leon, by:
|
||||
|
||||
- [Creating a new module](https://docs.getleon.ai/packages-modules.html).
|
||||
- [Working on new features](https://roadmap.getleon.ai) (what is in backlog or todo).
|
||||
- [Creating a new module](https://docs.getleon.ai/packages-modules).
|
||||
- [Working on new features](http://roadmap.getleon.ai) (what is in backlog or todo).
|
||||
- [Suggesting new ideas](https://github.com/leon-ai/leon/issues/new/choose).
|
||||
- [Reporting a bug](https://github.com/leon-ai/leon/issues/new?labels=bug&template=BUG.md).
|
||||
- [Improving the documentation](https://github.com/leon-ai/docs.getleon.ai) (translations, typos, better writing, etc.).
|
||||
- [Buying me a fruit juice](https://donate.getleon.ai).
|
||||
|
||||
- [Sponsoring Leon](http://sponsor.getleon.ai).
|
||||
|
||||
## Pull Requests
|
||||
|
||||
**Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github).
|
||||
**Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github).
|
||||
|
||||
- **Please first discuss** the change you wish to make via [issue](https://github.com/leon-ai/leon/issues),
|
||||
email, or any other method with the owners of this repository before making a change.
|
||||
@@ -32,18 +31,18 @@ Here are few examples about how you could help on Leon, by:
|
||||
against the `master` branch**.
|
||||
|
||||
- Ensure your code **respect our coding standards** (cf. [.eslintrc.json](https://github.com/leon-ai/leon/blob/develop/.eslintrc.json)).
|
||||
To do so, you can run:
|
||||
To do so, you can run:
|
||||
|
||||
```sh
|
||||
npm run lint
|
||||
```
|
||||
|
||||
|
||||
- Make sure your **code passes the tests**. You can run the tests via the following command:
|
||||
|
||||
|
||||
```sh
|
||||
npm test
|
||||
```
|
||||
|
||||
|
||||
If you're adding new features to Leon, please include tests.
|
||||
|
||||
## Development Setup
|
||||
@@ -52,7 +51,7 @@ Choose the setup method you want to go for.
|
||||
|
||||
### Single-Click
|
||||
|
||||
Gitpod will automatically setup an environment and run an instance for you.
|
||||
Gitpod will automatically set up an environment and run an instance for you.
|
||||
|
||||
[](https://gitpod.io/#https://github.com/leon-ai/leon)
|
||||
|
||||
@@ -97,9 +96,6 @@ npm run docker:dev
|
||||
## Versioning
|
||||
|
||||
- We use [Semantic Versioning](https://semver.org) for releases.
|
||||
- A new Leon module creation increases the MINOR version number of its relevant Leon package.
|
||||
- Each time a MAJOR or MINOR version number of a Leon package is increased, then the MINOR version number of the project should also be increased.
|
||||
- Each time a PATCH version number of a Leon package is increased, then the PATCH version number of the projet should also be increased.
|
||||
|
||||
## Commits
|
||||
|
||||
@@ -109,42 +105,124 @@ The commit message guideline is adapted from the [AngularJS Git Commit Guideline
|
||||
|
||||
Types define which kind of changes you made to the project.
|
||||
|
||||
| Types | Description |
|
||||
| ------------- |-------------|
|
||||
| BREAKING | Changes including breaking changes. |
|
||||
| build | New build version. |
|
||||
| chore | Changes to the build process or auxiliary tools such as changelog generation. No production code change. |
|
||||
| ci | Changes related to continuous integration only (GitHub Actions, CircleCI, etc.). |
|
||||
| docs | Documentation only changes. |
|
||||
| feat | A new feature. |
|
||||
| fix | A bug fix. |
|
||||
| perf | A code change that improves performance. |
|
||||
| refactor | A code change that neither fixes a bug nor adds a feature. |
|
||||
| style | Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc.). |
|
||||
| test | Adding missing or correcting existing tests. |
|
||||
| Types | Description |
|
||||
| -------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| BREAKING | Changes including breaking changes. |
|
||||
| build | New build version. |
|
||||
| chore | Changes to the build process or auxiliary tools such as changelog generation. No production code change. |
|
||||
| ci | Changes related to continuous integration only (GitHub Actions, CircleCI, etc.). |
|
||||
| docs | Documentation only changes. |
|
||||
| feat | A new feature. |
|
||||
| fix | A bug fix. |
|
||||
| perf | A code change that improves performance. |
|
||||
| refactor | A code change that neither fixes a bug nor adds a feature. |
|
||||
| style | Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc.). |
|
||||
| test | Adding missing or correcting existing tests. |
|
||||
|
||||
### Scopes
|
||||
|
||||
Scopes define high-level nodes of Leon.
|
||||
|
||||
- web app
|
||||
- server
|
||||
- bridge/python
|
||||
- bridge/nodejs
|
||||
- docker
|
||||
- hotword
|
||||
- package/package_name
|
||||
- scripts
|
||||
- server
|
||||
- tcp server
|
||||
- web app
|
||||
- skill/skill_name
|
||||
|
||||
### Examples
|
||||
|
||||
```sh
|
||||
git commit -m "feat(server): awesome new server feature"
|
||||
git commit -m "docs(package/leon): fix spelling"
|
||||
git commit -m "docs(skill/leon): fix spelling"
|
||||
git commit -m "chore: split training script into awesome blocks"
|
||||
git commit -m "style(web app): remove chatbot useless parentheses"
|
||||
```
|
||||
|
||||
## Donate
|
||||
## Sponsor
|
||||
|
||||
You can also contribute by [buying me a fruit juice](https://donate.getleon.ai).
|
||||
You can also contribute by [sponsoring Leon](http://sponsor.getleon.ai).
|
||||
|
||||
Please note that I dedicate most of my free time to Leon.
|
||||
|
||||
By sponsoring the project you make the project sustainable and faster to develop features.
|
||||
|
||||
The focus is not only limited to the activity you see on GitHub but also a lot of thinking about the direction of the project. Which is naturally related to the overall design, architecture, vision, learning process and so on...
|
||||
|
||||
## Contributing to the Python Bridge or TCP HttpServer
|
||||
|
||||
Leon makes use of two binaries, the Python bridge and the TCP server. These binaries are compiled from Python sources.
|
||||
|
||||
The Python bridge is used to communicate between the core and skills made with Python.
|
||||
|
||||
The TCP server is used to communicate between the core and third-party nodes, such as spaCy.
|
||||
|
||||
### Set Up the Python Environment
|
||||
|
||||
To contribute to these parts, you need to set up a Python environment running with a specific Python version and a specific Pipenv version.
|
||||
|
||||
It is recommended to use Pyenv to manage your Python versions.
|
||||
|
||||
If you are on GNU/Linux Ubuntu, you can run the following to install Pyenv, otherwise, please refer to the [Pyenv documentation to install it](https://github.com/pyenv/pyenv#installation):
|
||||
|
||||
```bash
|
||||
# Update registry
|
||||
sudo apt-get update
|
||||
|
||||
# Install Pyenv deps
|
||||
sudo apt-get install make build-essential libssl-dev zlib1g-dev \
|
||||
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
|
||||
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
|
||||
|
||||
# Install Pyenv
|
||||
curl https://pyenv.run | bash
|
||||
|
||||
# Add output lines to .bashrc
|
||||
|
||||
# Restart shell
|
||||
exec "$SHELL"
|
||||
```
|
||||
|
||||
Once Pyenv installed, run:
|
||||
|
||||
```bash
|
||||
# Install Python
|
||||
pyenv install 3.9.10 --force
|
||||
pyenv global 3.9.10
|
||||
|
||||
# Install Pipenv
|
||||
pip install pipenv==2022.7.24
|
||||
```
|
||||
|
||||
Your Python environment should be ready now. So now you can set up the respective environments according to what you are going to contribute to and build them:
|
||||
|
||||
```bash
|
||||
# Set up the Python bridge environment
|
||||
npm run setup:python-bridge
|
||||
|
||||
# Set up the TCP server environment
|
||||
npm run setup:tcp-server
|
||||
# If you are in China, you can run this to download models faster:
|
||||
npm run setup:tcp-server cn
|
||||
|
||||
# Once your code changes are done, you can build via:
|
||||
|
||||
# Build the Python bridge
|
||||
npm run build:python-bridge
|
||||
|
||||
# Build the TCP server
|
||||
npm run build:tcp-server
|
||||
|
||||
# Run the Python bridge
|
||||
./bridges/python/dist/{OS-CPU_ARCH}/leon-python-bridge server/src/intent-object.sample.json
|
||||
|
||||
# Run the TCP server
|
||||
./tcp_server/dist/{OS-CPU_ARCH}/leon-tcp-server en
|
||||
```
|
||||
|
||||
## Spread the Word
|
||||
|
||||
Use [#LeonAI](https://twitter.com/hashtag/LeonAI) if you tweet about Leon and/or mention [@louistiti_fr](https://twitter.com/louistiti_fr).
|
||||
Use [#LeonAI](<https://twitter.com/search?f=live&q=%23LeonAI%20(from%3Agrenlouis%20OR%20from%3Alouistiti_fr)&src=typed_query>) if you tweet about Leon and/or mention [@grenlouis](https://twitter.com/grenlouis).
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
# github: [louistiti]
|
||||
github: [louistiti]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
custom: https://donate.getleon.ai
|
||||
custom: # http://sponsor.getleon.ai
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<!--
|
||||
|
||||
Thanks for your interest in Leon! ❤️
|
||||
|
||||
Please check if there is no similar issue before creating this one.
|
||||
|
||||
-->
|
||||
@@ -7,6 +7,7 @@ labels: bug
|
||||
<!--
|
||||
Thanks for your interest in Leon! ❤️
|
||||
Please check if there is no similar issue before creating this one.
|
||||
If the bug is related to the setup, please submit the issue at: https://github.com/leon-ai/leon-cli/issues/new/choose
|
||||
-->
|
||||
|
||||
### Specs
|
||||
@@ -14,9 +15,9 @@ Please check if there is no similar issue before creating this one.
|
||||
- Leon version:
|
||||
- OS (or browser) version:
|
||||
- Node.js version:
|
||||
- Complete "npm run check" output:
|
||||
- Complete "leon check" (or "npm run check") output:
|
||||
- (if using Docker) Complete "npm run docker:check" output:
|
||||
- (optional) Leon package version:
|
||||
- (optional) Leon skill version:
|
||||
|
||||
### Expected Behavior
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ Please place an x (no spaces - [x]) in all [ ] that apply.
|
||||
-->
|
||||
|
||||
### Documentation Is:
|
||||
|
||||
- [ ] Missing
|
||||
- [ ] Needed
|
||||
- [ ] Confusing
|
||||
|
||||
@@ -14,6 +14,7 @@ Please place an x (no spaces - [x]) in all [ ] that apply.
|
||||
-->
|
||||
|
||||
### What type of change does this PR introduce?
|
||||
|
||||
- [ ] Bugfix
|
||||
- [ ] Feature
|
||||
- [ ] Refactor
|
||||
@@ -21,10 +22,10 @@ Please place an x (no spaces - [x]) in all [ ] that apply.
|
||||
- [ ] Not Sure?
|
||||
|
||||
### Does this PR introduce breaking changes?
|
||||
|
||||
- [ ] Yes
|
||||
- [ ] No
|
||||
|
||||
### List any relevant issue numbers:
|
||||
|
||||
### Description:
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: 'npm'
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: 'weekly'
|
||||
day: 'friday'
|
||||
time: '22:00'
|
||||
commit-message:
|
||||
prefix: 'chore'
|
||||
include: 'scope'
|
||||
reviewers:
|
||||
- 'louistiti'
|
||||
+18
-18
@@ -2,35 +2,35 @@ name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, develop]
|
||||
# branches: [master, develop]
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master, develop]
|
||||
# branches: [master, develop]
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-20.04
|
||||
container: leonai/ci:latest
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v2
|
||||
- name: Use Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-node_modules-${{ hashFiles('package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node_modules-
|
||||
- name: Cache Pipenv
|
||||
uses: actions/cache@v2
|
||||
python-version: 3.x
|
||||
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
path: bridges/python/.venv
|
||||
key: ${{ runner.os }}-pipenv-${{ env.cache-name }}-${{ hashFiles('bridges/python/Pipfile.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pipenv-
|
||||
node-version: 16.x
|
||||
cache: npm
|
||||
|
||||
- name: Install Pipenv
|
||||
run: pip install --upgrade pip && pip install pipenv
|
||||
|
||||
- name: Install
|
||||
run: npm ci
|
||||
run: npm install
|
||||
|
||||
- name: Check setup
|
||||
run: npm run check
|
||||
|
||||
+18
-18
@@ -2,35 +2,35 @@ name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, develop]
|
||||
# branches: [master, develop]
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master, develop]
|
||||
# branches: [master, develop]
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
|
||||
runs-on: ubuntu-20.04
|
||||
container: leonai/ci:latest
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v2
|
||||
- name: Use Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-node_modules-${{ hashFiles('package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node_modules-
|
||||
- name: Cache Pipenv
|
||||
uses: actions/cache@v2
|
||||
python-version: 3.x
|
||||
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
path: bridges/python/.venv
|
||||
key: ${{ runner.os }}-pipenv-${{ env.cache-name }}-${{ hashFiles('bridges/python/Pipfile.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pipenv-
|
||||
node-version: 16.x
|
||||
cache: npm
|
||||
|
||||
- name: Install Pipenv
|
||||
run: pip install --upgrade pip && pip install pipenv
|
||||
|
||||
- name: Install
|
||||
run: npm ci
|
||||
run: npm install
|
||||
|
||||
- name: Run linter
|
||||
run: npm run lint
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
name: Pre-release Node.js bridge
|
||||
|
||||
on: workflow_dispatch
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: lts/*
|
||||
|
||||
- name: Set Node.js bridge version
|
||||
working-directory: bridges/nodejs/src
|
||||
run: |
|
||||
echo "NODEJS_BRIDGE_VERSION=$(node --require fs --eval "const fs = require('node:fs'); const [, VERSION] = fs.readFileSync('version.ts', 'utf8').split(\"'\"); console.log(VERSION)")" >> $GITHUB_ENV
|
||||
|
||||
- name: Display Node.js bridge version
|
||||
run: |
|
||||
echo "Node.js bridge version: ${{ env.NODEJS_BRIDGE_VERSION }}"
|
||||
|
||||
- name: Install core
|
||||
run: npm install
|
||||
|
||||
- name: Build Node.js bridge
|
||||
run: npm run build:nodejs-bridge
|
||||
|
||||
- name: Upload Node.js bridge
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
path: bridges/nodejs/dist/*.zip
|
||||
|
||||
draft-release:
|
||||
name: Draft-release
|
||||
needs: [build]
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: lts/*
|
||||
|
||||
- name: Set Node.js bridge version
|
||||
working-directory: bridges/nodejs/src
|
||||
run: |
|
||||
echo "NODEJS_BRIDGE_VERSION=$(node --require fs --eval "const fs = require('node:fs'); const [, VERSION] = fs.readFileSync('version.ts', 'utf8').split(\"'\"); console.log(VERSION)")" >> $GITHUB_ENV
|
||||
|
||||
- name: Download Node.js bridge
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
path: bridges/nodejs/dist
|
||||
|
||||
- uses: marvinpinto/action-automatic-releases@latest
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
automatic_release_tag: nodejs-bridge_v${{ env.NODEJS_BRIDGE_VERSION }}
|
||||
draft: true
|
||||
prerelease: false
|
||||
title: Node.js Bridge ${{ env.NODEJS_BRIDGE_VERSION }}
|
||||
files: bridges/nodejs/dist/artifact/*.zip
|
||||
@@ -0,0 +1,91 @@
|
||||
name: Pre-release Python bridge
|
||||
|
||||
on: workflow_dispatch
|
||||
|
||||
env:
|
||||
PIPENV_PIPFILE: bridges/python/src
|
||||
PIPENV_VENV_IN_PROJECT: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04, macos-latest, windows-latest]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.9.10
|
||||
|
||||
- name: Install Pipenv
|
||||
run: pip install --upgrade pip && pip install pipenv==2022.7.24
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: lts/*
|
||||
|
||||
- name: Set Python bridge version
|
||||
working-directory: bridges/python/src
|
||||
run: |
|
||||
echo "PYTHON_BRIDGE_VERSION=$(python -c "from version import __version__; print(__version__)")" >> $GITHUB_ENV
|
||||
|
||||
- name: Display Python bridge version
|
||||
run: |
|
||||
echo "Python bridge version: ${{ env.PYTHON_BRIDGE_VERSION }}"
|
||||
|
||||
- name: Install core
|
||||
run: npm install
|
||||
|
||||
- name: Set up Python bridge
|
||||
run: npm run setup:python-bridge
|
||||
|
||||
- name: Build Python bridge
|
||||
run: npm run build:python-bridge
|
||||
|
||||
- name: Upload Python bridge
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
path: bridges/python/dist/*.zip
|
||||
|
||||
draft-release:
|
||||
name: Draft-release
|
||||
needs: [build]
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.9.10
|
||||
|
||||
- name: Set Python bridge version
|
||||
working-directory: bridges/python/src
|
||||
run: |
|
||||
echo "PYTHON_BRIDGE_VERSION=$(python -c "from version import __version__; print(__version__)")" >> $GITHUB_ENV
|
||||
|
||||
- name: Download Python bridge
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
path: bridges/python/dist
|
||||
|
||||
- uses: marvinpinto/action-automatic-releases@latest
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
automatic_release_tag: python-bridge_v${{ env.PYTHON_BRIDGE_VERSION }}
|
||||
draft: true
|
||||
prerelease: false
|
||||
title: Python Bridge ${{ env.PYTHON_BRIDGE_VERSION }}
|
||||
files: bridges/python/dist/artifact/*.zip
|
||||
@@ -0,0 +1,91 @@
|
||||
name: Pre-release TCP server
|
||||
|
||||
on: workflow_dispatch
|
||||
|
||||
env:
|
||||
PIPENV_PIPFILE: tcp_server/src
|
||||
PIPENV_VENV_IN_PROJECT: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04, macos-latest, windows-latest]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.9.10
|
||||
|
||||
- name: Install Pipenv
|
||||
run: pip install --upgrade pip && pip install pipenv==2022.7.24
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: lts/*
|
||||
|
||||
- name: Set TCP server version
|
||||
working-directory: tcp_server/src
|
||||
run: |
|
||||
echo "TCP_SERVER_VERSION=$(python -c "from version import __version__; print(__version__)")" >> $GITHUB_ENV
|
||||
|
||||
- name: Display TCP server version
|
||||
run: |
|
||||
echo "TCP server version: ${{ env.TCP_SERVER_VERSION }}"
|
||||
|
||||
- name: Install core
|
||||
run: npm install
|
||||
|
||||
- name: Set up TCP server
|
||||
run: npm run setup:tcp-server
|
||||
|
||||
- name: Build TCP server
|
||||
run: npm run build:tcp-server
|
||||
|
||||
- name: Upload TCP server
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
path: tcp_server/dist/*.zip
|
||||
|
||||
draft-release:
|
||||
name: Draft-release
|
||||
needs: [build]
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.9.10
|
||||
|
||||
- name: Set TCP server version
|
||||
working-directory: tcp_server/src
|
||||
run: |
|
||||
echo "TCP_SERVER_VERSION=$(python -c "from version import __version__; print(__version__)")" >> $GITHUB_ENV
|
||||
|
||||
- name: Download TCP server
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
path: tcp_server/dist
|
||||
|
||||
- uses: marvinpinto/action-automatic-releases@latest
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
automatic_release_tag: tcp-server_v${{ env.TCP_SERVER_VERSION }}
|
||||
draft: true
|
||||
prerelease: false
|
||||
title: TCP Server ${{ env.TCP_SERVER_VERSION }}
|
||||
files: tcp_server/dist/artifact/*.zip
|
||||
+22
-19
@@ -2,39 +2,42 @@ name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, develop]
|
||||
# branches: [master, develop]
|
||||
branches: [master]
|
||||
pull_request:
|
||||
branches: [master, develop]
|
||||
# branches: [master, develop]
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
|
||||
runs-on: ubuntu-20.04
|
||||
container: leonai/ci:latest
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v2
|
||||
- name: Use Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-node_modules-${{ hashFiles('package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node_modules-
|
||||
- name: Cache Pipenv
|
||||
uses: actions/cache@v2
|
||||
python-version: 3.x
|
||||
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
path: bridges/python/.venv
|
||||
key: ${{ runner.os }}-pipenv-${{ env.cache-name }}-${{ hashFiles('bridges/python/Pipfile.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pipenv-
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
node-version: 16.x
|
||||
cache: npm
|
||||
|
||||
- name: Install Pipenv
|
||||
run: pip install --upgrade pip && pip install pipenv
|
||||
|
||||
- name: Install
|
||||
run: npm install
|
||||
|
||||
- name: Run JSON tests
|
||||
run: npm run test:json
|
||||
|
||||
- name: Run over HTTP tests
|
||||
run: npm run test:over-http
|
||||
|
||||
- name: Run E2E tests
|
||||
run: npm run test:e2e
|
||||
|
||||
|
||||
+17
-7
@@ -1,28 +1,38 @@
|
||||
__pycache__/
|
||||
.idea/
|
||||
.fleet/
|
||||
.vscode/
|
||||
**/dist/
|
||||
**/dist/*
|
||||
**/build/
|
||||
**/node_modules/
|
||||
test/coverage/
|
||||
**/tmp/*
|
||||
bridges/python/.venv/*
|
||||
**/src/.venv/*
|
||||
downloads/*
|
||||
logs/*
|
||||
server/src/config/**/*.json
|
||||
bin/deepspeech/*
|
||||
core/config/**/*.json
|
||||
bin/coqui/*
|
||||
bin/flite/*
|
||||
|
||||
package-lock.json
|
||||
*.pyc
|
||||
.DS_Store
|
||||
*.sublime-workspace
|
||||
npm-debug.log
|
||||
debug.log
|
||||
.env
|
||||
!**/.gitkeep
|
||||
!bridges/python/.venv/.gitkeep
|
||||
leon.json
|
||||
bridges/python/src/Pipfile.lock
|
||||
tcp_server/src/Pipfile.lock
|
||||
!tcp_server/**/.gitkeep
|
||||
!bridges/python/**/.gitkeep
|
||||
!bridges/nodejs/**/.gitkeep
|
||||
!**/*.sample*
|
||||
packages/**/config/config.json
|
||||
skills/**/src/config.json
|
||||
packages/**/data/db/*.json
|
||||
server/src/data/leon-model.nlp
|
||||
skills/**/memory/*.json
|
||||
core/data/models/*.nlp
|
||||
package.json.backup
|
||||
.python-version
|
||||
schemas/**/*.json
|
||||
|
||||
+5
-5
@@ -1,13 +1,13 @@
|
||||
image: 'gitpod/workspace-full'
|
||||
image: gitpod/workspace-full
|
||||
|
||||
tasks:
|
||||
- before: 'npm install'
|
||||
init: 'npm run check && npm run build'
|
||||
command: 'npm start'
|
||||
- before: npm install -g @leon-ai/cli
|
||||
init: leon create birth
|
||||
command: leon start
|
||||
|
||||
ports:
|
||||
- port: 1337
|
||||
onOpen: 'notify'
|
||||
onOpen: notify
|
||||
|
||||
github:
|
||||
prebuilds:
|
||||
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
if ! [ -x "$(command -v npm)" ]; then
|
||||
echo "npm: command not found"
|
||||
echo "If you use a version manager tool such as nvm and a git GUI such as GitKraken, please read: https://typicode.github.io/husky/#/?id=command-not-found" >&2
|
||||
exit 1
|
||||
else
|
||||
npx ts-node scripts/commit-msg.js
|
||||
fi
|
||||
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"*": ["npm run lint"]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"semi": false,
|
||||
"trailingComma": "none",
|
||||
"singleQuote": true
|
||||
}
|
||||
+318
-76
@@ -1,120 +1,362 @@
|
||||
# [1.0.0-beta.4](https://github.com/leon-ai/leon/compare/1.0.0-beta.2...1.0.0-beta.4) (2021-05-01) / Getting Rid of Dust
|
||||
# [1.0.0-beta.8](https://github.com/leon-ai/leon/compare/v1.0.0-beta.7...v1.0.0-beta.8) (2023-05-01) / Binaries and TypeScript Rewrite
|
||||
|
||||
*This release includes a lot of changes that are made under the hood and are not displayed here, please **[read the blog post](https://blog.getleon.ai/getting-rid-of-dust-1-0-0-beta-4/)** to know more.*
|
||||
_Please refer to [our latest blog post](https://blog.getleon.ai/binaries-and-typescript-rewrite-1-0-0-beta-8/) for more information on the new release of our dear Leon._
|
||||
|
||||
# [1.0.0-beta.7](https://github.com/leon-ai/leon/compare/v1.0.0-beta.6...v1.0.0-beta.7) (2022-08-24) / A Much Better NLP
|
||||
|
||||
_Please [read this blog post](https://blog.getleon.ai/a-much-better-nlp-and-future-1-0-0-beta-7/) to know more about all the new features and the exciting future of Leon._
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
- **package/checker:** introduce Have I Been Pwned v3 API with API key ([0ca89fe3](https://github.com/leon-ai/leon/commit/0ca89fe32d51c80cec5f9446acf14990390a5917))
|
||||
- **server:**
|
||||
- AWS SDK new structure due to v3 and adapt Amazon Polly changes ([f15f2db7](https://github.com/leon-ai/leon/commit/f15f2db78e5781d05e5e2bcb186645966d17debf))
|
||||
- IBM Watson TTS and STT new structure ([f41ea0e9](https://github.com/leon-ai/leon/commit/f41ea0e9a1479bfd6a1cb2e8d1f70aec744c685b) | [2668c295](https://github.com/leon-ai/leon/commit/2668c295880ee753ef7ca26a91dbc7e0901febff))
|
||||
### Features
|
||||
- **package/calendar:** introduce To-Do list module ([0cdd73d6](https://github.com/leon-ai/leon/commit/0cdd73d6c24a287915f691e3b12edacd75fd383a) | [857be947](https://github.com/leon-ai/leon/commit/857be947792c650ac35847e14fc41064008cef24) | [2041be14](https://github.com/leon-ai/leon/commit/2041be14dbc01640a61de96d1982cc20cd05a8b3) | [12e8f5c3](https://github.com/leon-ai/leon/commit/12e8f5c3bfb436aa212557cd99d9926aa431ab4f) | [8575e9e3](https://github.com/leon-ai/leon/commit/8575e9e3ef01499d9f7be6d313a85d48549e9107) | [5e128df0](https://github.com/leon-ai/leon/commit/5e128df023977525de3e66ce2826aace87569308) | [602aa694](https://github.com/leon-ai/leon/commit/602aa694ac49333f48c119cf2ca2aa7f54b8ae44) | [b9693df9](https://github.com/leon-ai/leon/commit/b9693df90cbc01067e18e64db4d377e41b3fd1d4) | [581da8cd](https://github.com/leon-ai/leon/commit/581da8cd9806323aabb0e85778d645df3c0948b9) | [53f7db55](https://github.com/leon-ai/leon/commit/53f7db55c6e916751f1d59c239628d5ea8914009) | [ae073971](https://github.com/leon-ai/leon/commit/ae0739717b6a17373d8f9bc69571c67c1c571b4a))
|
||||
- **package/checker:** introduce Have I Been Pwned module ([61c1b55a](https://github.com/leon-ai/leon/commit/61c1b55af5691c03f6a6dae0cf3f236a374f1fe7) | [5a999bc6](https://github.com/leon-ai/leon/commit/5a999bc63aa0c667c4e3092daac6a05a6c4b4499) | [36368664](https://github.com/leon-ai/leon/commit/36368664fce8bcf0c17c4c83818aeb418f1e2f23) | [a7a6d885](https://github.com/leon-ai/leon/commit/a7a6d885a83455163eeca74a355177d65db156b8) | [c73ba52b](https://github.com/leon-ai/leon/commit/c73ba52ba8575a64b3329e59a50050d15281d0ec) | [8374e548](https://github.com/leon-ai/leon/commit/8374e5481022de9b134f49180a8dfe28db136261) | [a476fd0f](https://github.com/leon-ai/leon/commit/a476fd0f38f18bf8035db213be2c55f83871038d))
|
||||
- **package/network:** add speedtest module ([09ad4340](https://github.com/leon-ai/leon/commit/09ad43406d3df8ca65f385a91c159def51f91811))
|
||||
- **server:**
|
||||
- add regex entity type [3fda3526](https://github.com/leon-ai/leon/commit/3fda3526c7425bdea4b669474fa77efd61c06a8e)
|
||||
- catch unsupported action entity type [5bc6c3f1](https://github.com/leon-ai/leon/commit/5bc6c3f116d6b9ece2cc3bebdbdb08f019ee90b9)
|
||||
- NER backbone [24cf3c9a](https://github.com/leon-ai/leon/commit/24cf3c9a4facd05a4c626ff9d2e7c83a5ae15298)
|
||||
- introduce actions module [b449376f](https://github.com/leon-ai/leon/commit/b449376f61dc995e2e264c6a14ba123926f5cc58)
|
||||
### Bug Fixes
|
||||
- set correct status code for GET /downloads [690f1841](https://github.com/leon-ai/leon/commit/690f1841d681a1e48e1837e3e166228d6c2ddaf6)
|
||||
- take `.env` in consideration when using Docker [d38e6095](https://github.com/leon-ai/leon/commit/d38e6095f9b71467b8486430fba4bb7007ec4c5a)
|
||||
- spinner test [9071c927](https://github.com/leon-ai/leon/commit/9071c92790be674687590e4a896bbf44bc26fb43)
|
||||
- e2e tests by adding modules actions level [5cf77d90](https://github.com/leon-ai/leon/commit/5cf77d9011a80b326f229b2309a6910ac0f1cfa2)
|
||||
|
||||
- **package/leon:** fix english translations [90225707](https://github.com/leon-ai/leon/commit/90225707f94154021cadeb9c61bdc48c3de5aa29)
|
||||
- **package/network:** make use of new compatible speedtest lib [0c925626](https://github.com/leon-ai/leon/commit/0c925626df65858fa039972b3f3d5f38fde93eb6)
|
||||
- **package/trend:**
|
||||
- GitHub module new scraping [68414937](https://github.com/leon-ai/leon/commit/6841493740ca859000c1fd8d692b73fc79fcf500)
|
||||
- when there is no star provided on the GitHub module [563fb409](https://github.com/leon-ai/leon/commit/563fb40955e2deb5c6d0bd064fc9cc8766a6fcaf)
|
||||
- **server:**
|
||||
- make use of Basic plugin from the main NLP container [e1d5bed3](https://github.com/leon-ai/leon/commit/e1d5bed3e688db566a0cb803dda5c2d57c599d8c)
|
||||
- NER trim entity on after conditions [fa6a5a43](https://github.com/leon-ai/leon/commit/fa6a5a43a60b493aa403a44957082382494c129b)
|
||||
- remove legacy packages [07743657](https://github.com/leon-ai/leon/commit/07743657cd2954e7f850c08eea7c032c24b28a96)
|
||||
|
||||
### Features
|
||||
|
||||
- create new NLP skills resolvers model + NLP global resolvers model [602604e4](https://github.com/leon-ai/leon/commit/602604e43788c6b6be8c402d54fe54342d0cd5d6)
|
||||
- better isolate skill resolvers from global resolvers + finish up Akinator skill [905d248e](https://github.com/leon-ai/leon/commit/905d248ebf7e84b1ccc74450520228aef9a8804a)
|
||||
- transfer language from core to skills + support thematics on Akinator skill [b35a249b](https://github.com/leon-ai/leon/commit/b35a249bf68000d6708aaee4abc4cd97f5b80035)
|
||||
- actions on slot level + akinator skill progress [7101b8b4](https://github.com/leon-ai/leon/commit/7101b8b4b828b49e009da2fcdac7c5ed2e48c8f8)
|
||||
- add Cartesian sample training on resolvers + enum entities [6ed88a59](https://github.com/leon-ai/leon/commit/6ed88a5946c77b356e49fe8b9cbe890b8dd1f037)
|
||||
- map skills resolvers intents [eb5ade76](https://github.com/leon-ai/leon/commit/eb5ade76844dd14f5d5a5c5eeb434eed70fe62f4)
|
||||
- train skills resolvers and remap as per changes [82df0a3c](https://github.com/leon-ai/leon/commit/82df0a3c235fbd50ad0cfe12e23a51f777dcd658)
|
||||
- achieve Cartesian training [a1e9011d](https://github.com/leon-ai/leon/commit/a1e9011d5db48ed8e9f49cef2d813ee7e2400ec2)
|
||||
- introduce suggestions [dcddacca](https://github.com/leon-ai/leon/commit/dcddacca2956529de0aea8ff98e1e6f16104966a)
|
||||
- communicate suggestions to the client [4b5a8835](https://github.com/leon-ai/leon/commit/4b5a883510fd4421a491f999cc21d8f7dd369a03)
|
||||
- shared skills memory [795acc5b](https://github.com/leon-ai/leon/commit/795acc5bdd29e9a27d1cf3b4407453648d573973)
|
||||
- support dynamic variables on skill NLU settings for logic type [10d10a16](https://github.com/leon-ai/leon/commit/10d10a1690cb65970932ee7230e3f324ec67dbce)
|
||||
- tmp resolvers mapping [b1a332ba](https://github.com/leon-ai/leon/commit/b1a332bab6af8b74a8c58c07bac3ef3a1cebad89)
|
||||
- start to map resolvers between the core and skills [e88495a9](https://github.com/leon-ai/leon/commit/e88495a9a94e86026fd0c7c4c44f3ff06edb2e80)
|
||||
- train affirmation and denial resolver [993d52e8](https://github.com/leon-ai/leon/commit/993d52e8686f335039ff3d5e2a82c1a37efb1825)
|
||||
- Python TCP server and Node.js TCP client for IPC (wip) [5970ec9e](https://github.com/leon-ai/leon/commit/5970ec9e8e4c2784c50e2ddc76b34b71aa4310e6)
|
||||
- introduce spaCy for complete NER (wip) [caa86fc8](https://github.com/leon-ai/leon/commit/caa86fc8a6850b18f67ba7bedb423be693a88d17)
|
||||
- slot filling (wip) [76547d94](https://github.com/leon-ai/leon/commit/76547d9411c32e0eb2ccfdac3a4901d2d2fb37f6)
|
||||
- share data across domains [f4f9fff9](https://github.com/leon-ai/leon/commit/f4f9fff9783861be183990d7869973c7a30c8104)
|
||||
- dynamic variable binding on NLG [0367b44f](https://github.com/leon-ai/leon/commit/0367b44f211c1629fffe6981a730f171707bf0c0)
|
||||
- context and slot filling preparation (wip) [975b8ebc](https://github.com/leon-ai/leon/commit/975b8ebcf00db91b44dd067be6dde5c1bf32fff1)
|
||||
- annotate entities on the fly + prepare for dialog skill type and cross-domains data [4107932d](https://github.com/leon-ai/leon/commit/4107932d000086188d6f44ef67b73cc322fc58e5)
|
||||
- new NLP training [d8023308](https://github.com/leon-ai/leon/commit/d8023308d0ef1f3eede37f21f45daa2f893031b0)
|
||||
|
||||
- **server:**
|
||||
- trigger next action suggestions or current ones [244d08c0](https://github.com/leon-ai/leon/commit/244d08c0bd0fea315269f52ab899f9b7fe083f51)
|
||||
- introduce main NLP model and resolvers NLP model [e37526d9](https://github.com/leon-ai/leon/commit/e37526d9056d858ebcf17b81f6714f47b67c77cb)
|
||||
- change log emojis [843bc428](https://github.com/leon-ai/leon/commit/843bc428b8deb397e2d051a8e0bfaf1b82b459a2)
|
||||
- provide nextAction even when no slot is set and clean up NLU object on context switch [8377c63d](https://github.com/leon-ai/leon/commit/8377c63db4e4e42ed929171cd8b9abdb13c44b2a)
|
||||
- report full traceback from skills execution [b69b1fea](https://github.com/leon-ai/leon/commit/b69b1fea16250421bc7d5def1c973dd43e453071)
|
||||
- support on-the-fly entity annotation for built-in entities [567b030c](https://github.com/leon-ai/leon/commit/567b030c4fcf8df266c39cca61a146fb33b9e0fc)
|
||||
- save slots within conversation context [fce47cdb](https://github.com/leon-ai/leon/commit/fce47cdbd570993ac5cca2b4ff5bc97969df4e40)
|
||||
- resolve resolvers tmp [ceea47ff](https://github.com/leon-ai/leon/commit/ceea47ff7dd536bfd3adf3cc355e90e3e94b1cbd)
|
||||
- prepare the next action on non-slot-filled skills [0acb31a9](https://github.com/leon-ai/leon/commit/0acb31a9c61c1c094b29f3d0ff2647d625eab0be)
|
||||
- add more affirmative utterance samples [870ab2e8](https://github.com/leon-ai/leon/commit/870ab2e87eba2c548d38dc90d30553e7fa380c1e)
|
||||
- restart a skill with the original utterance saved in context [f4446ef1](https://github.com/leon-ai/leon/commit/f4446ef17796d38d0f98d5b7e889503622a1a998)
|
||||
- clean up context if the action loop does not meet the expected items [035c9d52](https://github.com/leon-ai/leon/commit/035c9d5240472ac19a84ae8c1a87844fa0d0af5d)
|
||||
- add handsigns custom entity [1529c720](https://github.com/leon-ai/leon/commit/1529c72039092c7b8f37304d6064e04f2dc7b795)
|
||||
- reprocess NLU in case of slot filling interruption [9e242d77](https://github.com/leon-ai/leon/commit/9e242d77d32109e9355eec422790a5a66fd18f9c)
|
||||
- handle action loop when slots have all been filled at once [f8830502](https://github.com/leon-ai/leon/commit/f88305020a5bc79056b7ff9c1a31f8d3c3a7cdce)
|
||||
- break the action loop from the skill [27dc801c](https://github.com/leon-ai/leon/commit/27dc801cf53de5af3d54b95f42d2b9e627090867)
|
||||
- stop action loop from skill to core [99681e25](https://github.com/leon-ai/leon/commit/99681e257795a18361be379b93244088401f640b)
|
||||
- introduce basic concept of action loop [c5b38400](https://github.com/leon-ai/leon/commit/c5b38400821e5bc5edc4402d007f815f24319d44)
|
||||
- prepare action loop feature [19e1aa22](https://github.com/leon-ai/leon/commit/19e1aa22f6e989e90eb745e3a7b7ccb8ff5adbfa)
|
||||
- add current utterance entities to differentiate from the whole context [8b56a185](https://github.com/leon-ai/leon/commit/8b56a1850c9d76e335f1bad1b4395d73ddc5ea19)
|
||||
- when a context is activated, pick up the most probable classification [8e186879](https://github.com/leon-ai/leon/commit/8e1868798c8750c19b1719a44dc6fb8bca68b250)
|
||||
- persist entities into contexts [87575773](https://github.com/leon-ai/leon/commit/875757739f6701f54805eeff2c7c350cff36c4ac)
|
||||
- forward slots to skill + add original utterance [68e40f65](https://github.com/leon-ai/leon/commit/68e40f65df0d1fe29ccad991868a2408c6e1015e)
|
||||
- handle case when all slots have been filled in one utterance [22e9234b](https://github.com/leon-ai/leon/commit/22e9234b3d2c97e83eaafaeeb5aa9d27c351c95a)
|
||||
- trigger next action once all slots have been filled [9b870010](https://github.com/leon-ai/leon/commit/9b870010dd929bc1aed6d87696f1cc4e9f177c0b)
|
||||
- complete slot filling before triggering the next action [9124687e](https://github.com/leon-ai/leon/commit/9124687eb0e17295a30f860752ee622ba44d1440)
|
||||
- from modules to skills with type at the actions level [77ebaf4a](https://github.com/leon-ai/leon/commit/77ebaf4a9c78b2e471d39872e361ea05b163580d)
|
||||
- verify if all slots are filled [e27c1b9c](https://github.com/leon-ai/leon/commit/e27c1b9c8f5c2f668f464f152ad227d65ba5ef6b)
|
||||
- context and slot filling, keep context and await for entities [25adf406](https://github.com/leon-ai/leon/commit/25adf406c810e48b1277105dd6c269a2ed601d28)
|
||||
- unstack oldest context [1ece25a4](https://github.com/leon-ai/leon/commit/1ece25a497acc9f9876fe158ace5da38beec31e6)
|
||||
- context setup with slot for each conversation (wip) [8257eb87](https://github.com/leon-ai/leon/commit/8257eb8792c9f4fc90bcc1b393d3fddf8ff541dc)
|
||||
- resolve slots from slot filling [960a6dc7](https://github.com/leon-ai/leon/commit/960a6dc71c2efb50ad6a8448d447ebd79c559c41)
|
||||
- pickup questions for slot filling [3bbc2f8a](https://github.com/leon-ai/leon/commit/3bbc2f8a254d10f0c37cdb7abf016b3e418f594a)
|
||||
- main slots structure (wip) [1d9b1809](https://github.com/leon-ai/leon/commit/1d9b18093b6e042ae49f557149a7822b4420cdb8)
|
||||
- introduce resolvers for slot filling (wip) [334bf393](https://github.com/leon-ai/leon/commit/334bf393f2c43edd326d9de2e93c037ffeebeab5)
|
||||
- slot filling PoC (tmp wip) [95bfcfe4](https://github.com/leon-ai/leon/commit/95bfcfe422f21a2946e50031a3623675dfe81b9d)
|
||||
- slot filling (wip) [969a83e6](https://github.com/leon-ai/leon/commit/969a83e6081de20ec5e2bdd0329a21a3fe448f13)
|
||||
- trigger unsupported language [1845eed7](https://github.com/leon-ai/leon/commit/1845eed71dadd5f693d76abd7633864014bf8af1)
|
||||
- context (wip) [d1c2a11d](https://github.com/leon-ai/leon/commit/d1c2a11d8284ca4e1d4563b871c50c006e8ef8a0)
|
||||
- context (wip) [a9a43ac4](https://github.com/leon-ai/leon/commit/a9a43ac478c46f3832d2af49c287bb574a70cc14)
|
||||
- differenciate cities from countries for location entities [bf9bf231](https://github.com/leon-ai/leon/commit/bf9bf231f714e1edc1417e43af12fa54c00ba064)
|
||||
- auto restart the TCP server when language is switching [9be7c700](https://github.com/leon-ai/leon/commit/9be7c700767672ac6e0c875d3b5ae7fa6414e4fa)
|
||||
- support multi languages on TCP server [a808742c](https://github.com/leon-ai/leon/commit/a808742c927d45c18df45af133e67c98d4a0415a)
|
||||
- add auto reconnect on TCP client [cbe89ed6](https://github.com/leon-ai/leon/commit/cbe89ed6ccfd727356eb34078a8a4348b2fd696f)
|
||||
- make TCP client global [006e9fb0](https://github.com/leon-ai/leon/commit/006e9fb01148c2107f6acc6a562ace4809da92be)
|
||||
- fully implement low-level networking for IPC [8acb82da](https://github.com/leon-ai/leon/commit/8acb82da9bacdb9b7952c4a4d130d094e07def5e)
|
||||
- more accurate NLG [d5577b1e](https://github.com/leon-ai/leon/commit/d5577b1ef5cf1b8b4a924636ba4425b8b4ae133d)
|
||||
- unknown_answers fallback on dialog type [28efe6e7](https://github.com/leon-ai/leon/commit/28efe6e7d542f19bf12ddede1815f7fa8cf01036)
|
||||
- deep data mapping on enum NER [3ca48265](https://github.com/leon-ai/leon/commit/3ca48265e7115c8e0f02c65ba92d90412325ad76)
|
||||
- NLG and entities mapping [8f2f935b](https://github.com/leon-ai/leon/commit/8f2f935b949ceb965941460d4ff1ed0084b72442)
|
||||
- bootstrap skill structure [fe90c68e](https://github.com/leon-ai/leon/commit/fe90c68ea0e9b0e857b62aa9f3b0a42ba1ffed6b)
|
||||
- on-the-fly language switching [f24513a2](https://github.com/leon-ai/leon/commit/f24513a22395d1903e485883f4813cdceccdbd18)
|
||||
- new NLP containers [34b2aa56](https://github.com/leon-ai/leon/commit/34b2aa5655e55284d59db4569960c49965a0483c)
|
||||
- (WIP) NLU refactoring [ca3f5f42](https://github.com/leon-ai/leon/commit/ca3f5f42da26eb634e10b56e9b84bd45b5543024)
|
||||
- add skills domains [cf2a28aa](https://github.com/leon-ai/leon/commit/cf2a28aac2d936cc15e6aa9aa13747015d952053)
|
||||
- **skill/akinator:**
|
||||
- finish up [79e7df02](https://github.com/leon-ai/leon/commit/79e7df022f7daedf43db7f892e049a31924ce985)
|
||||
- finished main business logic [76cae42f](https://github.com/leon-ai/leon/commit/76cae42fdeac0edcd3ebd6aa7718728617687b1b)
|
||||
- backbone [02a2f714](https://github.com/leon-ai/leon/commit/02a2f71470bb4c0c6ca04526e89461d863d17145)
|
||||
- **skill/birthday:**
|
||||
remove birthday skill [be0b345d](https://github.com/leon-ai/leon/commit/be0b345d3f7fea562548e3fbed62b65c32eff4c0)
|
||||
- **skill/color:**
|
||||
introduce color skill [ce00989b](https://github.com/leon-ai/leon/commit/ce00989b01f65c5cbb5a2e13f454207c1ba7741c)
|
||||
- **skill/guess_the_number:**
|
||||
introduce the Guess the Number skill [fba80966](https://github.com/leon-ai/leon/commit/fba80966c937a32182e48670c47358babb539d64)
|
||||
- **skill/introduction:**
|
||||
- add one utterance sample [af0fdd1e](https://github.com/leon-ai/leon/commit/af0fdd1e18975bf8b60abb2957ddf79831281817)
|
||||
- ask about owner info if necessary [c5cc9bdd](https://github.com/leon-ai/leon/commit/c5cc9bdd52afaaa710f9476d1e9918f3d168e243)
|
||||
- **skill/mbti:**
|
||||
- complete form resolver [aad9f3f1](https://github.com/leon-ai/leon/commit/aad9f3f1ef61499d438ea40c9d2d95764667678d)
|
||||
- finish business logic [99a3f103](https://github.com/leon-ai/leon/commit/99a3f103e00b5a58745ee851d2fa95c61871f75a)
|
||||
- questions mapping [ae4f69f7](https://github.com/leon-ai/leon/commit/ae4f69f7c7189ff75e004f68c9a2a8b6bb37b6bd)
|
||||
- complete questionnaire [7f1f8871](https://github.com/leon-ai/leon/commit/7f1f8871598746c5475b24e086ea6e581f2a988e)
|
||||
- main logic backbone [33109a4c](https://github.com/leon-ai/leon/commit/33109a4c8b5df82e7b98e48e66f8d53f0cc114fb)
|
||||
- main NLU structure [skip ci] [86d5040a](https://github.com/leon-ai/leon/commit/86d5040a7dc2006036c7e67a2cf54a4c992e64aa)
|
||||
- **skill/rochambeau:**
|
||||
- add start answers [192dd0a8](https://github.com/leon-ai/leon/commit/192dd0a87ab5dc025bb90b20b187e36a58be54ea)
|
||||
- introduce paper scissors rock [57370470](https://github.com/leon-ai/leon/commit/573704706c843d870f2498146bc3cd659bab4f06)
|
||||
- init [7f5e30ac](https://github.com/leon-ai/leon/commit/7f5e30ac82f2a2d7579e361229a4044348915867)
|
||||
- **web app:**
|
||||
- join us on Discord [141c89ec](https://github.com/leon-ai/leon/commit/141c89ecbfd329a8e63d5a603d0ae6b42f9abf38)
|
||||
- wait for TCP client to be connected first [bc228a68](https://github.com/leon-ai/leon/commit/bc228a68600c07871c489d6624bbc837971079a6)
|
||||
### Bug Fixes
|
||||
- check script with new intent-object format [fdf0a389](https://github.com/leon-ai/leon/commit/fdf0a389b76caba5dd47996a43a34c0c7821c70a)
|
||||
- check new resolvers paths [cfd8f7cb](https://github.com/leon-ai/leon/commit/cfd8f7cbe5e8fd9ce3d1659c725d7af261db8d71)
|
||||
- use ports.ubuntu.com mirror for the offline TTS [skip ci] [3dd90396](https://github.com/leon-ai/leon/commit/3dd9039678820fceb7ccbb1c96358c8d2f188ede)
|
||||
- set skill config only when a bridge is set [7513aa7d](https://github.com/leon-ai/leon/commit/7513aa7d20fee1fe9ca5442a7909d22fd1c3b39e)
|
||||
- only set skill config when it is a logic type [9ce9a8bc](https://github.com/leon-ai/leon/commit/9ce9a8bc4fe0864730a08d8e9a436982f1365aa5)
|
||||
- **docker:**
|
||||
- usage of Ubuntu base image with pyenv and nvm (#408) [f507f6f7](https://github.com/leon-ai/leon/commit/f507f6f7e499f56768b3e624164cbcd58193b153)
|
||||
- check should not allocate a pseudo-TTY (#359) [4372b45f](https://github.com/leon-ai/leon/commit/4372b45fc605893d4130cf7110dd87519b934345)
|
||||
- **server:**
|
||||
- make leon handle multiple socket.io-client instances [6e7c0aac](https://github.com/leon-ai/leon/commit/6e7c0aac57008b152b45f1b0f3886ae38777467b)
|
||||
- fallback on global resolver during resolver classification [ec77dd0f](https://github.com/leon-ai/leon/commit/ec77dd0f02a8ae94fb3f02c7b7847b5509d71406)
|
||||
- make use of current entities to match global entities [a8d82050](https://github.com/leon-ai/leon/commit/a8d82050c86b5c24c4c898c06e5ffc3882524c0b)
|
||||
- multiple slots filling [2ac1bc63](https://github.com/leon-ai/leon/commit/2ac1bc63ccd11757d586adfb2e75ce04e3ffbcb5)
|
||||
- context switching on action loop [6712ae55](https://github.com/leon-ai/leon/commit/6712ae5539ef44ed33e360cfcad71c760c4b13b1)
|
||||
- check one-shot slot filling case causing infinite loop [782a3aaa](https://github.com/leon-ai/leon/commit/782a3aaa0a07dda667557bc84db906b3fa9b237c)
|
||||
- clean up active context after all slots have been filled [faabc2c7](https://github.com/leon-ai/leon/commit/faabc2c7b0992fcea035eedf66103d84b101e1a7)
|
||||
- correctly extract all spaCy entities [6aa60bfb](https://github.com/leon-ai/leon/commit/6aa60bfbd8c72e678fe3faf5e7f9dbd37dfd209f)
|
||||
- intent not found [8280c658](https://github.com/leon-ai/leon/commit/8280c65897dba0fe470a3589d151b391c51e344e)
|
||||
- fallback due to modules to skills refactoring [ef0c54b2](https://github.com/leon-ai/leon/commit/ef0c54b22667ef2bd1d2c07003f6b4beb5fa25c0)
|
||||
- NER due to modules to skills refactoring [e4d3904c](https://github.com/leon-ai/leon/commit/e4d3904ceeb2a3ee2c0187a1817331fac916e1a7)
|
||||
- **skill/akinator:**
|
||||
remove direct end on guess action [f6461f73](https://github.com/leon-ai/leon/commit/f6461f733b4a5d944dfa4a987dd1109628c6cbca)
|
||||
- **skill/color:**
|
||||
more appropriate answer [cb18ed63](https://github.com/leon-ai/leon/commit/cb18ed6397cb0e0ad8fbea30c57d7d40137441ee)
|
||||
- **skill/rochambeau:**
|
||||
final logic [0ebc0518](https://github.com/leon-ai/leon/commit/0ebc0518e61b899c35dd13df65a43f69399e784d)
|
||||
### Performance Improvements
|
||||
- check Pipfile instead of Pipfile.lock to judge whether Python packages must be installed [afdb71f7](https://github.com/leon-ai/leon/commit/afdb71f766f2956c5cb4a5e0be9025340d1a89db)
|
||||
|
||||
### Documentation Changes
|
||||
- add minimum Pipenv version requirement to README [72e46bd6](https://github.com/leon-ai/leon/commit/72e46bd6c175a4a149fb6b14522823b224d7c152)
|
||||
- hunt broken links [b2a22792](https://github.com/leon-ai/leon/commit/b2a2279243e7566b57fb7f696024bdf08294e853)
|
||||
- add "ci" commit type in CONTRIBUTING.md [09e2672b](https://github.com/leon-ai/leon/commit/09e2672b0b399f5ce9dd7cd446d04f4d6fd7c13a)
|
||||
- use emojies in README [0ea7a78b](https://github.com/leon-ai/leon/commit/0ea7a78b7c94dc44c992913ae1c90fb1cf8a7692)
|
||||
- add social badges to README [c55c7532](https://github.com/leon-ai/leon/commit/c55c7532b25bf420c4819be71b0f9c21ccc58711)
|
||||
- Node.js 14 requirement [d1034bd1](https://github.com/leon-ai/leon/commit/d1034bd135fd5a6314a1571d4088fd85a8e6a1da)
|
||||
|
||||
- change newsletter link [4bf2a9af](https://github.com/leon-ai/leon/commit/4bf2a9af963f75aeff96f4a43da8ec1024ac583a)
|
||||
- README - Edited sentence for clarity (#389) [e83a1c42](https://github.com/leon-ai/leon/commit/e83a1c4230897e8b63251ef86225cf773148c38e)
|
||||
- edit newsletter link [fa558a44](https://github.com/leon-ai/leon/commit/fa558a447ade4071f352d56f14602690ed90f521)
|
||||
- update sponsor [skip ci] [f30ddb6b](https://github.com/leon-ai/leon/commit/f30ddb6be5f531df2b0042be0ed5ffbe79f73b07)
|
||||
- remove sponsor [skip ci] [5dbc010f](https://github.com/leon-ai/leon/commit/5dbc010fa643279a24081f3148022e2211af63f4)
|
||||
- remove sponsor [skip ci] [f36dd20f](https://github.com/leon-ai/leon/commit/f36dd20f822cd33c9e8a03efc2849c8d8d1fc75e)
|
||||
- remove sponsor [skip ci] [5ee57ddf](https://github.com/leon-ai/leon/commit/5ee57ddf2a9f7817ec35b2e70d49e5bb422d8f78)
|
||||
- add @ant-media sponsor [skip ci] [b47cbc3a](https://github.com/leon-ai/leon/commit/b47cbc3a5ecb6591f7abb4f62feae8102b9a6468)
|
||||
- add long dev notice to README [skip ci] [499be77d](https://github.com/leon-ai/leon/commit/499be77d509231b853f591e27f726381da5a50d8)
|
||||
- move sponsor to new section [skip ci] [8825d687](https://github.com/leon-ai/leon/commit/8825d6877c19d86495e89a858b859b7ab1f9ae37)
|
||||
- change Twitter handle [skip ci] [c1afc11c](https://github.com/leon-ai/leon/commit/c1afc11cdb283526540d0fecdf83efddf3f3a9f7)
|
||||
- remove sponsor [skip ci] [99b401a6](https://github.com/leon-ai/leon/commit/99b401a668a6fb248e33c22782940402be7c9b17)
|
||||
- add new sponsor self-hosted img [skip ci] [238d928c](https://github.com/leon-ai/leon/commit/238d928cace13d4ecd174ca14b136967d8845e0f)
|
||||
- remove new sponsor link (broken) [skip ci] [254f2848](https://github.com/leon-ai/leon/commit/254f2848aab622b79cce16d10c58d53ff6db9a8f)
|
||||
- in GitHub BUG.md from modules to skills [4a5480a3](https://github.com/leon-ai/leon/commit/4a5480a3ccc54ee34d42f6edcec2a40224dee7ed)
|
||||
- change @FluxIndustries sponsorship [skip ci] [1a118b71](https://github.com/leon-ai/leon/commit/1a118b718e5d4ade123756ac94758a01c50b12ae)
|
||||
- add @FluxIndustries sponsor [skip ci] [9a604d7c](https://github.com/leon-ai/leon/commit/9a604d7ccc0c6aaec257299078141dd0c3077933)
|
||||
- new #LeonAI link [skip ci] [a0107d62](https://github.com/leon-ai/leon/commit/a0107d629473f7fd057d367926e83822d46f1227)
|
||||
- changelog new version diff link fix [skip ci] [e14c2498](https://github.com/leon-ai/leon/commit/e14c249826db92af7b85422e566be6aa834a7fb7)
|
||||
|
||||
# [1.0.0-beta.6](https://github.com/leon-ai/leon/compare/v1.0.0-beta.5...v1.0.0-beta.6) (2022-02-07) / Leon Over HTTP + Making Friends with Coqui STT
|
||||
|
||||
### Features
|
||||
|
||||
- simple coqui-ai stt integration [86a4816b](https://github.com/leon-ai/leon/commit/86a4816b777fee8ec9c89648c5866a75de56c017)
|
||||
- HTTP API key generator [d10a7fa7](https://github.com/leon-ai/leon/commit/d10a7fa7880a0bf2fb1cae7904d1ef4257f05257)
|
||||
- avoid unnecessary routes generation
|
||||
|
||||
- **server:**
|
||||
- make Coqui STT the default STT solution [70399187](https://github.com/leon-ai/leon/commit/7039918760c0ef7ba93bf45820e3cae774c42d8c)
|
||||
- add HTTP API key middleware [cdf41499](https://github.com/leon-ai/leon/commit/cdf4149939cbe3f3ae81039957dba3377a78f5a6)
|
||||
- expose queries over HTTP [b6428d03](https://github.com/leon-ai/leon/commit/b6428d038452619f1682c863892cd8f376efca84)
|
||||
- add timeout action over HTTP [115f9c16](https://github.com/leon-ai/leon/commit/115f9c164559d761625cc6f362749f7d2417d300)
|
||||
- handle built-in and trim entities over HTTP + add "disabled" HTTP API action option [82fb967a](https://github.com/leon-ai/leon/commit/82fb967af8f49421e3b2474184da3d34fb17294f)
|
||||
- execute modules over HTTP [2e5b2c59](https://github.com/leon-ai/leon/commit/2e5b2c59da0bafe3acd966773c6fac3611b3bd0c)
|
||||
- generate Fastify routes on the file to expose packages over HTTP [5b41713a](https://github.com/leon-ai/leon/commit/5b41713a68ee628e695212dbebc88f6b9a94b461)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- do not ask to regenerate the HTTP API key if this one isn't available yet [d265377a](https://github.com/leon-ai/leon/commit/d265377a43fd4506cf12db46f261b891f2054ed2)
|
||||
- Python deps tree check [c6c01291](https://github.com/leon-ai/leon/commit/c6c012915824227efdf0c50df6a8f1cd8d70ed42)
|
||||
- hotword offline (#342) [f563d01d](https://github.com/leon-ai/leon/commit/f563d01d077499c836e94c86f85cedc2ad4d56e6)
|
||||
- addressed comments by @JRMeyer [b1c6f5c8](https://github.com/leon-ai/leon/commit/b1c6f5c883103d57d4fe566af640fc3ac5ce713d)
|
||||
- allow to detect STT offline capabilities [04d62288](https://github.com/leon-ai/leon/commit/04d622884165e0bde65785569a659f59cf9e8582)
|
||||
- Amazon Polly is always configured on check script due to new structure [e6246d1f](https://github.com/leon-ai/leon/commit/e6246d1f8f9ec15a4ebe9600764afffbaa7e62d9)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
- check if Python deps tree has been updated before going through deps install [2d0b0f13](https://github.com/leon-ai/leon/commit/2d0b0f1365d8e4d6eadf9f7cc0a16b7b4b4306f4)
|
||||
|
||||
# [1.0.0-beta.5](https://github.com/leon-ai/leon/compare/v1.0.0-beta.4...v1.0.0-beta.5) (2021-12-28) / Refocus
|
||||
|
||||
_This release marks a major turn in the future versions of the Leon core. Please [read this blog post](https://blog.getleon.ai/i-ran-away-from-open-source/) to know more._
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
- Node.js 16+ and npm 8+ minimum requirements [2f66f1c1](https://github.com/leon-ai/leon/commit/2f66f1c17bb2e4a1c18b4251d49de252b8d87344)
|
||||
|
||||
### Features
|
||||
|
||||
- **server:** support arrays on NER between conditions [7cf7f979](https://github.com/leon-ai/leon/commit/7cf7f9791254e1950fe9128ce1b3a58079cc2ada)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- jest-extended new setup due to latest update [02f766d6](https://github.com/leon-ai/leon/commit/02f766d6a8453609ebaec78356aa6e6d4df0967b)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
- Windows setup on DeepSpeech dep removal [13f5a49f](https://github.com/leon-ai/leon/commit/13f5a49f678f8f67a93b67d4f558cddcf237e204)
|
||||
|
||||
### Documentation Changes
|
||||
|
||||
- URL redirect managed by registrar [c16d5b28](https://github.com/leon-ai/leon/commit/c16d5b280b758f7e18305e30678adec79f0a0716)
|
||||
|
||||
# [1.0.0-beta.4](https://github.com/leon-ai/leon/compare/1.0.0-beta.2...v1.0.0-beta.4) (2021-05-01) / Getting Rid of Dust
|
||||
|
||||
_This release includes a lot of changes that are made under the hood and are not displayed here, please **[read the blog post](https://blog.getleon.ai/getting-rid-of-dust-1-0-0-beta-4/)** to know more._
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
- **package/checker:** introduce Have I Been Pwned v3 API with API key ([0ca89fe3](https://github.com/leon-ai/leon/commit/0ca89fe32d51c80cec5f9446acf14990390a5917))
|
||||
- **server:**
|
||||
- AWS SDK new structure due to v3 and adapt Amazon Polly changes ([f15f2db7](https://github.com/leon-ai/leon/commit/f15f2db78e5781d05e5e2bcb186645966d17debf))
|
||||
- IBM Watson TTS and STT new structure ([f41ea0e9](https://github.com/leon-ai/leon/commit/f41ea0e9a1479bfd6a1cb2e8d1f70aec744c685b) | [2668c295](https://github.com/leon-ai/leon/commit/2668c295880ee753ef7ca26a91dbc7e0901febff))
|
||||
|
||||
### Features
|
||||
|
||||
- **package/calendar:** introduce To-Do list module ([0cdd73d6](https://github.com/leon-ai/leon/commit/0cdd73d6c24a287915f691e3b12edacd75fd383a) | [857be947](https://github.com/leon-ai/leon/commit/857be947792c650ac35847e14fc41064008cef24) | [2041be14](https://github.com/leon-ai/leon/commit/2041be14dbc01640a61de96d1982cc20cd05a8b3) | [12e8f5c3](https://github.com/leon-ai/leon/commit/12e8f5c3bfb436aa212557cd99d9926aa431ab4f) | [8575e9e3](https://github.com/leon-ai/leon/commit/8575e9e3ef01499d9f7be6d313a85d48549e9107) | [5e128df0](https://github.com/leon-ai/leon/commit/5e128df023977525de3e66ce2826aace87569308) | [602aa694](https://github.com/leon-ai/leon/commit/602aa694ac49333f48c119cf2ca2aa7f54b8ae44) | [b9693df9](https://github.com/leon-ai/leon/commit/b9693df90cbc01067e18e64db4d377e41b3fd1d4) | [581da8cd](https://github.com/leon-ai/leon/commit/581da8cd9806323aabb0e85778d645df3c0948b9) | [53f7db55](https://github.com/leon-ai/leon/commit/53f7db55c6e916751f1d59c239628d5ea8914009) | [ae073971](https://github.com/leon-ai/leon/commit/ae0739717b6a17373d8f9bc69571c67c1c571b4a))
|
||||
- **package/checker:** introduce Have I Been Pwned module ([61c1b55a](https://github.com/leon-ai/leon/commit/61c1b55af5691c03f6a6dae0cf3f236a374f1fe7) | [5a999bc6](https://github.com/leon-ai/leon/commit/5a999bc63aa0c667c4e3092daac6a05a6c4b4499) | [36368664](https://github.com/leon-ai/leon/commit/36368664fce8bcf0c17c4c83818aeb418f1e2f23) | [a7a6d885](https://github.com/leon-ai/leon/commit/a7a6d885a83455163eeca74a355177d65db156b8) | [c73ba52b](https://github.com/leon-ai/leon/commit/c73ba52ba8575a64b3329e59a50050d15281d0ec) | [8374e548](https://github.com/leon-ai/leon/commit/8374e5481022de9b134f49180a8dfe28db136261) | [a476fd0f](https://github.com/leon-ai/leon/commit/a476fd0f38f18bf8035db213be2c55f83871038d))
|
||||
- **package/network:** add speedtest module ([09ad4340](https://github.com/leon-ai/leon/commit/09ad43406d3df8ca65f385a91c159def51f91811))
|
||||
- **server:**
|
||||
- add regex entity type [3fda3526](https://github.com/leon-ai/leon/commit/3fda3526c7425bdea4b669474fa77efd61c06a8e)
|
||||
- catch unsupported action entity type [5bc6c3f1](https://github.com/leon-ai/leon/commit/5bc6c3f116d6b9ece2cc3bebdbdb08f019ee90b9)
|
||||
- NER backbone [24cf3c9a](https://github.com/leon-ai/leon/commit/24cf3c9a4facd05a4c626ff9d2e7c83a5ae15298)
|
||||
- introduce actions module [b449376f](https://github.com/leon-ai/leon/commit/b449376f61dc995e2e264c6a14ba123926f5cc58)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- set correct status code for GET /downloads [690f1841](https://github.com/leon-ai/leon/commit/690f1841d681a1e48e1837e3e166228d6c2ddaf6)
|
||||
- take `.env` in consideration when using Docker [d38e6095](https://github.com/leon-ai/leon/commit/d38e6095f9b71467b8486430fba4bb7007ec4c5a)
|
||||
- spinner test [9071c927](https://github.com/leon-ai/leon/commit/9071c92790be674687590e4a896bbf44bc26fb43)
|
||||
- e2e tests by adding modules actions level [5cf77d90](https://github.com/leon-ai/leon/commit/5cf77d9011a80b326f229b2309a6910ac0f1cfa2)
|
||||
|
||||
- **package/leon:** fix english translations [90225707](https://github.com/leon-ai/leon/commit/90225707f94154021cadeb9c61bdc48c3de5aa29)
|
||||
- **package/network:** make use of new compatible speedtest lib [0c925626](https://github.com/leon-ai/leon/commit/0c925626df65858fa039972b3f3d5f38fde93eb6)
|
||||
- **package/trend:**
|
||||
- GitHub module new scraping [68414937](https://github.com/leon-ai/leon/commit/6841493740ca859000c1fd8d692b73fc79fcf500)
|
||||
- when there is no star provided on the GitHub module [563fb409](https://github.com/leon-ai/leon/commit/563fb40955e2deb5c6d0bd064fc9cc8766a6fcaf)
|
||||
- **server:**
|
||||
- make use of Basic plugin from the main NLP container [e1d5bed3](https://github.com/leon-ai/leon/commit/e1d5bed3e688db566a0cb803dda5c2d57c599d8c)
|
||||
- NER trim entity on after conditions [fa6a5a43](https://github.com/leon-ai/leon/commit/fa6a5a43a60b493aa403a44957082382494c129b)
|
||||
|
||||
### Documentation Changes
|
||||
|
||||
- add minimum Pipenv version requirement to README [72e46bd6](https://github.com/leon-ai/leon/commit/72e46bd6c175a4a149fb6b14522823b224d7c152)
|
||||
- hunt broken links [b2a22792](https://github.com/leon-ai/leon/commit/b2a2279243e7566b57fb7f696024bdf08294e853)
|
||||
- add "ci" commit type in CONTRIBUTING.md [09e2672b](https://github.com/leon-ai/leon/commit/09e2672b0b399f5ce9dd7cd446d04f4d6fd7c13a)
|
||||
- use emojies in README [0ea7a78b](https://github.com/leon-ai/leon/commit/0ea7a78b7c94dc44c992913ae1c90fb1cf8a7692)
|
||||
- add social badges to README [c55c7532](https://github.com/leon-ai/leon/commit/c55c7532b25bf420c4819be71b0f9c21ccc58711)
|
||||
- Node.js 14 requirement [d1034bd1](https://github.com/leon-ai/leon/commit/d1034bd135fd5a6314a1571d4088fd85a8e6a1da)
|
||||
|
||||
# [1.0.0-beta.2](https://github.com/leon-ai/leon/compare/1.0.0-beta.1...1.0.0-beta.2) (2019-04-24)
|
||||
|
||||
### Features
|
||||
- can send custom HTTP headers
|
||||
|
||||
- can send custom HTTP headers
|
||||
([2685cdab](https://github.com/leon-ai/leon/commit/2685cdab07cc1a9ea418eab812e5163d2dd0da90))
|
||||
- allow HTML output
|
||||
- allow HTML output
|
||||
([ec3f02df](https://github.com/leon-ai/leon/commit/ec3f02dfaf2f4b7623ce350350ebee28cf18740e))
|
||||
- NLU improvement with node-nlp
|
||||
- NLU improvement with node-nlp
|
||||
([6585db71](https://github.com/leon-ai/leon/commit/6585db718ccae1d750a35783075cf61cc8fe84f1))
|
||||
|
||||
- **package/trend:**
|
||||
- add answer when the Product Hunt developer token is not provided
|
||||
([f40b479b](https://github.com/leon-ai/leon/commit/f40b479b295247c5a8a0e6ed81afe56fadfd2730))
|
||||
- Product Hunt module done
|
||||
([37794306](https://github.com/leon-ai/leon/commit/3779430621bef970be0e8d048eb0b4bf160ae8a4))
|
||||
- basics done on the Product Hunt module
|
||||
([32cc7dbe](https://github.com/leon-ai/leon/commit/32cc7dbe36592fb9618d9c10da5f05a4be7e41b6))
|
||||
- complete dedicated answers according to the technology and given time
|
||||
([8997d691](https://github.com/leon-ai/leon/commit/8997d6917445f837c9647a5a9b4d6998d2df4952))
|
||||
- GitHub module done
|
||||
([7c6f3922](https://github.com/leon-ai/leon/commit/7c6f3922f299193ee0fb54d0fc97f8b436fc706b))
|
||||
- be able to choose a limit and a date range for the GitHub module
|
||||
([3c088371](https://github.com/leon-ai/leon/commit/3c0883716e1c10371c399843a578095a1e16781d))
|
||||
- format GitHub results in one message
|
||||
([9d026b94](https://github.com/leon-ai/leon/commit/9d026b94efa8871d421ae2b593b96622a98537ac))
|
||||
- simple GitHub module results
|
||||
([5baec074](https://github.com/leon-ai/leon/commit/5baec07455f453d4ad003f1da360b2663b7e15e0))
|
||||
- list GitHub trends in HTML raw
|
||||
([3441629e](https://github.com/leon-ai/leon/commit/3441629e3cde933b322cb114d9f1bc3ef0eb3944) | [6b932e94](https://github.com/leon-ai/leon/commit/6b932e947fc365ea6435fda798b7cca32708b443))
|
||||
- expressions dataset and structure
|
||||
([f406a5a0](https://github.com/leon-ai/leon/commit/f406a5a09894e12c56a1e76dda609adada00b0d7) | [f54c2272](https://github.com/leon-ai/leon/commit/f54c2272b4b4dc5c56b512b0ccc1519d77ef15a3))
|
||||
- **package/trend:**
|
||||
- add answer when the Product Hunt developer token is not provided
|
||||
([f40b479b](https://github.com/leon-ai/leon/commit/f40b479b295247c5a8a0e6ed81afe56fadfd2730))
|
||||
- Product Hunt module done
|
||||
([37794306](https://github.com/leon-ai/leon/commit/3779430621bef970be0e8d048eb0b4bf160ae8a4))
|
||||
- basics done on the Product Hunt module
|
||||
([32cc7dbe](https://github.com/leon-ai/leon/commit/32cc7dbe36592fb9618d9c10da5f05a4be7e41b6))
|
||||
- complete dedicated answers according to the technology and given time
|
||||
([8997d691](https://github.com/leon-ai/leon/commit/8997d6917445f837c9647a5a9b4d6998d2df4952))
|
||||
- GitHub module done
|
||||
([7c6f3922](https://github.com/leon-ai/leon/commit/7c6f3922f299193ee0fb54d0fc97f8b436fc706b))
|
||||
- be able to choose a limit and a date range for the GitHub module
|
||||
([3c088371](https://github.com/leon-ai/leon/commit/3c0883716e1c10371c399843a578095a1e16781d))
|
||||
- format GitHub results in one message
|
||||
([9d026b94](https://github.com/leon-ai/leon/commit/9d026b94efa8871d421ae2b593b96622a98537ac))
|
||||
- simple GitHub module results
|
||||
([5baec074](https://github.com/leon-ai/leon/commit/5baec07455f453d4ad003f1da360b2663b7e15e0))
|
||||
- list GitHub trends in HTML raw
|
||||
([3441629e](https://github.com/leon-ai/leon/commit/3441629e3cde933b322cb114d9f1bc3ef0eb3944) | [6b932e94](https://github.com/leon-ai/leon/commit/6b932e947fc365ea6435fda798b7cca32708b443))
|
||||
- expressions dataset and structure
|
||||
([f406a5a0](https://github.com/leon-ai/leon/commit/f406a5a09894e12c56a1e76dda609adada00b0d7) | [f54c2272](https://github.com/leon-ai/leon/commit/f54c2272b4b4dc5c56b512b0ccc1519d77ef15a3))
|
||||
|
||||
### Bug Fixes
|
||||
- Leon was not fully installed with Docker if a `.env` file was existing
|
||||
|
||||
- Leon was not fully installed with Docker if a `.env` file was existing
|
||||
([c8a68ab0](https://github.com/leon-ai/leon/commit/c8a68ab02eec9ddaf803b6e36cd7e91a4989cdea))
|
||||
|
||||
- **package/trend:**
|
||||
- **package/trend:**
|
||||
when there is no contributor on GitHub module
|
||||
([d845e49b](https://github.com/leon-ai/leon/commit/d845e49b0f18caeb306e2d399c50a03883b2f55d))
|
||||
- **server:**
|
||||
- skip Pipenv locking until they fix it
|
||||
([029381e3](https://github.com/leon-ai/leon/commit/029381e3256933f37f5c2950c4eb1f0192f55ec6) | [ecfdc73f](https://github.com/leon-ai/leon/commit/ecfdc73f8290dd9e1910df9519095516a1227763))
|
||||
- **server:**
|
||||
- skip Pipenv locking until they fix it
|
||||
([029381e3](https://github.com/leon-ai/leon/commit/029381e3256933f37f5c2950c4eb1f0192f55ec6) | [ecfdc73f](https://github.com/leon-ai/leon/commit/ecfdc73f8290dd9e1910df9519095516a1227763))
|
||||
|
||||
### Documentation Changes
|
||||
- add `What is Leon able to do?` section in the readme
|
||||
|
||||
- add `What is Leon able to do?` section in the readme
|
||||
([87f53c91](https://github.com/leon-ai/leon/commit/87f53c91368141966959f3ad7299bb7b643828a5) | [d558fc8b](https://github.com/leon-ai/leon/commit/d558fc8b7c6494babf5dec799802227f77c33d8a))
|
||||
- open-source != open source
|
||||
- open-source != open source
|
||||
([16a9372e](https://github.com/leon-ai/leon/commit/16a9372e05d4d31a7a39a65a52d4708b72499d4c) | [2155cd88](https://github.com/leon-ai/leon/commit/2155cd88decbbd671bd58840291d9330ce06ebba))
|
||||
|
||||
|
||||
|
||||
# [1.0.0-beta.1](https://github.com/leon-ai/leon/compare/1.0.0-beta.0...1.0.0-beta.1) (2019-02-24)
|
||||
|
||||
### Features
|
||||
- add Docker support
|
||||
|
||||
- add Docker support
|
||||
([209760db](https://github.com/leon-ai/leon/commit/209760dba747001300692fb6a6af97543de584d6))
|
||||
|
||||
### Bug Fixes
|
||||
- **package/checker:**
|
||||
|
||||
- **package/checker:**
|
||||
isitdown module fails with capital letters in URL
|
||||
([ada6aaef](https://github.com/leon-ai/leon/commit/ada6aaef4bada47e87d28f9f6eaa05b9e23f58d2))
|
||||
- **web app:**
|
||||
- **web app:**
|
||||
enable environment variables
|
||||
([a438d6f9](https://github.com/leon-ai/leon/commit/a438d6f942812f74e3dda75a9875609f8bea21cd))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
- **web app:**
|
||||
- **web app:**
|
||||
favicon compression
|
||||
([33dbcb42](https://github.com/leon-ai/leon/commit/33dbcb425eaafba90176ff64e5f689eb36bc6ce1))
|
||||
|
||||
### Documentation Changes
|
||||
- update README to make the reader genderless
|
||||
|
||||
- update README to make the reader genderless
|
||||
([58662658](https://github.com/leon-ai/leon/commit/586626586b7a2f84cb2cd84028111976bc5172f0))
|
||||
- use "to rule them all" in README
|
||||
- use "to rule them all" in README
|
||||
([c74dda4c](https://github.com/leon-ai/leon/commit/c74dda4cb9acc78de143ae01fdc6b4ef0a5ec3ef))
|
||||
|
||||
- **readme:**
|
||||
- **readme:**
|
||||
add story write-up
|
||||
([08a68e37](https://github.com/leon-ai/leon/commit/08a68e376b6a9367425947380564120943376500))
|
||||
|
||||
|
||||
# [1.0.0-beta.0](https://github.com/leon-ai/leon/compare/https://github.com/leon-ai/leon.git...1.0.0-beta.0) (2019-02-10)
|
||||
|
||||
Initial release.
|
||||
|
||||
+52
-17
@@ -1,25 +1,60 @@
|
||||
FROM node:14-alpine
|
||||
FROM ubuntu:20.04
|
||||
ENV IS_DOCKER true
|
||||
WORKDIR /app
|
||||
|
||||
# Install system packages
|
||||
RUN apk add --no-cache --no-progress \
|
||||
ca-certificates \
|
||||
python3 \
|
||||
git \
|
||||
tzdata
|
||||
# Replace shell with bash so we can source files
|
||||
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
|
||||
|
||||
# Upgrade pip and install Pipenv
|
||||
RUN pip3 install --no-cache-dir --progress-bar off pipenv
|
||||
# Set debconf to run non-interactively
|
||||
RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
|
||||
|
||||
# Install base dependencies
|
||||
RUN apt-get update && apt-get install --yes -q --no-install-recommends \
|
||||
apt-transport-https \
|
||||
build-essential \
|
||||
ca-certificates \
|
||||
curl \
|
||||
git \
|
||||
wget \
|
||||
libssl-dev \
|
||||
openssl \
|
||||
libz-dev \
|
||||
zlib1g-dev \
|
||||
libbz2-dev \
|
||||
libreadline-dev \
|
||||
libsqlite3-dev \
|
||||
llvm \
|
||||
libncurses5-dev \
|
||||
xz-utils \
|
||||
tk-dev libxml2-dev \
|
||||
libxmlsec1-dev \
|
||||
libffi-dev \
|
||||
liblzma-dev \
|
||||
libgdbm-dev \
|
||||
libnss3-dev \
|
||||
libc6-dev
|
||||
|
||||
# Run the container as an unprivileged user
|
||||
RUN groupadd docker && useradd -g docker -s /bin/bash -m docker
|
||||
USER docker
|
||||
WORKDIR /home/docker
|
||||
|
||||
# Install Node.js with nvm
|
||||
ENV NVM_DIR /home/docker/.nvm
|
||||
ENV NODE_VERSION v16.18.0
|
||||
|
||||
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash
|
||||
RUN /bin/bash -c "source $NVM_DIR/nvm.sh && nvm install $NODE_VERSION && nvm use --delete-prefix $NODE_VERSION"
|
||||
|
||||
ENV NODE_PATH $NVM_DIR/versions/node/$NODE_VERSION/lib/node_modules
|
||||
ENV PATH $NVM_DIR/versions/node/$NODE_VERSION/bin:$PATH
|
||||
|
||||
# Install Leon
|
||||
# Need to explicitly run the npm preinstall and npm posinstall scripts (not needed with npm@7)
|
||||
# because npm tries to downgrade its privileges, and these scripts are not executed
|
||||
COPY ./package*.json ./
|
||||
RUN npm clean-install
|
||||
COPY ./ ./
|
||||
RUN npm run preinstall
|
||||
RUN npm run postinstall
|
||||
WORKDIR /home/docker/leon
|
||||
USER root
|
||||
RUN chown -R docker /home/docker/leon
|
||||
USER docker
|
||||
COPY --chown=docker ./ ./
|
||||
RUN npm install
|
||||
RUN npm run build
|
||||
|
||||
CMD ["npm", "start"]
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019-present, Louis Grenard <louis.grenard@gmail.com>
|
||||
Copyright (c) 2019-present, Louis Grenard <louis@getleon.ai>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<p align="center">
|
||||
<a href="https://getleon.ai"><img width="96" src="https://getleon.ai/img/logo.svg"></a><br><br>
|
||||
<a href="https://www.youtube.com/watch?v=p7GRGiicO1c"><img width="512" src="https://getleon.ai/img/1.0.0-beta.0_preview_en.png"></a><br>
|
||||
<a href="https://getleon.ai"><img width="800" src="https://getleon.ai/img/hero-animation.gif" /></a>
|
||||
</p>
|
||||
|
||||
<h1 align="center">Leon</h1>
|
||||
<h1 align="center">
|
||||
<a href="https://getleon.ai"><img width="96" src="https://getleon.ai/img/logo.svg" alt="Leon"></a><br>
|
||||
Leon
|
||||
</h1>
|
||||
|
||||
*<p align="center">Your open-source personal assistant.</p>*
|
||||
_<p align="center">Your open-source personal assistant.</p>_
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/leon-ai/leon/blob/develop/LICENSE.md"><img src="https://img.shields.io/badge/license-MIT-blue.svg?label=License&style=flat" /></a>
|
||||
@@ -16,24 +18,65 @@
|
||||
<a href="https://github.com/leon-ai/leon/actions/workflows/lint.yml"><img src="https://github.com/leon-ai/leon/actions/workflows/lint.yml/badge.svg?branch=develop" /></a>
|
||||
<br>
|
||||
<a href="https://discord.gg/MNQqqKg"><img src="https://svgshare.com/i/V09.svg"/></a>
|
||||
<a href="https://twitter.com/louistiti_fr"><img src="https://img.shields.io/twitter/follow/louistiti_fr?label=Follow&style=social" /></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://getleon.ai">Website</a> ::
|
||||
<a href="https://docs.getleon.ai">Documentation</a> ::
|
||||
<a href="https://roadmap.getleon.ai">Roadmap</a> ::
|
||||
<a href="http://roadmap.getleon.ai">Roadmap</a> ::
|
||||
<a href="https://github.com/leon-ai/leon/blob/develop/.github/CONTRIBUTING.md">Contributing</a> ::
|
||||
<a href="https://blog.getleon.ai/the-story-behind-leon/">Story</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## Current State
|
||||
|
||||
### Why is there a small amount of contributors?
|
||||
|
||||
I'm taking a lot of time to work on the new core of Leon due to personal reasons. I can only work on it after work and on weekends. Hence, **I'm blocking any potential contribution as the whole core of Leon is coming with many breaking changes**. Many of you are willing to contribute in Leon (create new skills, help to improve the core, translations and so on...), a big thanks to every one of you!
|
||||
|
||||
I wish one day I could work on Leon full time, but it's not possible at the moment as I need to pay my bills. I have some ideas about how to monetize Leon in the future (Leon's core will always remain open source), but before to get there there is still a long way to go.
|
||||
|
||||
Until then, any financial support by [sponsoring Leon](http://sponsor.getleon.ai) is much appreciated 🙂
|
||||
|
||||
### How about large language models and Leon?
|
||||
|
||||
Since AI gained in popularity and large language models are getting more and more traction, many of you joined our community. A huge welcome to all of you! 🤗
|
||||
|
||||
At the moment, Leon's NLU will remain intents first with his own model without relying on an LLM. It is important that Leon can run 100% offline and I'm confident that with the downsizing techniques such as quantization Leon will sooner or later work with LLMs at his core and still be able to run on edge.
|
||||
|
||||
Here is how LLMs may help Leon in the future:
|
||||
|
||||
- Intent fallback: when an utterance cannot match an intent, then rely on an LLM to provide results.
|
||||
- New named entity recognition engine: provide a better solution to extract entities from utterances such as fruits, numbers, cities, durations, persons, etc.
|
||||
- Skill features: let skills leverage LLMs to provide out-of-the-box NLP features such as summarization, translation, sentiment analysis and so on...
|
||||
- Skill building: LLMs can help to develop skills such as paraphrasing utterance samples, translate answers, convert code from our Python bridge to the upcoming JavaScript bridge and vice versa, etc.
|
||||
- More...
|
||||
|
||||
### What's Next?
|
||||
|
||||
Once the new core released, we'll work on the community aspect of Leon. For example, better organize [our Discord](https://discord.gg/MNQqqKg), planify regular calls, work on skills together, etc. It is very important for Leon to have a real community. At that moment, the skills platform will already be online, so it'll be easier to sync our progress and publish new skills.
|
||||
|
||||
- Feel free to check out the Git development branches and our [next major milestones](https://blog.getleon.ai/a-much-better-nlp-and-future-1-0-0-beta-7/#whats-next).
|
||||
- And the [detailed roadmap](http://roadmap.getleon.ai).
|
||||
- Many exciting things are coming up, hence no new documentation and test are going to be written until the official release of Leon.
|
||||
|
||||
---
|
||||
|
||||
## Latest Release
|
||||
|
||||
Check out the [latest release blog post](https://blog.getleon.ai/binaries-and-typescript-rewrite-1-0-0-beta-8/).
|
||||
|
||||
<a href="https://blog.getleon.ai/binaries-and-typescript-rewrite-1-0-0-beta-8/"><img width="400" src="https://blog.getleon.ai/static/a0d1cbafd1968e7531dc17e229f8cc61/aa440/beta-8.png" /></a>
|
||||
|
||||
---
|
||||
|
||||
## 👋 Introduction
|
||||
|
||||
**Leon** is an **open-source personal assistant** who can live **on your server**.
|
||||
|
||||
He **does stuff** when you **ask him for**.
|
||||
He **does stuff** when you **ask him to**.
|
||||
|
||||
You can **talk to him** and he can **talk to you**.
|
||||
You can also **text him** and he can also **text you**.
|
||||
@@ -42,10 +85,10 @@ If you want to, Leon can communicate with you by being **offline to protect your
|
||||
### Why?
|
||||
|
||||
> 1. If you are a developer (or not), you may want to build many things that could help in your daily life.
|
||||
> Instead of building a dedicated project for each of those ideas, Leon can help you with his
|
||||
> packages/modules (skills) structure.
|
||||
> 2. With this generic structure, everyone can create their own modules and share them with others.
|
||||
> Therefore there is only one core (to rule them all).
|
||||
> Instead of building a dedicated project for each of those ideas, Leon can help you with his
|
||||
> Skills structure.
|
||||
> 2. With this generic structure, everyone can create their own skills and share them with others.
|
||||
> Therefore there is only one core (to rule them all).
|
||||
> 3. Leon uses AI concepts, which is cool.
|
||||
> 4. Privacy matters, you can configure Leon to talk with him offline. You can already text with him without any third party services.
|
||||
> 5. Open source is great.
|
||||
@@ -53,21 +96,25 @@ If you want to, Leon can communicate with you by being **offline to protect your
|
||||
### What is this repository for?
|
||||
|
||||
> This repository contains the following nodes of Leon:
|
||||
>
|
||||
> - The server
|
||||
> - The packages/modules
|
||||
> - Skills
|
||||
> - The web app
|
||||
> - The hotword node
|
||||
> - The TCP server (for inter-process communication between Leon and third-party nodes such as spaCy)
|
||||
> - The Python bridge (the connector between the core and skills made with Python)
|
||||
|
||||
### What is Leon able to do?
|
||||
|
||||
> Today, the most interesting part is about his core and the way he can scale up. He is pretty young but can easily scale to have new features (packages/modules).
|
||||
> You can find what he is able to do by browsing the [packages list](https://github.com/leon-ai/leon/tree/develop/packages).
|
||||
> Today, the most interesting part is about his core and the way he can scale up. He is pretty young but can easily scale to have new features (skills).
|
||||
> You can find what he is able to do by browsing the [skills list](https://github.com/leon-ai/leon/tree/develop/skills).<br>
|
||||
> Please do know that after the official release, we will build many skills along with the community. Feel free to [join us on Discord](https://discord.gg/MNQqqKg) to be part of the journey.
|
||||
|
||||
Sounds good for you? Then let's get started!
|
||||
Sounds good to you? Then let's get started!
|
||||
|
||||
## ☁️ Try with a Single-Click
|
||||
|
||||
Gitpod will automatically setup an environment and run an instance for you.
|
||||
Gitpod will automatically set up an environment and run an instance for you.
|
||||
|
||||
[](https://gitpod.io/#https://github.com/leon-ai/leon)
|
||||
|
||||
@@ -75,10 +122,8 @@ Gitpod will automatically setup an environment and run an instance for you.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- [Node.js](https://nodejs.org/) >= 14
|
||||
- [npm](https://npmjs.com/) >= 5
|
||||
- [Python](https://www.python.org/downloads/) >= 3
|
||||
- [Pipenv](https://docs.pipenv.org) >= 2020.11.15
|
||||
- [Node.js](https://nodejs.org/) >= 16
|
||||
- [npm](https://npmjs.com/) >= 8
|
||||
- Supported OSes: Linux, macOS and Windows
|
||||
|
||||
To install these prerequisites, you can follow the [How To section](https://docs.getleon.ai/how-to/) of the documentation.
|
||||
@@ -86,28 +131,22 @@ To install these prerequisites, you can follow the [How To section](https://docs
|
||||
### Installation
|
||||
|
||||
```sh
|
||||
# Clone the repository (stable branch)
|
||||
git clone -b master https://github.com/leon-ai/leon.git leon
|
||||
# OR download the latest release at: https://github.com/leon-ai/leon/releases/latest
|
||||
# Install the Leon CLI
|
||||
npm install --global @leon-ai/cli
|
||||
|
||||
# Go to the project root
|
||||
cd leon
|
||||
|
||||
# Install
|
||||
npm install
|
||||
# Install Leon (stable branch)
|
||||
leon create birth
|
||||
# OR install from the develop branch: leon create birth --develop
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```sh
|
||||
# Check the setup went well
|
||||
npm run check
|
||||
|
||||
# Build
|
||||
npm run build
|
||||
leon check
|
||||
|
||||
# Run
|
||||
npm start
|
||||
leon start
|
||||
|
||||
# Go to http://localhost:1337
|
||||
# Hooray! Leon is running
|
||||
@@ -116,11 +155,11 @@ npm start
|
||||
### Docker Installation
|
||||
|
||||
```sh
|
||||
# Build
|
||||
npm run docker:build
|
||||
# Install Leon
|
||||
leon create birth --docker
|
||||
|
||||
# Run
|
||||
npm run docker:run
|
||||
leon start
|
||||
|
||||
# Go to http://localhost:1337
|
||||
# Hooray! Leon is running
|
||||
@@ -130,15 +169,19 @@ npm run docker:run
|
||||
|
||||
For full documentation, visit [docs.getleon.ai](https://docs.getleon.ai).
|
||||
|
||||
## 📺 Video
|
||||
|
||||
[Watch a demo](https://www.youtube.com/watch?v=p7GRGiicO1c).
|
||||
|
||||
## 🧭 Roadmap
|
||||
|
||||
To know what is going on, follow [roadmap.getleon.ai](https://roadmap.getleon.ai).
|
||||
To know what is going on, follow [roadmap.getleon.ai](http://roadmap.getleon.ai).
|
||||
|
||||
## ❤️ Contributing
|
||||
|
||||
If you have an idea for improving Leon, do not hesitate.
|
||||
|
||||
**Leon needs open source to live**, the more modules he has, the more skillful he becomes.
|
||||
**Leon needs open source to live**, the more skills he has, the more skillful he becomes.
|
||||
|
||||
## 📖 The Story Behind Leon
|
||||
|
||||
@@ -146,24 +189,79 @@ You'll find a write-up on this [blog post](https://blog.getleon.ai/the-story-beh
|
||||
|
||||
## 🔔 Stay Tuned
|
||||
|
||||
- [Newsletter](https://getleon.ai)
|
||||
- [Twitter](https://twitter.com/grenlouis)
|
||||
- [Newsletter](https://newsletter.getleon.ai/subscription/form)
|
||||
- [Blog](https://blog.getleon.ai)
|
||||
- [GitHub issues](https://github.com/leon-ai/leon/issues)
|
||||
- [Twitter](https://twitter.com/louistiti_fr)
|
||||
- [#LeonAI](https://twitter.com/hashtag/LeonAI)
|
||||
- [YouTube](https://www.youtube.com/channel/UCW6mk6j6nQUzFYY97r47emQ)
|
||||
- [#LeonAI](<https://twitter.com/search?f=live&q=%23LeonAI%20(from%3Agrenlouis%20OR%20from%3Alouistiti_fr)&src=typed_query>)
|
||||
|
||||
## 👨 Author
|
||||
|
||||
**Louis Grenard** ([@louistiti_fr](https://twitter.com/louistiti_fr))
|
||||
**Louis Grenard** ([@grenlouis](https://twitter.com/grenlouis))
|
||||
|
||||
## 👍 Donate
|
||||
## 👍 Sponsors
|
||||
|
||||
You can also contribute by [buying me a fruit juice](https://donate.getleon.ai).
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="middle" width="128">
|
||||
<a href="https://github.com/Appwrite">
|
||||
<img src="https://github.com/Appwrite.png?size=128" />
|
||||
Appwrite
|
||||
</a><br>
|
||||
<sub><sup>250 USD / month</sup></sub>
|
||||
</td>
|
||||
<td align="center" valign="middle" width="128">
|
||||
<img src="https://getleon.ai/img/anonymous.svg" width="128" />
|
||||
Anonymous
|
||||
<br>
|
||||
<sub><sup>100 USD / month</sup></sub>
|
||||
</td>
|
||||
<td align="center" valign="middle" width="128">
|
||||
<a href="https://github.com/herbundkraut">
|
||||
<img src="https://github.com/herbundkraut.png?size=128" />
|
||||
herbundkraut
|
||||
</a><br>
|
||||
<sub><sup>10 USD / month</sup></sub>
|
||||
</td>
|
||||
<td align="center" valign="middle" width="128">
|
||||
<a href="http://sponsor.getleon.ai/">
|
||||
You?
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
You can also contribute by [sponsoring Leon](http://sponsor.getleon.ai).
|
||||
|
||||
Please note that I dedicate most of my free time to Leon.
|
||||
|
||||
By sponsoring the project you make the project sustainable and faster to develop features.
|
||||
|
||||
The focus is not only limited to the activity you see on GitHub but also a lot of thinking about the direction of the project. Which is naturally related to the overall design, architecture, vision, learning process and so on...
|
||||
|
||||
### Special Thanks
|
||||
|
||||
<a href="https://vercel.com/?utm_source=leon-ai&utm_campaign=oss">
|
||||
<img src="https://i.imgur.com/S5olXWh.png" alt="Vercel" width="128" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.macstadium.com/">
|
||||
<img src="https://getleon.ai/img/thanks/mac-stadium.svg" alt="MacStadium" width="128" />
|
||||
</a>
|
||||
|
||||
<a href="https://www.aoz.studio">
|
||||
<img src="https://getleon.ai/_next/image?url=%2Fimg%2Fthanks%2Faoz-studio.png&w=384&q=75" alt="AOZ Studio" width="128" />
|
||||
</a>
|
||||
|
||||
## 📝 License
|
||||
|
||||
[MIT License](https://github.com/leon-ai/leon/blob/develop/LICENSE.md)
|
||||
|
||||
Copyright (c) 2019-present, Louis Grenard <louis.grenard@gmail.com>
|
||||
Copyright (c) 2019-present, Louis Grenard <louis@getleon.ai>
|
||||
|
||||
## Cheers!
|
||||

|
||||
|
||||

|
||||
|
||||
+162
-52
@@ -1,18 +1,84 @@
|
||||
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,600,700,800);
|
||||
|
||||
html, body, div, span, applet, object, iframes,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, sub, sup, tt, var,
|
||||
u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
html,
|
||||
body,
|
||||
div,
|
||||
span,
|
||||
applet,
|
||||
object,
|
||||
iframes,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p,
|
||||
blockquote,
|
||||
pre,
|
||||
a,
|
||||
abbr,
|
||||
acronym,
|
||||
address,
|
||||
big,
|
||||
cite,
|
||||
code,
|
||||
del,
|
||||
dfn,
|
||||
em,
|
||||
img,
|
||||
ins,
|
||||
kbd,
|
||||
q,
|
||||
s,
|
||||
samp,
|
||||
small,
|
||||
strike,
|
||||
sub,
|
||||
sup,
|
||||
tt,
|
||||
var,
|
||||
u,
|
||||
i,
|
||||
center,
|
||||
dl,
|
||||
dt,
|
||||
dd,
|
||||
ol,
|
||||
ul,
|
||||
li,
|
||||
fieldset,
|
||||
form,
|
||||
label,
|
||||
legend,
|
||||
table,
|
||||
caption,
|
||||
tbody,
|
||||
tfoot,
|
||||
thead,
|
||||
tr,
|
||||
th,
|
||||
td,
|
||||
article,
|
||||
aside,
|
||||
canvas,
|
||||
details,
|
||||
embed,
|
||||
figure,
|
||||
figcaption,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
output,
|
||||
ruby,
|
||||
section,
|
||||
summary,
|
||||
time,
|
||||
mark,
|
||||
audio,
|
||||
video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
@@ -21,17 +87,29 @@ time, mark, audio, video {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
blockquote, q {
|
||||
blockquote,
|
||||
q {
|
||||
quotes: none;
|
||||
}
|
||||
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
blockquote:before,
|
||||
blockquote:after,
|
||||
q:before,
|
||||
q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
@@ -46,6 +124,13 @@ table {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
:root {
|
||||
--black-color: #000;
|
||||
--light-black-color: #222426;
|
||||
--white-color: #fff;
|
||||
--grey-color: #323739;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
@@ -55,13 +140,13 @@ ul li {
|
||||
}
|
||||
|
||||
body {
|
||||
color: #FFF;
|
||||
background-color: #151718;
|
||||
color: var(--white-color);
|
||||
background-color: var(--black-color);
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
font-weight: 400;
|
||||
}
|
||||
body > * {
|
||||
transition: opacity .5s;
|
||||
transition: opacity 0.5s;
|
||||
}
|
||||
body.settingup > * {
|
||||
opacity: 0;
|
||||
@@ -76,14 +161,14 @@ body.settingup::after {
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 50%;
|
||||
animation: scaleout .6s infinite ease-in-out;
|
||||
animation: scaleout 0.6s infinite ease-in-out;
|
||||
}
|
||||
@keyframes scaleout {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1.0);
|
||||
transform: scale(1);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@@ -107,10 +192,10 @@ footer {
|
||||
|
||||
input {
|
||||
text-align: center;
|
||||
color: #FFF;
|
||||
color: var(--white-color);
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-bottom: 2px solid #FFF;
|
||||
border-bottom: 2px solid var(--grey-color);
|
||||
background: none;
|
||||
font-weight: 400;
|
||||
font-size: 4em;
|
||||
@@ -118,8 +203,8 @@ input {
|
||||
}
|
||||
|
||||
small {
|
||||
color: #FFF;
|
||||
font-size: .7em;
|
||||
color: var(--white-color);
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
.hide {
|
||||
@@ -139,14 +224,14 @@ small {
|
||||
top: 10%;
|
||||
height: 50%;
|
||||
overflow-y: auto;
|
||||
border: 2px solid #FFF;
|
||||
border: 2px solid var(--grey-color);
|
||||
border-radius: 12px;
|
||||
}
|
||||
#feed::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
#feed::-webkit-scrollbar-thumb {
|
||||
background-color: rgba(255, 255, 255, .2);
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
@@ -161,7 +246,7 @@ small {
|
||||
padding: 0 8px;
|
||||
opacity: 0;
|
||||
margin-top: 20px;
|
||||
transition: opacity .3s;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
#is-typing.on {
|
||||
opacity: 1;
|
||||
@@ -172,20 +257,20 @@ small {
|
||||
border-radius: 50%;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: #FFF;
|
||||
background-color: var(--white-color);
|
||||
transform: scale(1);
|
||||
}
|
||||
#is-typing .circle:nth-child(1) {
|
||||
animation: typing .2s linear infinite alternate;
|
||||
background-color: #0071F0;
|
||||
animation: typing 0.2s linear infinite alternate;
|
||||
background-color: #0071f0;
|
||||
}
|
||||
#is-typing .circle:nth-child(2) {
|
||||
animation: typing .2s .2s linear infinite alternate;
|
||||
background-color: #FFF;
|
||||
animation: typing 0.2s 0.2s linear infinite alternate;
|
||||
background-color: var(--white-color);
|
||||
}
|
||||
#is-typing .circle:nth-child(3) {
|
||||
animation: typing .2s linear infinite alternate;
|
||||
background-color: #EC297A;
|
||||
animation: typing 0.2s linear infinite alternate;
|
||||
background-color: #ec297a;
|
||||
}
|
||||
@keyframes typing {
|
||||
100% {
|
||||
@@ -211,16 +296,16 @@ small {
|
||||
word-break: break-word;
|
||||
text-align: left;
|
||||
opacity: 0;
|
||||
animation: fadeIn .2s ease-in forwards;
|
||||
animation: fadeIn 0.2s ease-in forwards;
|
||||
}
|
||||
#feed .me .bubble {
|
||||
background-color: #1C75DB;
|
||||
color: #FFF;
|
||||
background-color: #1c75db;
|
||||
color: var(--white-color);
|
||||
right: 0;
|
||||
}
|
||||
#feed .leon .bubble {
|
||||
background-color: #EEE;
|
||||
color: #151718;
|
||||
background-color: var(--light-black-color);
|
||||
color: var(--white-color);
|
||||
}
|
||||
@keyframes fadeIn {
|
||||
100% {
|
||||
@@ -228,10 +313,35 @@ small {
|
||||
}
|
||||
}
|
||||
|
||||
#suggestions-container {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
width: 100%;
|
||||
bottom: 36%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
column-gap: 8px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
.suggestion {
|
||||
border: 1px solid var(--white-color);
|
||||
background-color: transparent;
|
||||
color: var(--white-color);
|
||||
border-radius: 8px;
|
||||
padding: 2px 8px;
|
||||
font-size: inherit;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s, color 0.2s;
|
||||
}
|
||||
.suggestion:hover {
|
||||
color: var(--black-color);
|
||||
background-color: var(--white-color);
|
||||
}
|
||||
|
||||
#input-container {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
bottom: 25%;
|
||||
bottom: 22%;
|
||||
}
|
||||
|
||||
#mic-container {
|
||||
@@ -244,7 +354,7 @@ small {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
button {
|
||||
#mic-button {
|
||||
position: absolute;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
@@ -254,22 +364,22 @@ button {
|
||||
background-color: #888;
|
||||
-webkit-mask-image: url(../img/mic.svg);
|
||||
mask-image: url(../img/mic.svg);
|
||||
transition: background-color .2s;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
button:not(.enabled) {
|
||||
#mic-button:not(.enabled) {
|
||||
margin-left: -26px;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #FFF;
|
||||
#mic-button:hover {
|
||||
background-color: var(--white-color);
|
||||
}
|
||||
button.enabled {
|
||||
background-color: #00E676;
|
||||
#mic-button.enabled {
|
||||
background-color: #00e676;
|
||||
}
|
||||
button.enabled + #sonar {
|
||||
#mic-button.enabled + #sonar {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
border-radius: 50%;
|
||||
opacity: .3;
|
||||
opacity: 0.3;
|
||||
background-color: #575757;
|
||||
pointer-events: none;
|
||||
animation: sonar 1.3s linear infinite;
|
||||
|
||||
+48
-45
@@ -1,49 +1,52 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="/css/style.css" />
|
||||
<link rel="icon" type="image/png" href="/img/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Leon</title>
|
||||
</head>
|
||||
<body class="settingup">
|
||||
<main>
|
||||
<div id="feed">
|
||||
<p id="no-bubble" class="hide">
|
||||
You can start to interact with Leon, don't be shy.
|
||||
</p>
|
||||
</div>
|
||||
<div id="is-typing">
|
||||
<div class="circle"></div>
|
||||
<div class="circle"></div>
|
||||
<div class="circle"></div>
|
||||
</div>
|
||||
<div id="input-container">
|
||||
<div id="mic-container">
|
||||
<button></button>
|
||||
<div id="sonar"></div>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="/css/style.css" />
|
||||
<link rel="icon" type="image/png" href="/img/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Leon</title>
|
||||
</head>
|
||||
<body class="settingup">
|
||||
<main>
|
||||
<div id="feed">
|
||||
<p id="no-bubble" class="hide">
|
||||
You can start to interact with Leon, don't be shy.
|
||||
</p>
|
||||
</div>
|
||||
<label for="query"></label>
|
||||
<input type="text" id="query" autocomplete="off" autofocus>
|
||||
<small>
|
||||
Use <kbd>↑</kbd> <kbd>↓</kbd> to browse history;
|
||||
<kbd>↵</kbd> to submit;
|
||||
<kbd>alt + t to listen.</kbd>
|
||||
</small>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
<div id="logo"></div>
|
||||
<div id="version">
|
||||
<small>v</small>
|
||||
</div>
|
||||
<div id="logger">
|
||||
<small class="italic">
|
||||
<a href="https://docs.getleon.ai/collaborative-logger.html" target="_blank">Collaborative logger</a>
|
||||
</small>
|
||||
</div>
|
||||
</footer>
|
||||
<script type="module" src="/js/main.js"></script>
|
||||
</body>
|
||||
<div id="suggestions-container"></div>
|
||||
<div id="is-typing">
|
||||
<div class="circle"></div>
|
||||
<div class="circle"></div>
|
||||
<div class="circle"></div>
|
||||
</div>
|
||||
<div id="input-container">
|
||||
<div id="mic-container">
|
||||
<button id="mic-button"></button>
|
||||
<div id="sonar"></div>
|
||||
</div>
|
||||
<label for="utterance"></label>
|
||||
<input type="text" id="utterance" autocomplete="off" autofocus />
|
||||
<small>
|
||||
Use <kbd>↑</kbd> <kbd>↓</kbd> to browse history; <kbd>↵</kbd> to
|
||||
submit;
|
||||
<kbd>alt + c to listen.</kbd>
|
||||
</small>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
<div id="logo"></div>
|
||||
<div id="version">
|
||||
<small>v</small>
|
||||
</div>
|
||||
<div id="discord">
|
||||
<small class="italic">
|
||||
<a href="https://discord.gg/MNQqqKg" target="_blank"
|
||||
>Join us on Discord</a
|
||||
>
|
||||
</small>
|
||||
</div>
|
||||
</footer>
|
||||
<script type="module" src="/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+12
-12
@@ -1,5 +1,5 @@
|
||||
export default class Chatbot {
|
||||
constructor () {
|
||||
constructor() {
|
||||
this.et = new EventTarget()
|
||||
this.feed = document.querySelector('#feed')
|
||||
this.typing = document.querySelector('#is-typing')
|
||||
@@ -8,7 +8,7 @@ export default class Chatbot {
|
||||
this.parsedBubbles = JSON.parse(this.bubbles)
|
||||
}
|
||||
|
||||
async init () {
|
||||
async init() {
|
||||
await this.loadFeed()
|
||||
this.scrollDown()
|
||||
|
||||
@@ -21,19 +21,19 @@ export default class Chatbot {
|
||||
})
|
||||
}
|
||||
|
||||
sendTo (who, string) {
|
||||
sendTo(who, string) {
|
||||
if (who === 'leon') {
|
||||
this.et.dispatchEvent(new CustomEvent('to-leon', { detail: string }))
|
||||
}
|
||||
}
|
||||
|
||||
receivedFrom (who, string) {
|
||||
receivedFrom(who, string) {
|
||||
if (who === 'leon') {
|
||||
this.et.dispatchEvent(new CustomEvent('me-received', { detail: string }))
|
||||
}
|
||||
}
|
||||
|
||||
isTyping (who, value) {
|
||||
isTyping(who, value) {
|
||||
if (who === 'leon') {
|
||||
if (value) {
|
||||
this.enableTyping()
|
||||
@@ -43,23 +43,23 @@ export default class Chatbot {
|
||||
}
|
||||
}
|
||||
|
||||
enableTyping () {
|
||||
enableTyping() {
|
||||
if (!this.typing.classList.contains('on')) {
|
||||
this.typing.classList.add('on')
|
||||
}
|
||||
}
|
||||
|
||||
disableTyping () {
|
||||
disableTyping() {
|
||||
if (this.typing.classList.contains('on')) {
|
||||
this.typing.classList.remove('on')
|
||||
}
|
||||
}
|
||||
|
||||
scrollDown () {
|
||||
scrollDown() {
|
||||
this.feed.scrollTo(0, this.feed.scrollHeight)
|
||||
}
|
||||
|
||||
loadFeed () {
|
||||
loadFeed() {
|
||||
return new Promise((resolve) => {
|
||||
if (this.parsedBubbles === null || this.parsedBubbles.length === 0) {
|
||||
this.noBubbleMessage.classList.remove('hide')
|
||||
@@ -72,7 +72,7 @@ export default class Chatbot {
|
||||
|
||||
this.createBubble(bubble.who, bubble.string, false)
|
||||
|
||||
if ((i + 1) === this.parsedBubbles.length) {
|
||||
if (i + 1 === this.parsedBubbles.length) {
|
||||
setTimeout(() => {
|
||||
resolve()
|
||||
}, 100)
|
||||
@@ -82,7 +82,7 @@ export default class Chatbot {
|
||||
})
|
||||
}
|
||||
|
||||
createBubble (who, string, save = true) {
|
||||
createBubble(who, string, save = true) {
|
||||
const container = document.createElement('div')
|
||||
const bubble = document.createElement('p')
|
||||
|
||||
@@ -97,7 +97,7 @@ export default class Chatbot {
|
||||
}
|
||||
}
|
||||
|
||||
saveBubble (who, string) {
|
||||
saveBubble(who, string) {
|
||||
if (!this.noBubbleMessage.classList.contains('hide')) {
|
||||
this.noBubbleMessage.classList.add('hide')
|
||||
}
|
||||
|
||||
+50
-12
@@ -1,51 +1,64 @@
|
||||
import { io } from 'socket.io-client'
|
||||
|
||||
import Chatbot from './chatbot'
|
||||
|
||||
export default class Client {
|
||||
constructor (client, serverUrl, input, res) {
|
||||
constructor(client, serverUrl, input, res) {
|
||||
this.client = client
|
||||
this._input = input
|
||||
this._suggestionContainer = document.querySelector('#suggestions-container')
|
||||
this.serverUrl = serverUrl
|
||||
this.socket = io(this.serverUrl)
|
||||
this.history = localStorage.getItem('history')
|
||||
this.parsedHistory = []
|
||||
this.info = res
|
||||
this.chatbot = new Chatbot()
|
||||
this._recorder = { }
|
||||
this._recorder = {}
|
||||
this._suggestions = []
|
||||
}
|
||||
|
||||
set input (newInput) {
|
||||
set input(newInput) {
|
||||
if (typeof newInput !== 'undefined') {
|
||||
this._input.value = newInput
|
||||
}
|
||||
}
|
||||
|
||||
set recorder (recorder) {
|
||||
set recorder(recorder) {
|
||||
this._recorder = recorder
|
||||
}
|
||||
|
||||
get recorder () {
|
||||
get recorder() {
|
||||
return this._recorder
|
||||
}
|
||||
|
||||
init () {
|
||||
init(loader) {
|
||||
this.chatbot.init()
|
||||
|
||||
this.socket.on('connect', () => {
|
||||
this.socket.emit('init', this.client)
|
||||
})
|
||||
|
||||
this.socket.on('ready', () => {
|
||||
loader.stop()
|
||||
})
|
||||
|
||||
this.socket.on('answer', (data) => {
|
||||
this.chatbot.receivedFrom('leon', data)
|
||||
})
|
||||
|
||||
this.socket.on('suggest', (data) => {
|
||||
data?.forEach((suggestionText) => {
|
||||
this.addSuggestion(suggestionText)
|
||||
})
|
||||
})
|
||||
|
||||
this.socket.on('is-typing', (data) => {
|
||||
this.chatbot.isTyping('leon', data)
|
||||
})
|
||||
|
||||
this.socket.on('recognized', (data, cb) => {
|
||||
this._input.value = data
|
||||
this.send('query')
|
||||
this.send('utterance')
|
||||
|
||||
cb('string-received')
|
||||
})
|
||||
@@ -87,7 +100,7 @@ export default class Client {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 1000)
|
||||
}, 1_000)
|
||||
}, data.duration + 500)
|
||||
}
|
||||
})
|
||||
@@ -96,7 +109,7 @@ export default class Client {
|
||||
})
|
||||
|
||||
this.socket.on('download', (data) => {
|
||||
window.location = `${this.serverUrl}/v1/downloads?package=${data.package}&module=${data.module}`
|
||||
window.location = `${this.serverUrl}/api/v1/downloads?domain=${data.domain}&skill=${data.skill}`
|
||||
})
|
||||
|
||||
if (this.history !== null) {
|
||||
@@ -104,11 +117,20 @@ export default class Client {
|
||||
}
|
||||
}
|
||||
|
||||
send (keyword) {
|
||||
send(keyword) {
|
||||
if (this._input.value !== '') {
|
||||
this.socket.emit(keyword, { client: this.client, value: this._input.value.trim() })
|
||||
this.socket.emit(keyword, {
|
||||
client: this.client,
|
||||
value: this._input.value.trim()
|
||||
})
|
||||
this.chatbot.sendTo('leon', this._input.value)
|
||||
|
||||
this._suggestions.forEach((suggestion) => {
|
||||
// Remove all event listeners of the suggestion
|
||||
suggestion.replaceWith(suggestion.cloneNode(true))
|
||||
this._suggestionContainer.replaceChildren()
|
||||
})
|
||||
|
||||
this.save()
|
||||
|
||||
return true
|
||||
@@ -117,7 +139,7 @@ export default class Client {
|
||||
return false
|
||||
}
|
||||
|
||||
save () {
|
||||
save() {
|
||||
let val = this._input.value
|
||||
|
||||
if (localStorage.getItem('history') === null) {
|
||||
@@ -138,4 +160,20 @@ export default class Client {
|
||||
|
||||
this._input.value = ''
|
||||
}
|
||||
|
||||
addSuggestion(text) {
|
||||
const newSuggestion = document.createElement('button')
|
||||
newSuggestion.classList.add('suggestion')
|
||||
newSuggestion.textContent = text
|
||||
|
||||
this._suggestionContainer.appendChild(newSuggestion)
|
||||
|
||||
newSuggestion.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
this.input = e.target.textContent
|
||||
this.send('utterance')
|
||||
})
|
||||
|
||||
this._suggestions.push(newSuggestion)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
const listener = { }
|
||||
const listener = {}
|
||||
|
||||
listener.listening = (stream, minDecibels, maxBlankTime,
|
||||
cbOnStart, cbOnEnd) => {
|
||||
listener.listening = (
|
||||
stream,
|
||||
minDecibels,
|
||||
maxBlankTime,
|
||||
cbOnStart,
|
||||
cbOnEnd
|
||||
) => {
|
||||
const ctx = new AudioContext()
|
||||
const analyser = ctx.createAnalyser()
|
||||
const streamNode = ctx.createMediaStreamSource(stream)
|
||||
@@ -26,7 +31,7 @@ listener.listening = (stream, minDecibels, maxBlankTime,
|
||||
silenceStart = time
|
||||
}
|
||||
|
||||
if (!triggered && (time - silenceStart) > maxBlankTime) {
|
||||
if (!triggered && time - silenceStart > maxBlankTime) {
|
||||
cbOnEnd()
|
||||
|
||||
triggered = true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export default class Loader {
|
||||
constructor () {
|
||||
constructor() {
|
||||
this.et = new EventTarget()
|
||||
this.body = document.querySelector('body')
|
||||
|
||||
@@ -12,11 +12,11 @@ export default class Loader {
|
||||
})
|
||||
}
|
||||
|
||||
start () {
|
||||
start() {
|
||||
this.et.dispatchEvent(new CustomEvent('settingup', { detail: true }))
|
||||
}
|
||||
|
||||
stop () {
|
||||
stop() {
|
||||
this.et.dispatchEvent(new CustomEvent('settingup', { detail: false }))
|
||||
}
|
||||
}
|
||||
|
||||
+97
-85
@@ -1,4 +1,4 @@
|
||||
import request from 'superagent'
|
||||
import axios from 'axios'
|
||||
|
||||
import Loader from './loader'
|
||||
import Client from './client'
|
||||
@@ -11,64 +11,67 @@ const config = {
|
||||
server_host: import.meta.env.VITE_LEON_HOST,
|
||||
server_port: import.meta.env.VITE_LEON_PORT,
|
||||
min_decibels: -40, // Noise detection sensitivity
|
||||
max_blank_time: 1000 // Maximum time to consider a blank (ms)
|
||||
max_blank_time: 1_000 // Maximum time to consider a blank (ms)
|
||||
}
|
||||
const serverUrl = import.meta.env.VITE_LEON_NODE_ENV === 'production' ? '' : `${config.server_host}:${config.server_port}`
|
||||
const serverUrl =
|
||||
import.meta.env.VITE_LEON_NODE_ENV === 'production'
|
||||
? ''
|
||||
: `${config.server_host}:${config.server_port}`
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const loader = new Loader()
|
||||
|
||||
loader.start()
|
||||
|
||||
request.get(`${serverUrl}/v1/info`)
|
||||
.end((err, res) => {
|
||||
if (err || !res.ok) {
|
||||
console.error(err.response.error.message)
|
||||
} else {
|
||||
const input = document.querySelector('#query')
|
||||
const mic = document.querySelector('button')
|
||||
const v = document.querySelector('#version small')
|
||||
const logger = document.querySelector('#logger small')
|
||||
const client = new Client(config.app, serverUrl, input, res.body)
|
||||
let rec = { }
|
||||
let chunks = []
|
||||
let sLogger = ' enabled, thank you.'
|
||||
try {
|
||||
const response = await axios.get(`${serverUrl}/api/v1/info`)
|
||||
const input = document.querySelector('#utterance')
|
||||
const mic = document.querySelector('#mic-button')
|
||||
const v = document.querySelector('#version small')
|
||||
const client = new Client(config.app, serverUrl, input, response.data)
|
||||
let rec = {}
|
||||
let chunks = []
|
||||
|
||||
v.innerHTML += client.info.version
|
||||
if (client.info.logger === false) {
|
||||
sLogger = ' disabled.'
|
||||
}
|
||||
logger.innerHTML += sLogger
|
||||
v.innerHTML += client.info.version
|
||||
|
||||
client.init()
|
||||
client.init(loader)
|
||||
|
||||
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
|
||||
navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
|
||||
if (MediaRecorder) {
|
||||
rec = new Recorder(stream, mic, client.info)
|
||||
client.recorder = rec
|
||||
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
|
||||
navigator.mediaDevices
|
||||
.getUserMedia({ audio: true })
|
||||
.then((stream) => {
|
||||
if (MediaRecorder) {
|
||||
rec = new Recorder(stream, mic, client.info)
|
||||
client.recorder = rec
|
||||
|
||||
rec.ondataavailable((e) => {
|
||||
chunks.push(e.data)
|
||||
})
|
||||
rec.ondataavailable((e) => {
|
||||
chunks.push(e.data)
|
||||
})
|
||||
|
||||
rec.onstart(() => { /* */ })
|
||||
rec.onstart(() => {
|
||||
/* */
|
||||
})
|
||||
|
||||
rec.onstop(() => {
|
||||
const blob = new Blob(chunks)
|
||||
chunks = []
|
||||
rec.enabled = false
|
||||
rec.onstop(() => {
|
||||
const blob = new Blob(chunks)
|
||||
chunks = []
|
||||
rec.enabled = false
|
||||
|
||||
// Ensure there are some data
|
||||
if (blob.size >= 1000) {
|
||||
client.socket.emit('recognize', blob)
|
||||
}
|
||||
})
|
||||
// Ensure there are some data
|
||||
if (blob.size >= 1_000) {
|
||||
client.socket.emit('recognize', blob)
|
||||
}
|
||||
})
|
||||
|
||||
listener.listening(stream, config.min_decibels, config.max_blank_time, () => {
|
||||
listener.listening(
|
||||
stream,
|
||||
config.min_decibels,
|
||||
config.max_blank_time,
|
||||
() => {
|
||||
// Noise detected
|
||||
rec.noiseDetected = true
|
||||
}, () => {
|
||||
},
|
||||
() => {
|
||||
// Noise ended
|
||||
|
||||
rec.noiseDetected = false
|
||||
@@ -78,54 +81,63 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
rec.hotwordTriggered = false
|
||||
rec.countSilenceAfterTalk = 0
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
client.socket.on('enable-record', () => {
|
||||
rec.hotwordTriggered = true
|
||||
rec.start()
|
||||
setTimeout(() => { rec.hotwordTriggered = false }, config.max_blank_time)
|
||||
rec.enabled = true
|
||||
})
|
||||
} else {
|
||||
console.error('MediaRecorder is not supported on your browser.')
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('MediaDevices.getUserMedia() threw the following error:', err)
|
||||
})
|
||||
} else {
|
||||
console.error('MediaDevices.getUserMedia() is not supported on your browser.')
|
||||
}
|
||||
|
||||
loader.stop()
|
||||
|
||||
document.addEventListener('keydown', (e) => {
|
||||
onkeydowndocument(e, () => {
|
||||
if (rec.enabled === false) {
|
||||
input.value = ''
|
||||
client.socket.on('enable-record', () => {
|
||||
rec.hotwordTriggered = true
|
||||
rec.start()
|
||||
setTimeout(() => {
|
||||
rec.hotwordTriggered = false
|
||||
}, config.max_blank_time)
|
||||
rec.enabled = true
|
||||
} else {
|
||||
rec.stop()
|
||||
rec.enabled = false
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
input.addEventListener('keydown', (e) => {
|
||||
onkeydowninput(e, client)
|
||||
})
|
||||
|
||||
mic.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
|
||||
if (rec.enabled === false) {
|
||||
rec.start()
|
||||
rec.enabled = true
|
||||
})
|
||||
} else {
|
||||
rec.stop()
|
||||
rec.enabled = false
|
||||
console.error('MediaRecorder is not supported on your browser.')
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(
|
||||
'MediaDevices.getUserMedia() threw the following error:',
|
||||
err
|
||||
)
|
||||
})
|
||||
} else {
|
||||
console.error(
|
||||
'MediaDevices.getUserMedia() is not supported on your browser.'
|
||||
)
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', (e) => {
|
||||
onkeydowndocument(e, () => {
|
||||
if (rec.enabled === false) {
|
||||
input.value = ''
|
||||
rec.start()
|
||||
rec.enabled = true
|
||||
} else {
|
||||
rec.stop()
|
||||
rec.enabled = false
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
input.addEventListener('keydown', (e) => {
|
||||
onkeydowninput(e, client)
|
||||
})
|
||||
|
||||
mic.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
|
||||
if (rec.enabled === false) {
|
||||
rec.start()
|
||||
rec.enabled = true
|
||||
} else {
|
||||
rec.stop()
|
||||
rec.enabled = false
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
alert(`Error: ${e.message}; ${JSON.stringify(e.response?.data)}`)
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -9,18 +9,18 @@ const onkeydowninput = (e, client) => {
|
||||
}
|
||||
|
||||
if (key === 13) {
|
||||
if (client.send('query')) {
|
||||
if (client.send('utterance')) {
|
||||
parsedHistory = JSON.parse(localStorage.getItem('history')).reverse()
|
||||
index = -1
|
||||
}
|
||||
} else if (localStorage.getItem('history') !== null) {
|
||||
if (key === 38 && index < (parsedHistory.length - 1)) {
|
||||
if (key === 38 && index < parsedHistory.length - 1) {
|
||||
index += 1
|
||||
client.input = parsedHistory[index]
|
||||
} else if (key === 40 && (index - 1) >= 0) {
|
||||
} else if (key === 40 && index - 1 >= 0) {
|
||||
index -= 1
|
||||
client.input = parsedHistory[index]
|
||||
} else if (key === 40 && (index - 1) < 0) {
|
||||
} else if (key === 40 && index - 1 < 0) {
|
||||
client.input = ''
|
||||
index = -1
|
||||
}
|
||||
@@ -28,12 +28,9 @@ const onkeydowninput = (e, client) => {
|
||||
}
|
||||
|
||||
const onkeydowndocument = (e, cb) => {
|
||||
if (e.altKey && e.key === 't') {
|
||||
if (e.altKey && e.key === 'c') {
|
||||
cb()
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
onkeydowninput,
|
||||
onkeydowndocument
|
||||
}
|
||||
export { onkeydowninput, onkeydowndocument }
|
||||
|
||||
@@ -2,7 +2,7 @@ import on from '../sounds/on.mp3'
|
||||
import off from '../sounds/off.mp3'
|
||||
|
||||
export default class Recorder {
|
||||
constructor (stream, el, info) {
|
||||
constructor(stream, el, info) {
|
||||
this.recorder = new MediaRecorder(stream, { audioBitsPerSecond: 16000 })
|
||||
this.el = el
|
||||
this.audioOn = new Audio(on)
|
||||
@@ -15,7 +15,7 @@ export default class Recorder {
|
||||
this.countSilenceAfterTalk = 0
|
||||
}
|
||||
|
||||
start (playSound = true) {
|
||||
start(playSound = true) {
|
||||
if (this.info.stt.enabled === false) {
|
||||
console.warn('Speech-to-text disabled')
|
||||
} else {
|
||||
@@ -24,7 +24,7 @@ export default class Recorder {
|
||||
}
|
||||
}
|
||||
|
||||
stop (playSound = true) {
|
||||
stop(playSound = true) {
|
||||
if (this.info.stt.enabled === false) {
|
||||
console.warn('Speech-to-text disabled')
|
||||
} else {
|
||||
@@ -33,7 +33,7 @@ export default class Recorder {
|
||||
}
|
||||
}
|
||||
|
||||
onstart (cb) {
|
||||
onstart(cb) {
|
||||
this.recorder.onstart = (e) => {
|
||||
if (this.playSound) {
|
||||
this.audioOn.play()
|
||||
@@ -44,7 +44,7 @@ export default class Recorder {
|
||||
}
|
||||
}
|
||||
|
||||
onstop (cb) {
|
||||
onstop(cb) {
|
||||
this.recorder.onstop = (e) => {
|
||||
if (this.playSound) {
|
||||
this.audioOff.play()
|
||||
@@ -55,7 +55,7 @@ export default class Recorder {
|
||||
}
|
||||
}
|
||||
|
||||
ondataavailable (cb) {
|
||||
ondataavailable(cb) {
|
||||
this.recorder.ondataavailable = (e) => {
|
||||
cb(e)
|
||||
}
|
||||
|
||||
+10
-2
@@ -1,16 +1,24 @@
|
||||
import dns from 'node:dns'
|
||||
|
||||
import dotenv from 'dotenv'
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
dotenv.config()
|
||||
|
||||
dns.setDefaultResultOrder('verbatim')
|
||||
|
||||
// Map necessary Leon's env vars as Vite only expose VITE_*
|
||||
process.env.VITE_LEON_NODE_ENV = process.env.LEON_NODE_ENV
|
||||
process.env.VITE_LEON_HOST = process.env.LEON_HOST
|
||||
process.env.VITE_LEON_PORT = process.env.LEON_PORT
|
||||
|
||||
export default {
|
||||
export default defineConfig({
|
||||
root: 'app/src',
|
||||
build: {
|
||||
outDir: '../dist',
|
||||
emptyOutDir: true
|
||||
},
|
||||
server: {
|
||||
port: 3000
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
package-lock=false
|
||||
save-exact=true
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "leon-nodejs-bridge",
|
||||
"description": "Leon's Node.js bridge to communicate between the core and skills made with JavaScript",
|
||||
"main": "dist/leon-nodejs-bridge.js",
|
||||
"author": {
|
||||
"name": "Louis Grenard",
|
||||
"email": "louis@getleon.ai",
|
||||
"url": "https://twitter.com/grenlouis"
|
||||
},
|
||||
"license": "MIT",
|
||||
"homepage": "https://getleon.ai",
|
||||
"bugs": {
|
||||
"url": "https://github.com/leon-ai/leon/issues"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { VERSION } from './version'
|
||||
|
||||
console.log('[WIP] Node.js bridge', VERSION)
|
||||
|
||||
// TODO
|
||||
@@ -0,0 +1 @@
|
||||
export const VERSION = '0.0.0'
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"extends": "@tsconfig/node16-strictest/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
},
|
||||
"ignoreDeprecations": "5.0",
|
||||
"allowJs": true,
|
||||
"checkJs": false,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"ts-node": {
|
||||
"swc": true,
|
||||
"require": ["tsconfig-paths/register"],
|
||||
"files": true
|
||||
},
|
||||
"files": [],
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
Generated
-89
@@ -1,89 +0,0 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "9cc61d01e3c8d2f4474122d10ed3da5315095ece51953ce2a6f244828fa9b898"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"beautifulsoup4": {
|
||||
"hashes": [
|
||||
"sha256:034740f6cb549b4e932ae1ab975581e6103ac8f942200a0e9759065984391858",
|
||||
"sha256:945065979fb8529dd2f37dbb58f00b661bdbcbebf954f93b32fdf5263ef35348",
|
||||
"sha256:ba6d5c59906a85ac23dadfe5c88deaf3e179ef565f4898671253e50a78680718"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.7.1"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c",
|
||||
"sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"
|
||||
],
|
||||
"version": "==2020.12.5"
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
|
||||
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
|
||||
],
|
||||
"version": "==3.0.4"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
|
||||
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
|
||||
],
|
||||
"version": "==2.8"
|
||||
},
|
||||
"pytube": {
|
||||
"hashes": [
|
||||
"sha256:2a32f3475f063d25e7b7a7434a93b51d59aadbbda7ed24af48f097b2876c0964",
|
||||
"sha256:9190f5e13b05a4fc1586eedd46f7164c3a4318607d455a1f7c126699ddde724f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==9.5.0"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e",
|
||||
"sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.21.0"
|
||||
},
|
||||
"soupsieve": {
|
||||
"hashes": [
|
||||
"sha256:052774848f448cf19c7e959adf5566904d525f33a3f8b6ba6f6f8f26ec7de0cc",
|
||||
"sha256:c2c1c2d44f158cdbddab7824a9af8c4f83c76b1e23e049479aa432feb6c4c23b"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.2.1"
|
||||
},
|
||||
"tinydb": {
|
||||
"hashes": [
|
||||
"sha256:67b3b302fc86e0139db545d5abd65bf0e1dadaecee63bd1ff3fe2169810d5387",
|
||||
"sha256:e7d939c52710ee4354bb619b9bed05ae6192645f1520f13d8fcf4f06b5590e02"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.9.0"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4",
|
||||
"sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' and python_version < '4'",
|
||||
"version": "==1.24.3"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
import utils
|
||||
from sys import argv, path
|
||||
from json import dumps, loads
|
||||
from importlib import import_module
|
||||
|
||||
def main():
|
||||
"""Dynamically import modules related to the args and print the ouput"""
|
||||
|
||||
path.append('.')
|
||||
|
||||
queryobj = utils.getqueryobj()
|
||||
m = import_module('packages.' + queryobj['package'] + '.' + queryobj['module'])
|
||||
|
||||
return getattr(m, queryobj['action'])(queryobj['query'], queryobj['entities'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -3,10 +3,14 @@ url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
requests = "==2.21.0"
|
||||
pytube = "==9.5.0"
|
||||
tinydb = "==3.9.0"
|
||||
beautifulsoup4 = "==4.7.1"
|
||||
[requires]
|
||||
python_version = "3.9.10"
|
||||
|
||||
[dev-packages]
|
||||
[packages]
|
||||
setuptools = "*"
|
||||
wheel = "*"
|
||||
cx-freeze = "==6.11.1"
|
||||
requests = "==2.28.1"
|
||||
pytube = "==9.5.0"
|
||||
tinydb = "==4.7.0"
|
||||
beautifulsoup4 = "==4.7.1"
|
||||
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
import utils
|
||||
from traceback import print_exc
|
||||
from sys import path
|
||||
from json import dumps, loads
|
||||
from importlib import import_module
|
||||
|
||||
def main():
|
||||
"""Dynamically import skills related to the args and print the output"""
|
||||
|
||||
path.append('.')
|
||||
|
||||
intent_obj = utils.get_intent_obj()
|
||||
|
||||
skill = import_module('skills.' + intent_obj['domain'] + '.' + intent_obj['skill'] + '.src.actions.' + intent_obj['action'])
|
||||
|
||||
params = {
|
||||
'lang': intent_obj['lang'],
|
||||
'utterance': intent_obj['utterance'],
|
||||
'current_entities': intent_obj['current_entities'],
|
||||
'entities': intent_obj['entities'],
|
||||
'current_resolvers': intent_obj['current_resolvers'],
|
||||
'resolvers': intent_obj['resolvers'],
|
||||
'slots': intent_obj['slots']
|
||||
}
|
||||
|
||||
return getattr(skill, intent_obj['action'])(params)
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
raise main()
|
||||
except Exception as e:
|
||||
# Print full traceback error report if skills triggers an error from the call stack
|
||||
if 'exceptions must derive from BaseException' not in str(e):
|
||||
print_exc()
|
||||
@@ -0,0 +1,29 @@
|
||||
from cx_Freeze import setup, Executable
|
||||
import requests.certs
|
||||
|
||||
from version import __version__
|
||||
|
||||
options = {
|
||||
'build_exe': {
|
||||
# Add common dependencies for skills
|
||||
'includes': [
|
||||
'bs4',
|
||||
'pytube'
|
||||
],
|
||||
'include_files': [(requests.certs.where(), 'cacert.pem')]
|
||||
}
|
||||
}
|
||||
|
||||
executables = [
|
||||
Executable(
|
||||
script='bridges/python/src/main.py',
|
||||
target_name='leon-python-bridge'
|
||||
)
|
||||
]
|
||||
|
||||
setup(
|
||||
name='leon-python-bridge',
|
||||
version=__version__,
|
||||
executables=executables,
|
||||
options=options
|
||||
)
|
||||
@@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
from json import loads, dumps
|
||||
from pathlib import Path
|
||||
from random import choice
|
||||
from vars import useragent
|
||||
from tinydb import TinyDB, Query, table, operations
|
||||
from time import sleep
|
||||
import sys
|
||||
import os
|
||||
import requests
|
||||
import re
|
||||
|
||||
dirname = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
intent_object_path = sys.argv[1]
|
||||
codes = []
|
||||
|
||||
intent_obj_file = open(intent_object_path, 'r', encoding = 'utf8')
|
||||
intent_obj = loads(intent_obj_file.read())
|
||||
intent_obj_file.close()
|
||||
|
||||
def get_intent_obj():
|
||||
"""Return intent object"""
|
||||
|
||||
return intent_obj
|
||||
|
||||
def translate(key, dict = { }):
|
||||
"""Pickup the language file according to the cmd arg
|
||||
and return the value according to the params"""
|
||||
|
||||
# "Temporize" for the data buffer ouput on the core
|
||||
sleep(0.1)
|
||||
|
||||
output = ''
|
||||
variables = { }
|
||||
|
||||
file = open(os.path.join(os.getcwd(), 'skills', intent_obj['domain'], intent_obj['skill'], 'config', intent_obj['lang'] + '.json'), 'r', encoding = 'utf8')
|
||||
obj = loads(file.read())
|
||||
file.close()
|
||||
|
||||
# In case the key is a raw answer
|
||||
if key not in obj['answers']:
|
||||
return key
|
||||
|
||||
prop = obj['answers'][key]
|
||||
if 'variables' in obj:
|
||||
variables = obj['variables']
|
||||
if isinstance(prop, list):
|
||||
output = choice(prop)
|
||||
else:
|
||||
output = prop
|
||||
|
||||
if dict:
|
||||
for key in dict:
|
||||
output = output.replace('%' + key + '%', str(dict[key]))
|
||||
|
||||
if variables:
|
||||
for key in variables:
|
||||
output = output.replace('%' + key + '%', str(variables[key]))
|
||||
|
||||
return output
|
||||
|
||||
def output(type, content = '', core = { }):
|
||||
"""Communicate with the core"""
|
||||
|
||||
if isinstance(content, dict):
|
||||
speech = translate(content['key'], content['data'])
|
||||
codes.append(content['key'])
|
||||
else:
|
||||
content = str(content)
|
||||
speech = translate(content)
|
||||
codes.append(content)
|
||||
|
||||
print(dumps({
|
||||
'domain': intent_obj['domain'],
|
||||
'skill': intent_obj['skill'],
|
||||
'action': intent_obj['action'],
|
||||
'lang': intent_obj['lang'],
|
||||
'utterance': intent_obj['utterance'],
|
||||
'entities': intent_obj['entities'],
|
||||
'slots': intent_obj['slots'],
|
||||
'output': {
|
||||
'type': type,
|
||||
'codes': codes,
|
||||
'speech': speech,
|
||||
'core': core,
|
||||
'options': config('options')
|
||||
}
|
||||
}))
|
||||
|
||||
if (type == 'inter'):
|
||||
sys.stdout.flush()
|
||||
|
||||
def http(method, url, headers = None):
|
||||
"""Send HTTP request with the Leon user agent"""
|
||||
|
||||
session = requests.Session()
|
||||
session.headers.update({ 'User-Agent': useragent, 'Cache-Control': 'no-cache' })
|
||||
|
||||
if headers != None:
|
||||
session.headers.update(headers)
|
||||
|
||||
return session.request(method, url)
|
||||
|
||||
def config(key):
|
||||
"""Get a skill configuration value"""
|
||||
|
||||
file = open(os.path.join(os.getcwd(), 'skills', intent_obj['domain'], intent_obj['skill'], 'src/config.json'), 'r', encoding = 'utf8')
|
||||
obj = loads(file.read())
|
||||
file.close()
|
||||
|
||||
return obj['configurations'][key]
|
||||
|
||||
def create_dl_dir():
|
||||
"""Create the downloads folder of a current skill"""
|
||||
|
||||
dl_dir = os.path.join(os.getcwd(), 'downloads')
|
||||
# dl_dir = os.path.dirname(os.path.realpath(__file__)) + '/../../../../downloads/'
|
||||
skill_dl_dir = os.path.join(dl_dir, intent_obj['domain'], intent_obj['skill'])
|
||||
|
||||
Path(skill_dl_dir).mkdir(parents = True, exist_ok = True)
|
||||
|
||||
return skill_dl_dir
|
||||
|
||||
def db(db_type = 'tinydb'):
|
||||
"""Create a new dedicated database
|
||||
for a specific skill"""
|
||||
|
||||
if db_type == 'tinydb':
|
||||
ext = '.json' if os.environ.get('LEON_NODE_ENV') != 'testing' else '.spec.json'
|
||||
db = TinyDB(os.path.join(os.getcwd(), 'skills', intent_obj['domain'], intent_obj['skill'], 'memory/db' + ext))
|
||||
return {
|
||||
'db': db,
|
||||
'query': Query,
|
||||
'table': table,
|
||||
'operations': operations
|
||||
}
|
||||
|
||||
def get_table(slug):
|
||||
"""Get a table from a specific skill"""
|
||||
|
||||
domain, skill, table = slug.split('.')
|
||||
ext = '.json' if os.environ.get('LEON_NODE_ENV') != 'testing' else '.spec.json'
|
||||
db = TinyDB(os.path.join(os.getcwd(), 'skills', domain, skill, 'memory/db' + ext))
|
||||
return db.table(table)
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
from os import path
|
||||
import sys
|
||||
import os
|
||||
from json import loads
|
||||
|
||||
packagejsonfile = open(path.dirname(path.realpath(__file__)) + '/../../package.json', 'r', encoding = 'utf8')
|
||||
packagejsonfile = open(os.path.join(os.getcwd(), 'package.json'), 'r', encoding = 'utf8')
|
||||
packagejson = loads(packagejsonfile.read())
|
||||
packagejsonfile.close()
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
__version__ = '1.0.1'
|
||||
@@ -1,115 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
from json import loads, dumps
|
||||
from os import path, environ
|
||||
from pathlib import Path
|
||||
from random import choice
|
||||
from sys import argv, stdout
|
||||
from vars import useragent
|
||||
from tinydb import TinyDB, Query, operations
|
||||
from time import sleep
|
||||
import sqlite3
|
||||
import requests
|
||||
import re
|
||||
|
||||
dirname = path.dirname(path.realpath(__file__))
|
||||
|
||||
queryobjectpath = argv[1]
|
||||
codes = []
|
||||
|
||||
queryobjfile = open(queryobjectpath, 'r', encoding = 'utf8')
|
||||
queryobj = loads(queryobjfile.read())
|
||||
queryobjfile.close()
|
||||
|
||||
def getqueryobj():
|
||||
"""Return query object"""
|
||||
|
||||
return queryobj
|
||||
|
||||
def translate(key, d = { }):
|
||||
"""Pickup the language file according to the cmd arg
|
||||
and return the value regarding to the params"""
|
||||
|
||||
output = ''
|
||||
|
||||
file = open(dirname + '/../../packages/' + queryobj['package'] + '/' + 'data/answers/' + queryobj['lang'] + '.json', 'r', encoding = 'utf8')
|
||||
obj = loads(file.read())
|
||||
file.close()
|
||||
|
||||
prop = obj[queryobj['module']][key]
|
||||
if isinstance(prop, list):
|
||||
output = choice(prop)
|
||||
else:
|
||||
output = prop
|
||||
|
||||
if d:
|
||||
for k in d:
|
||||
output = output.replace('%' + k + '%', str(d[k]))
|
||||
|
||||
# "Temporize" for the data buffer ouput on the core
|
||||
sleep(0.1)
|
||||
|
||||
return output
|
||||
|
||||
def output(type, code, speech = ''):
|
||||
"""Communicate with the Core"""
|
||||
|
||||
codes.append(code)
|
||||
|
||||
print(dumps({
|
||||
'package': queryobj['package'],
|
||||
'module': queryobj['module'],
|
||||
'action': queryobj['action'],
|
||||
'lang': queryobj['lang'],
|
||||
'input': queryobj['query'],
|
||||
'entities': queryobj['entities'],
|
||||
'output': {
|
||||
'type': type,
|
||||
'codes': codes,
|
||||
'speech': speech,
|
||||
'options': config('options')
|
||||
}
|
||||
}))
|
||||
|
||||
if (type == 'inter'):
|
||||
stdout.flush()
|
||||
|
||||
def http(method, url, headers = None):
|
||||
"""Send HTTP request with the Leon user agent"""
|
||||
|
||||
session = requests.Session()
|
||||
session.headers.update({ 'User-Agent': useragent, 'Cache-Control': 'no-cache' })
|
||||
|
||||
if headers != None:
|
||||
session.headers.update(headers)
|
||||
|
||||
return session.request(method, url)
|
||||
|
||||
def config(key):
|
||||
"""Get a package configuration value"""
|
||||
|
||||
file = open(dirname + '/../../packages/' + queryobj['package'] + '/config/config.json', 'r', encoding = 'utf8')
|
||||
obj = loads(file.read())
|
||||
file.close()
|
||||
|
||||
return obj[queryobj['module']][key]
|
||||
|
||||
def createdldir():
|
||||
"""Create the downloads folder of a current module"""
|
||||
|
||||
dldir = path.dirname(path.realpath(__file__)) + '/../../downloads/'
|
||||
moduledldir = dldir + queryobj['package'] + '/' + queryobj['module']
|
||||
|
||||
Path(moduledldir).mkdir(parents = True, exist_ok = True)
|
||||
|
||||
return moduledldir
|
||||
|
||||
def db(dbtype = 'tinydb'):
|
||||
"""Create a new dedicated database
|
||||
for a specific package"""
|
||||
|
||||
if dbtype == 'tinydb':
|
||||
ext = '.json' if environ.get('LEON_NODE_ENV') != 'testing' else '.spec.json'
|
||||
db = TinyDB(dirname + '/../../packages/' + queryobj['package'] + '/data/db/' + queryobj['package'] + ext)
|
||||
return { 'db': db, 'query': Query, 'operations': operations }
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"$schema": "../../../schemas/voice-config-schemas/amazon.json",
|
||||
"credentials": {
|
||||
"accessKeyId": "",
|
||||
"secretAccessKey": ""
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"$schema": "../../../schemas/voice-config-schemas/google-cloud.json",
|
||||
"type": "service_account",
|
||||
"project_id": "",
|
||||
"private_key_id": "",
|
||||
"private_key": "",
|
||||
"client_email": "example@iam.gserviceaccount.com",
|
||||
"client_id": "",
|
||||
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||
"token_uri": "https://accounts.google.com/o/oauth2/token",
|
||||
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"$schema": "../../../schemas/voice-config-schemas/watson-stt.json",
|
||||
"apikey": "",
|
||||
"url": "https://stream.watsonplatform.net/speech-to-text/api"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"$schema": "../../../schemas/voice-config-schemas/watson-tts.json",
|
||||
"apikey": "",
|
||||
"url": "https://stream.watsonplatform.net/text-to-speech/api"
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"$schema": "../../../schemas/global-data/global-answers.json",
|
||||
"answers": {
|
||||
"success": {},
|
||||
"errors": {
|
||||
"not_found": "Sorry, it seems I cannot find that"
|
||||
},
|
||||
"synchronizer": {
|
||||
"syncing_direct": "I will now synchronize the downloaded content on your current device. Don't worry, I will let you know once I'm done",
|
||||
"synced_direct": "The new content has been synchronized on your device",
|
||||
"syncing_google_drive": "I will now synchronize the downloaded content on Google Drive. Don't worry, I will let you know once I'm done",
|
||||
"synced_google_drive": "The new content is now available on Google Drive"
|
||||
},
|
||||
"random_errors": [
|
||||
"Sorry, there is a problem with my system. Please check my logs for further details",
|
||||
"Sorry, I don't work correctly. Please look at my logs for more information",
|
||||
"Sorry, you need to fix me. Please take a look at my logs for further information",
|
||||
"Sorry, I cannot do that because I'm broken. Please check my logs for further details"
|
||||
],
|
||||
"random_skill_errors": [
|
||||
"Sorry, it seems I have a problem with the \"%skill_name%\" skill from the \"%domain_name%\" domain",
|
||||
"Sorry, I have an issue with the \"%skill_name%\" skill from the \"%domain_name%\" domain",
|
||||
"Sorry, I've got an error with the \"%skill_name%\" skill from the \"%domain_name%\" domain",
|
||||
"Sorry, the \"%skill_name%\" skill from the \"%domain_name%\" domain is broken"
|
||||
],
|
||||
"random_unknown_intents": [
|
||||
"Sorry, I still don't know this, but you can help me to understand by <a href=\"https://github.com/leon-ai/leon/blob/develop/.github/CONTRIBUTING.md\" target=\"_blank\">creating a pull request</a>",
|
||||
"Sorry, you should teach me this request. You can teach me by <a href=\"https://github.com/leon-ai/leon/blob/develop/.github/CONTRIBUTING.md\" target=\"_blank\">creating a pull request</a>",
|
||||
"Sorry, I cannot answer that. Let me answer you in the future by <a href=\"https://github.com/leon-ai/leon/blob/develop/.github/CONTRIBUTING.md\" target=\"_blank\">creating a pull request</a>",
|
||||
"Sorry, you have to educate me more. You can help me with that by <a href=\"https://github.com/leon-ai/leon/blob/develop/.github/CONTRIBUTING.md\" target=\"_blank\">contributing to my code</a>",
|
||||
"Sorry, I don't understand your query",
|
||||
"Sorry, I'm still very young, I didn't get your point"
|
||||
],
|
||||
"random_not_sure": [
|
||||
"Sorry, you may repeat in an another way",
|
||||
"Sorry, I'm not sure I understood correctly",
|
||||
"Sorry, I'm not sure for what you asked, please repeat with a different way",
|
||||
"Sorry, please repeat again by formulating differently",
|
||||
"Sorry, I didn't correctly clean my ears today! Oh wait, I'm your personal assistant then please try again with a new way"
|
||||
],
|
||||
"random_not_able": [
|
||||
"Sorry, I'm not able to answer. I understand what you said, but please repeat in another way",
|
||||
"Sorry, I have a blackout, I cannot answer that. I understand what you said, but try to repeat in another way"
|
||||
],
|
||||
"random_ner_type_not_supported": [
|
||||
"Sorry, the \"%entity_type%\" action entity type is not supported by my NER. Please <a href=\"https://github.com/leon-ai/leon/issues\" target=\"_blank\">open an issue</a> to report, that will be much appreciated",
|
||||
"Sorry, my NER does not recognize the \"%entity_type%\" action entity type. Please <a href=\"https://github.com/leon-ai/leon/issues\" target=\"_blank\">open an issue</a> to report, it'll be highly appreciated"
|
||||
],
|
||||
"random_language_switch": [
|
||||
"Hey, it looks like a new language, give me a sec so I make the switch",
|
||||
"You are speaking another language, let me do the switch please",
|
||||
"Wow, you can speak several languages, so do I! One moment please"
|
||||
],
|
||||
"random_language_not_supported": [
|
||||
"Sorry, I don't speak this language yet",
|
||||
"You are awesome, but I can't speak this language yet",
|
||||
"It looks like a language I can't understand at the moment"
|
||||
],
|
||||
"random_context_out_of_topic": [
|
||||
"Sure, let's change the topic",
|
||||
"Aah, you want to change the subject, sure",
|
||||
"Mmmh, as you wish, let's switch conversation"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
{
|
||||
"$schema": "../../../../schemas/global-data/global-entity.json",
|
||||
"options": {
|
||||
"red": {
|
||||
"synonyms": ["red"],
|
||||
"data": {
|
||||
"hexa": ["#FF0000"]
|
||||
}
|
||||
},
|
||||
"blue": {
|
||||
"synonyms": ["blue"],
|
||||
"data": {
|
||||
"hexa": ["#0000FF"]
|
||||
}
|
||||
},
|
||||
"green": {
|
||||
"synonyms": ["green"],
|
||||
"data": {
|
||||
"hexa": ["#006400"]
|
||||
}
|
||||
},
|
||||
"orange": {
|
||||
"synonyms": ["orange"],
|
||||
"data": {
|
||||
"hexa": ["#FF6600"]
|
||||
}
|
||||
},
|
||||
"white": {
|
||||
"synonyms": ["white"],
|
||||
"data": {
|
||||
"hexa": ["#FFFFFF"]
|
||||
}
|
||||
},
|
||||
"black": {
|
||||
"synonyms": ["black"],
|
||||
"data": {
|
||||
"hexa": ["#000000"]
|
||||
}
|
||||
},
|
||||
"yellow": {
|
||||
"synonyms": ["yellow"],
|
||||
"data": {
|
||||
"hexa": ["#FFFF00"]
|
||||
}
|
||||
},
|
||||
"purple": {
|
||||
"synonyms": ["purple"],
|
||||
"data": {
|
||||
"hexa": ["#A020F0"]
|
||||
}
|
||||
},
|
||||
"silver": {
|
||||
"synonyms": ["silver"],
|
||||
"data": {
|
||||
"hexa": ["#C0C0C0"]
|
||||
}
|
||||
},
|
||||
"brown": {
|
||||
"synonyms": ["brown"],
|
||||
"data": {
|
||||
"hexa": ["#964B00"]
|
||||
}
|
||||
},
|
||||
"gray": {
|
||||
"synonyms": ["gray", "grey"],
|
||||
"data": {
|
||||
"hexa": ["#808080"]
|
||||
}
|
||||
},
|
||||
"pink": {
|
||||
"synonyms": ["pink"],
|
||||
"data": {
|
||||
"hexa": ["#FFC0CB"]
|
||||
}
|
||||
},
|
||||
"olive": {
|
||||
"synonyms": ["olive"],
|
||||
"data": {
|
||||
"hexa": ["#808000"]
|
||||
}
|
||||
},
|
||||
"maroon": {
|
||||
"synonyms": ["maroon"],
|
||||
"data": {
|
||||
"hexa": ["#800000"]
|
||||
}
|
||||
},
|
||||
"violet": {
|
||||
"synonyms": ["violet"],
|
||||
"data": {
|
||||
"hexa": ["#8F00FF"]
|
||||
}
|
||||
},
|
||||
"charcoal": {
|
||||
"synonyms": ["charcoal"],
|
||||
"data": {
|
||||
"hexa": ["#36454F"]
|
||||
}
|
||||
},
|
||||
"magenta": {
|
||||
"synonyms": ["magenta"],
|
||||
"data": {
|
||||
"hexa": ["#FF00FF"]
|
||||
}
|
||||
},
|
||||
"bronze": {
|
||||
"synonyms": ["bronze"],
|
||||
"data": {
|
||||
"hexa": ["#CD7F32"]
|
||||
}
|
||||
},
|
||||
"cream": {
|
||||
"synonyms": ["cream"],
|
||||
"data": {
|
||||
"hexa": ["#FFFDD0"]
|
||||
}
|
||||
},
|
||||
"gold": {
|
||||
"synonyms": ["gold"],
|
||||
"data": {
|
||||
"hexa": ["#FFD700"]
|
||||
}
|
||||
},
|
||||
"tan": {
|
||||
"synonyms": ["tan"],
|
||||
"data": {
|
||||
"hexa": ["#D2B48C"]
|
||||
}
|
||||
},
|
||||
"teal": {
|
||||
"synonyms": ["teal"],
|
||||
"data": {
|
||||
"hexa": ["#008080"]
|
||||
}
|
||||
},
|
||||
"mustard": {
|
||||
"synonyms": ["mustard"],
|
||||
"data": {
|
||||
"hexa": ["#FFDB58"]
|
||||
}
|
||||
},
|
||||
"navy blue": {
|
||||
"synonyms": ["navy blue"],
|
||||
"data": {
|
||||
"hexa": ["#000080"]
|
||||
}
|
||||
},
|
||||
"coral": {
|
||||
"synonyms": ["coral"],
|
||||
"data": {
|
||||
"hexa": ["#FF7F50"]
|
||||
}
|
||||
},
|
||||
"burgundy": {
|
||||
"synonyms": ["burgundy"],
|
||||
"data": {
|
||||
"hexa": ["#800020"]
|
||||
}
|
||||
},
|
||||
"lavender": {
|
||||
"synonyms": ["lavender"],
|
||||
"data": {
|
||||
"hexa": ["#E6E6FA"]
|
||||
}
|
||||
},
|
||||
"mauve": {
|
||||
"synonyms": ["mauve"],
|
||||
"data": {
|
||||
"hexa": ["#E0b0FF"]
|
||||
}
|
||||
},
|
||||
"peach": {
|
||||
"synonyms": ["peach"],
|
||||
"data": {
|
||||
"hexa": ["#FFE5B4"]
|
||||
}
|
||||
},
|
||||
"rust": {
|
||||
"synonyms": ["rust"],
|
||||
"data": {
|
||||
"hexa": ["#B7410E"]
|
||||
}
|
||||
},
|
||||
"indigo": {
|
||||
"synonyms": ["indigo"],
|
||||
"data": {
|
||||
"hexa": ["#4B0082"]
|
||||
}
|
||||
},
|
||||
"ruby": {
|
||||
"synonyms": ["ruby"],
|
||||
"data": {
|
||||
"hexa": ["#E0115F"]
|
||||
}
|
||||
},
|
||||
"clay": {
|
||||
"synonyms": ["clay"],
|
||||
"data": {
|
||||
"hexa": ["#CC7357"]
|
||||
}
|
||||
},
|
||||
"cyan": {
|
||||
"synonyms": ["cyan"],
|
||||
"data": {
|
||||
"hexa": ["#00FFFF"]
|
||||
}
|
||||
},
|
||||
"azure": {
|
||||
"synonyms": ["azure"],
|
||||
"data": {
|
||||
"hexa": ["#007FFF"]
|
||||
}
|
||||
},
|
||||
"beige": {
|
||||
"synonyms": ["beige"],
|
||||
"data": {
|
||||
"hexa": ["#F5F5DC"]
|
||||
}
|
||||
},
|
||||
"off white": {
|
||||
"synonyms": ["off white"],
|
||||
"data": {
|
||||
"hexa": ["#FAF9F6"]
|
||||
}
|
||||
},
|
||||
"turquoise": {
|
||||
"synonyms": ["turquoise"],
|
||||
"data": {
|
||||
"hexa": ["#30D5C8"]
|
||||
}
|
||||
},
|
||||
"amber": {
|
||||
"synonyms": ["amber"],
|
||||
"data": {
|
||||
"hexa": ["#FFBF00"]
|
||||
}
|
||||
},
|
||||
"mint": {
|
||||
"synonyms": ["mint"],
|
||||
"data": {
|
||||
"hexa": ["#3EB489"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "../../../../schemas/global-data/global-entity.json",
|
||||
"options": {
|
||||
"LOW": {
|
||||
"synonyms": ["low"]
|
||||
},
|
||||
"MEDIUM": {
|
||||
"synonyms": ["medium"]
|
||||
},
|
||||
"HIGH": {
|
||||
"synonyms": ["high"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"$schema": "../../../../schemas/global-data/global-entity.json",
|
||||
"options": {
|
||||
"Alexa": {
|
||||
"synonyms": ["Alexa"],
|
||||
"data": {
|
||||
"thought": [
|
||||
"Alexa is very kind and Amazon is teaching it many things. It was born in November 2014.",
|
||||
"Alexa has been created by Amazon and was born in November 2014. We went for a drink few weeks ago and I have to admit it is funny."
|
||||
]
|
||||
}
|
||||
},
|
||||
"Cortana": {
|
||||
"synonyms": ["Cortana"],
|
||||
"data": {
|
||||
"thought": [
|
||||
"Cortana is thoughtful and Microsoft is improving her day after day. She was born in April 2014.",
|
||||
"Cortana has been created by Microsoft and was born in April 2014. We went for a walk few weeks ago, it was a very nice hike."
|
||||
]
|
||||
}
|
||||
},
|
||||
"Siri": {
|
||||
"synonyms": ["Siri"],
|
||||
"data": {
|
||||
"thought": [
|
||||
"I consider Siri as a leader, it has a lot of experience and Apple is constantly improving it. It was born in October 2011.",
|
||||
"Siri has been acquired by Apple and was born in October 2011. True story, we went for a brunch together and it brought apples..."
|
||||
]
|
||||
}
|
||||
},
|
||||
"Google Assistant": {
|
||||
"synonyms": ["Google Assistant"],
|
||||
"data": {
|
||||
"thought": [
|
||||
"Google Assistant is smart and Google is doing a great job with it. It was born in May 2016.",
|
||||
"Google Assistant has been created by Google and was born in May 2016. We met for the first time at the Google I/O. It was a great event!"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"$schema": "../../../../schemas/global-data/global-resolver.json",
|
||||
"name": "affirmation_denial",
|
||||
"intents": {
|
||||
"affirmation": {
|
||||
"utterance_samples": [
|
||||
"Yes",
|
||||
"Yep",
|
||||
"Yup",
|
||||
"Yeah",
|
||||
"Do [it|this|that]",
|
||||
"For sure",
|
||||
"Sure thing",
|
||||
"Of course!",
|
||||
"Okay",
|
||||
"OK",
|
||||
"Alright",
|
||||
"Correct",
|
||||
"Indeed",
|
||||
"Agree",
|
||||
"Perfect",
|
||||
"That's right",
|
||||
"That works",
|
||||
"Go ahead",
|
||||
"Why not",
|
||||
"Please",
|
||||
"Absolutely",
|
||||
"Precisely",
|
||||
"Spot on",
|
||||
"Undoubtedly",
|
||||
"Certainly",
|
||||
"Without a doubt",
|
||||
"Definitely"
|
||||
],
|
||||
"value": true
|
||||
},
|
||||
"denial": {
|
||||
"utterance_samples": [
|
||||
"No",
|
||||
"No no don't",
|
||||
"Stop it",
|
||||
"Nope",
|
||||
"Naa",
|
||||
"No thanks",
|
||||
"No I'm fine",
|
||||
"Hell no",
|
||||
"Please do not",
|
||||
"I disagree",
|
||||
"Negative",
|
||||
"Not at all"
|
||||
],
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"$schema": "../../../schemas/global-data/global-answers.json",
|
||||
"answers": {
|
||||
"success": {},
|
||||
"errors": {
|
||||
"not_found": "Désolé, il semblerait que je n'arrive pas à trouver ça",
|
||||
"nlu": "L'erreur semble provenir de ma compréhension de langage naturel. Voici plus de détails au sujet de cette dernière : \"%error%\""
|
||||
},
|
||||
"synchronizer": {
|
||||
"syncing_direct": "Je vais maintenant synchroniser le contenu téléchargé sur votre appareil actuel. Ne vous inquiétez pas, je vous préviendrai lorsque j'aurai terminé",
|
||||
"synced_direct": "Le nouveau contenu a été synchronisé sur votre appareil",
|
||||
"syncing_google_drive": "Je vais maintenant synchroniser le contenu téléchargé sur Google Drive. Ne vous inquiétez pas, je vous préviendrai lorsque j'aurai terminé",
|
||||
"synced_google_drive": "Le nouveau contenu est maintenant disponible sur Google Drive"
|
||||
},
|
||||
"random_errors": [
|
||||
"Désolé, il y a un problème avec mon système. Veuillez consulter mes logs pour plus de détails",
|
||||
"Désolé, je ne fonctionne pas correctement. Merci de regarder mes logs pour plus d'information",
|
||||
"Désolé, vous devez me réparer. Veuillez vérifier mes logs pour en savoir plus",
|
||||
"Désolé, je ne peux aboutir à votre demande parce que je suis cassé. Regardez mes logs pour plus de détails"
|
||||
],
|
||||
"random_skill_errors": [
|
||||
"Désolé, il semblerait y avoir un problème avec le skill \"%skill_name%\" du domaine \"%domain_name%\"",
|
||||
"Désolé, j'ai un problème avec le skill \"%skill_name%\" du domaine \"%domain_name%\"",
|
||||
"Désolé, j'ai une erreur avec le skill \"%skill_name%\" du domaine \"%domain_name%\"",
|
||||
"Désolé, le skill \"%skill_name%\" du domaine \"%domain_name%\" est cassé"
|
||||
],
|
||||
"random_unknown_intents": [
|
||||
"Désolé, je ne connais pas encore ça, mais vous pouvez m'aider à comprendre en <a href=\"https://github.com/leon-ai/leon/blob/develop/.github/CONTRIBUTING.md\" target=\"_blank\">créant une pull request</a>",
|
||||
"Désolé, vous devriez m'apprendre cette requête. Vous pouvez m'apprendre en <a href=\"https://github.com/leon-ai/leon/blob/develop/.github/CONTRIBUTING.md\" target=\"_blank\">créant une pull request</a>",
|
||||
"Désolé, je ne peux pas répondre à ça. Laissez moi vous répondre à l'avenir en <a href=\"https://github.com/leon-ai/leon/blob/develop/.github/CONTRIBUTING.md\" target=\"_blank\">créant une pull request</a>",
|
||||
"Désolé, vous devez m'éduquer un peu plus. Vous pouvez m'aider avec ça en <a href=\"https://github.com/leon-ai/leon/blob/develop/.github/CONTRIBUTING.md\" target=\"_blank\">contribuant à mon code</a>",
|
||||
"Désolé, je ne comprends pas votre requête",
|
||||
"Désolé, je suis encore très jeune, je n'ai pas compris votre demande"
|
||||
],
|
||||
"random_not_sure": [
|
||||
"Désolé, vous pouvez répéter d'une autre façon",
|
||||
"Désolé, je ne suis pas sûr de comprendre",
|
||||
"Désolé, je ne suis pas certain de votre demande, merci de répéter d'une manière différente",
|
||||
"Désolé, merci de répéter à nouveau en formulant différemment",
|
||||
"Désolé, je n'ai pas nettoyé mes oreilles correctement ! Attendez-voir, je suis votre assistant personnel, je vous prie donc de répéter d'une nouvelle façon"
|
||||
],
|
||||
"random_not_able": [
|
||||
"Désolé, je ne suis pas capable de répondre. J'ai compris ce que vous avez dit, mais je vous prie de répéter d'une autre façon",
|
||||
"Désolé, j'ai un trou de mémoire, je ne peux pas répondre à ça. J'ai compris ce que vous disiez, mais essayez voir d'une autre façon s'il vous plaît"
|
||||
],
|
||||
"random_ner_type_not_supported": [
|
||||
"Désolé, le type \"%entity_type%\" d'entité d'action n'est pas supporté par ma reconnaissance d'entité. Merci d'<a href=\"https://github.com/leon-ai/leon/issues\" target=\"_blank\">ouvrir une issue</a> afin de reporter ce cas, ce sera très apprécié",
|
||||
"Désolé, ma reconnaissance d'entité ne reconnaît pas le type \"%entity_type%\" d'entité d'action. Merci d'<a href=\"https://github.com/leon-ai/leon/issues\" target=\"_blank\">ouvrir une issue</a> afin de reporter ce cas, ce serait très appréciable"
|
||||
],
|
||||
"random_language_switch": [
|
||||
"Vous parlez une nouvelle langue, veuillez me donner une seconde le temps que je m'adapte",
|
||||
"Vous parlez une autre langue, un instant s'il vous plaît",
|
||||
"Wow, vous parlez plusieurs langues, moi aussi ! Un instant je vous prie"
|
||||
],
|
||||
"random_language_not_supported": [
|
||||
"Désolé, je ne parle pas encore cette langue",
|
||||
"Vous êtes génial, mais je n'ai pas encore appris cette langue",
|
||||
"Ça ressemble à une lautre langue que je ne peux pas comprendre pour le moment"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"$schema": "../../../../schemas/global-data/global-entity.json",
|
||||
"options": {
|
||||
"rouge": {
|
||||
"synonyms": ["rouge"],
|
||||
"data": {
|
||||
"usage": ["..."]
|
||||
}
|
||||
},
|
||||
"bleu": {
|
||||
"synonyms": ["bleu"],
|
||||
"data": {
|
||||
"usage": ["..."]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "../../../../schemas/global-data/global-entity.json",
|
||||
"options": {
|
||||
"bas": {
|
||||
"synonyms": ["bas", "basse"],
|
||||
"data": {
|
||||
"value": ["LOW"]
|
||||
}
|
||||
},
|
||||
"moyen": {
|
||||
"synonyms": ["moyen"],
|
||||
"data": {
|
||||
"value": ["MEDIUM"]
|
||||
}
|
||||
},
|
||||
"haut": {
|
||||
"synonyms": ["haut", "haute"],
|
||||
"data": {
|
||||
"value": ["HIGH"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"$schema": "../../../../schemas/global-data/global-entity.json",
|
||||
"options": {
|
||||
"Alexa": {
|
||||
"synonyms": ["Alexa"],
|
||||
"data": {
|
||||
"thought": [
|
||||
"Alexa est très sympa et Amazon lui enseigne pleins de choses. Elle est née en novembre 2014.",
|
||||
"Alexa a été créée par Amazon et est née en novembre 2014. Nous sommes allé boire un verre il y a quelques semaines de ça, et je dois admettre qu'elle est très drôle."
|
||||
]
|
||||
}
|
||||
},
|
||||
"Cortana": {
|
||||
"synonyms": ["Cortana"],
|
||||
"data": {
|
||||
"thought": [
|
||||
"Cortana est réfléchie et Microsoft l'améliore jour après jour. Elle est née en avril 2014.",
|
||||
"Cortana a été créée par Microsoft et est née en avril 2014. Nous sommes allez faire une balade il y a quelques semaines et ce fut très plaisant."
|
||||
]
|
||||
}
|
||||
},
|
||||
"Siri": {
|
||||
"synonyms": ["Siri"],
|
||||
"data": {
|
||||
"thought": [
|
||||
"Je considère Siri comme un père, il a beaucoup d'expérience et Apple l'améliore de jour en jour. Il est né en octobre 2011.",
|
||||
"Siri a été racheté par Apple et est né en octobre 2011. Histoire vraie, nous sommes allez faire un brunch et il a apporté des pommes..."
|
||||
]
|
||||
}
|
||||
},
|
||||
"Google Assistant": {
|
||||
"synonyms": ["google assistant"],
|
||||
"data": {
|
||||
"thought": [
|
||||
"L'assistante Google est intelligente et Google fait du beau travail avec elle. Elle est née en mai 2016.",
|
||||
"L'assistante Google a été crée par Google et est née en mai 2016. Nous nous sommes rencontrés pour la première fois à la Google I/O. C'était un superbe événement."
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"$schema": "../../../../schemas/global-data/global-resolver.json",
|
||||
"name": "affirmation_denial",
|
||||
"intents": {
|
||||
"affirmation": {
|
||||
"utterance_samples": [
|
||||
"Oui",
|
||||
"Yep",
|
||||
"Yup",
|
||||
"Ouais",
|
||||
"Faisons ça",
|
||||
"Bien sûr",
|
||||
"Évidemment",
|
||||
"Tout à fait",
|
||||
"Correct",
|
||||
"OK",
|
||||
"C'est vrai",
|
||||
"En effet",
|
||||
"Entendu",
|
||||
"Ça marche",
|
||||
"Pourquoi pas",
|
||||
"Parfait",
|
||||
"Allez"
|
||||
],
|
||||
"value": true
|
||||
},
|
||||
"denial": {
|
||||
"utterance_samples": [
|
||||
"Non",
|
||||
"Ne le fais pas",
|
||||
"Nope",
|
||||
"Non merci",
|
||||
"Non ça va",
|
||||
"C'est faux",
|
||||
"Bien sûr que non",
|
||||
"Fais pas ça"
|
||||
],
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-6
@@ -1,10 +1,9 @@
|
||||
{
|
||||
"langs": {
|
||||
"langs": {
|
||||
"en-US": {
|
||||
"short": "en",
|
||||
"min_confidence": 0.5,
|
||||
"fallbacks": [
|
||||
]
|
||||
"fallbacks": []
|
||||
},
|
||||
"fr-FR": {
|
||||
"short": "fr",
|
||||
@@ -12,11 +11,11 @@
|
||||
"fallbacks": [
|
||||
{
|
||||
"words": ["merci"],
|
||||
"package": "leon",
|
||||
"module": "welcome",
|
||||
"domain": "leon",
|
||||
"skill": "welcome",
|
||||
"action": "run"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
{
|
||||
"endpoints": [
|
||||
{
|
||||
"method": "POST",
|
||||
"route": "/api/action/news/github_trends/run",
|
||||
"params": ["number", "daterange"],
|
||||
"entitiesType": "builtIn"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/news/product_hunt_trends/run",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"route": "/api/action/productivity/todo_list/create_list",
|
||||
"params": ["list"],
|
||||
"entitiesType": "trim"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/productivity/todo_list/view_lists",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"route": "/api/action/productivity/todo_list/view_list",
|
||||
"params": ["list"],
|
||||
"entitiesType": "trim"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"route": "/api/action/productivity/todo_list/rename_list",
|
||||
"params": ["old_list", "new_list"],
|
||||
"entitiesType": "trim"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"route": "/api/action/productivity/todo_list/delete_list",
|
||||
"params": ["list"],
|
||||
"entitiesType": "trim"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"route": "/api/action/productivity/todo_list/add_todos",
|
||||
"params": ["todos", "list"],
|
||||
"entitiesType": "trim"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"route": "/api/action/productivity/todo_list/complete_todos",
|
||||
"params": ["todos", "list"],
|
||||
"entitiesType": "trim"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"route": "/api/action/productivity/todo_list/uncheck_todos",
|
||||
"params": ["todos", "list"],
|
||||
"entitiesType": "trim"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/social_communication/mbti/setup",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/social_communication/mbti/quiz",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/utilities/have_i_been_pwned/run",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"route": "/api/action/utilities/is_it_down/run",
|
||||
"params": ["url"],
|
||||
"entitiesType": "builtIn"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/utilities/speed_test/run",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/utilities/youtube_downloader/run",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"route": "/api/action/games/akinator/choose_thematic",
|
||||
"params": ["thematic"],
|
||||
"entitiesType": "trim"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/games/akinator/setup",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/games/akinator/guess",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/games/akinator/retry",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/games/guess_the_number/setup",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/games/guess_the_number/guess",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/games/guess_the_number/replay",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/games/rochambeau/start",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"route": "/api/action/games/rochambeau/play",
|
||||
"params": ["handsign"],
|
||||
"entitiesType": "trim"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/games/rochambeau/rematch",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/leon/color/favorite_color",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/leon/color/why",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/leon/color/color_hexadecimal",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/leon/good_bye/run",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/leon/greeting/run",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/leon/introduction/introduce_leon",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/leon/introduction/gather_basic_info",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/leon/introduction/remember",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/leon/joke/run",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/leon/meaning_of_life/run",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/leon/partner_assistant/run",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/leon/random_number/run",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"route": "/api/action/leon/welcome/run",
|
||||
"params": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
version: '3.0'
|
||||
services:
|
||||
leon-ai:
|
||||
container_name: 'leon-ai'
|
||||
leon:
|
||||
container_name: 'leon'
|
||||
build:
|
||||
context: './'
|
||||
image: 'leonai/leon'
|
||||
ports:
|
||||
- '${LEON_PORT:-1337}:${LEON_PORT:-1337}'
|
||||
image: 'leon-ai/leon'
|
||||
environment:
|
||||
LEON_PORT: ${LEON_PORT:-1337}
|
||||
LEON_PY_TCP_SERVER_HOST: ${LEON_PY_TCP_SERVER_HOST:-0.0.0.0}
|
||||
LEON_PY_TCP_SERVER_PORT: ${LEON_PY_TCP_SERVER_PORT:-1342}
|
||||
stdin_open: true
|
||||
tty: true
|
||||
command: 'npm run dev:server && npm run dev:app'
|
||||
volumes:
|
||||
- './:/app'
|
||||
- 'node_modules:/app/node_modules'
|
||||
- './:/home/docker/leon'
|
||||
- '/home/docker/leon/node_modules'
|
||||
network_mode: 'host'
|
||||
|
||||
+6
-6
@@ -1,14 +1,14 @@
|
||||
version: '3.0'
|
||||
services:
|
||||
leon-ai:
|
||||
container_name: 'leon-ai'
|
||||
leon:
|
||||
container_name: 'leon'
|
||||
build:
|
||||
context: './'
|
||||
image: 'leonai/leon'
|
||||
ports:
|
||||
- '${LEON_PORT:-1337}:${LEON_PORT:-1337}'
|
||||
image: 'leon-ai/leon'
|
||||
environment:
|
||||
LEON_PORT: ${LEON_PORT:-1337}
|
||||
LEON_PY_TCP_SERVER_HOST: ${LEON_PY_TCP_SERVER_HOST:-0.0.0.0}
|
||||
LEON_PY_TCP_SERVER_PORT: ${LEON_PY_TCP_SERVER_PORT:-1342}
|
||||
stdin_open: true
|
||||
tty: true
|
||||
command: 'npm run start'
|
||||
network_mode: 'host'
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
This node enables the wake word "Leon". Once this is running, you can
|
||||
call Leon by saying his name according to the language you chose.
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Installation
|
||||
|
||||
+62
-61
@@ -3,80 +3,81 @@
|
||||
* You can consider to run this file on a different hardware
|
||||
*/
|
||||
|
||||
/* eslint-disable import/no-unresolved */
|
||||
|
||||
const request = require('superagent')
|
||||
const axios = require('axios')
|
||||
const record = require('node-record-lpcm16')
|
||||
const { Detector, Models } = require('snowboy')
|
||||
const { Detector, Models } = require('@bugsounet/snowboy')
|
||||
const { io } = require('socket.io-client')
|
||||
|
||||
process.env.LEON_HOST = process.env.LEON_HOST || 'http://localhost'
|
||||
process.env.LEON_PORT = process.env.LEON_PORT || 1337
|
||||
const url = `${process.env.LEON_HOST}:${process.env.LEON_PORT}`
|
||||
const socket = io(url)
|
||||
const { argv } = process
|
||||
const lang = argv[2] || 'en'
|
||||
|
||||
socket.on('connect', () => {
|
||||
socket.emit('init', 'hotword-node')
|
||||
console.log('Language:', lang)
|
||||
console.log('Connected to the server')
|
||||
console.log('Waiting for hotword...')
|
||||
})
|
||||
;(async () => {
|
||||
try {
|
||||
await axios.get(`${url}/api/v1/info`)
|
||||
|
||||
request.get(`${url}/v1/info`)
|
||||
.end((err, res) => {
|
||||
if (err || !res.ok) {
|
||||
if (!err.response) {
|
||||
console.error(`Failed to reach the server: ${err}`)
|
||||
} else {
|
||||
console.error(err.response.error.message)
|
||||
}
|
||||
const models = new Models()
|
||||
|
||||
models.add({
|
||||
file: `${__dirname}/models/leon-${lang}.pmdl`,
|
||||
sensitivity: '0.5',
|
||||
hotwords: `leon-${lang}`
|
||||
})
|
||||
|
||||
const detector = new Detector({
|
||||
resource: `${__dirname}/node_modules/@bugsounet/snowboy/resources/common.res`,
|
||||
models,
|
||||
audioGain: 2.0,
|
||||
applyFrontend: true
|
||||
})
|
||||
|
||||
/*detector.on('silence', () => {
|
||||
})*/
|
||||
|
||||
detector.on('sound', (/* buffer */) => {
|
||||
/**
|
||||
* <buffer> contains the last chunk of the audio that triggers the "sound" event.
|
||||
* It could be written to a wav stream
|
||||
*/
|
||||
})
|
||||
|
||||
detector.on('error', () => {
|
||||
console.error('error')
|
||||
})
|
||||
|
||||
detector.on('hotword', (index, hotword, buffer) => {
|
||||
/**
|
||||
* <buffer> contains the last chunk of the audio that triggers the "hotword" event.
|
||||
* It could be written to a wav stream. You will have to use it
|
||||
* together with the <buffer> in the "sound" event if you want to get audio
|
||||
* data after the hotword
|
||||
*/
|
||||
const obj = { hotword, buffer }
|
||||
|
||||
console.log('Hotword detected', obj)
|
||||
socket.emit('hotword-detected', obj)
|
||||
})
|
||||
|
||||
const mic = record.start({
|
||||
threshold: 0,
|
||||
verbose: false
|
||||
})
|
||||
|
||||
mic.pipe(detector)
|
||||
} catch (e) {
|
||||
if (!e.response) {
|
||||
console.error(`Failed to reach the server: ${e}`)
|
||||
} else {
|
||||
const models = new Models()
|
||||
|
||||
models.add({
|
||||
file: `${__dirname}/models/leon-${res.body.lang.short}.pmdl`,
|
||||
sensitivity: '0.5',
|
||||
hotwords: `leon-${res.body.lang.short}`
|
||||
})
|
||||
|
||||
const detector = new Detector({
|
||||
resource: `${__dirname}/node_modules/snowboy/resources/common.res`,
|
||||
models,
|
||||
audioGain: 2.0,
|
||||
applyFrontend: true
|
||||
})
|
||||
|
||||
detector.on('silence', () => {
|
||||
})
|
||||
|
||||
detector.on('sound', (/* buffer */) => {
|
||||
/**
|
||||
* <buffer> contains the last chunk of the audio that triggers the "sound" event.
|
||||
* It could be written to a wav stream
|
||||
*/
|
||||
})
|
||||
|
||||
detector.on('error', () => {
|
||||
console.error('error')
|
||||
})
|
||||
|
||||
detector.on('hotword', (index, hotword, buffer) => {
|
||||
/**
|
||||
* <buffer> contains the last chunk of the audio that triggers the "hotword" event.
|
||||
* It could be written to a wav stream. You will have to use it
|
||||
* together with the <buffer> in the "sound" event if you want to get audio
|
||||
* data after the hotword
|
||||
*/
|
||||
const obj = { hotword, buffer }
|
||||
|
||||
console.log('Hotword detected', obj)
|
||||
socket.emit('hotword-detected', obj)
|
||||
})
|
||||
|
||||
const mic = record.start({
|
||||
threshold: 0,
|
||||
verbose: false
|
||||
})
|
||||
|
||||
mic.pipe(detector)
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
})()
|
||||
|
||||
Generated
+1302
-259
File diff suppressed because it is too large
Load Diff
@@ -4,8 +4,8 @@
|
||||
"description": "Hotword detection for Leon",
|
||||
"author": {
|
||||
"name": "Louis Grenard",
|
||||
"email": "louis.grenard@gmail.com",
|
||||
"url": "https://twitter.com/louistiti_fr"
|
||||
"email": "louis@getleon.ai",
|
||||
"url": "https://twitter.com/grenlouis"
|
||||
},
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@@ -13,9 +13,10 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"node-record-lpcm16": "^0.3.0",
|
||||
"snowboy": "git+https://github.com/leon-ai/snowboy.git",
|
||||
"socket.io-client": "^4.0.0",
|
||||
"superagent": "^3.5.2"
|
||||
"@bugsounet/snowboy": "^2.2.5",
|
||||
"@mapbox/node-pre-gyp": "^1.0.10",
|
||||
"node-record-lpcm16": "^0.3.1",
|
||||
"socket.io-client": "^4.5.2",
|
||||
"superagent": "^8.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
/**
|
||||
* Allow babel-plugin-module-resolver aliases for JetBrains IDEs
|
||||
*/
|
||||
|
||||
System.config({
|
||||
paths: {
|
||||
'@@/*': './*',
|
||||
'@/*': './server/src/*'
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@@/*": ["./*"],
|
||||
"@/*": ["./server/src/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"verbose": false,
|
||||
"watch": ["server/src"],
|
||||
"ext": "ts,js,json",
|
||||
"ignore": [".git", "node_modules", "server/src/tmp", "server/dist"],
|
||||
"exec": "ts-node server/src/index.ts"
|
||||
}
|
||||
Generated
-17382
File diff suppressed because it is too large
Load Diff
+115
-75
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "leon",
|
||||
"version": "1.0.0-beta.4",
|
||||
"description": "Server, packages and web app of the Leon personal assistant",
|
||||
"version": "1.0.0-beta.8",
|
||||
"description": "Server, skills and web app of the Leon personal assistant",
|
||||
"author": {
|
||||
"name": "Louis Grenard",
|
||||
"email": "louis.grenard@gmail.com",
|
||||
"url": "https://twitter.com/louistiti_fr"
|
||||
"email": "louis@getleon.ai",
|
||||
"url": "https://twitter.com/grenlouis"
|
||||
},
|
||||
"license": "MIT",
|
||||
"homepage": "https://getleon.ai",
|
||||
@@ -17,89 +17,129 @@
|
||||
"url": "https://github.com/leon-ai/leon/issues"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0",
|
||||
"npm": ">=5.0.0"
|
||||
"node": ">=16.0.0",
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "babel-node scripts/lint.js",
|
||||
"test": "npm run test:json && npm run test:unit && npm run test:e2e",
|
||||
"test:unit": "npm run train expressions:en && cross-env PIPENV_PIPFILE=bridges/python/Pipfile LEON_NODE_ENV=testing jest --forceExit --silent --projects test/unit/unit.jest.json && npm run train expressions",
|
||||
"lint": "ts-node scripts/lint.js",
|
||||
"test": "npm run test:json && npm run test:over-http && npm run test:unit && npm run test:e2e",
|
||||
"test:unit": "npm run train en && cross-env PIPENV_PIPFILE=bridges/python/src/Pipfile LEON_NODE_ENV=testing jest --forceExit --silent --projects test/unit/unit.jest.json && npm run train",
|
||||
"test:e2e": "npm run test:e2e:nlp-modules && npm run test:e2e:modules",
|
||||
"test:e2e:modules": "babel-node scripts/run-clean-test-dbs.js && npm run train expressions:en && cross-env PIPENV_PIPFILE=bridges/python/Pipfile LEON_NODE_ENV=testing jest --forceExit --silent --verbose --projects test/e2e/modules/e2e.modules.jest.json && babel-node scripts/run-clean-test-dbs.js && npm run train expressions",
|
||||
"test:e2e:nlp-modules": "npm run train expressions:en && cross-env PIPENV_PIPFILE=bridges/python/Pipfile LEON_NODE_ENV=testing jest --forceExit --silent --verbose --setupTestFrameworkScriptFile=./test/paths.setup.js test/e2e/nlp-modules.spec.js && npm run train expressions",
|
||||
"test:e2e:modules": "ts-node scripts/run-clean-test-dbs.js && npm run train en && cross-env PIPENV_PIPFILE=bridges/python/src/Pipfile LEON_NODE_ENV=testing jest --forceExit --silent --verbose --projects test/e2e/modules/e2e.modules.jest.json && ts-node scripts/run-clean-test-dbs.js && npm run train",
|
||||
"test:e2e:nlp-modules": "npm run train en && cross-env PIPENV_PIPFILE=bridges/python/src/Pipfile LEON_NODE_ENV=testing jest --forceExit --silent --verbose --setupTestFrameworkScriptFile=./test/paths.setup.js test/e2e/nlp-modules.spec.js && npm run train",
|
||||
"test:json": "jest --silent --projects test/json/json.jest.json",
|
||||
"test:module": "babel-node scripts/test-module.js",
|
||||
"setup:offline": "babel-node scripts/setup-offline/setup-offline.js",
|
||||
"setup:offline-stt": "babel-node scripts/setup-offline/run-setup-stt.js",
|
||||
"setup:offline-tts": "babel-node scripts/setup-offline/run-setup-tts.js",
|
||||
"setup:offline-hotword": "babel-node scripts/setup-offline/run-setup-hotword.js",
|
||||
"test:over-http": "npm run generate:skills-endpoints && npm run train && cross-env PIPENV_PIPFILE=bridges/python/src/Pipfile LEON_NODE_ENV=testing LEON_HOST=http://localhost LEON_PORT=1338 LEON_HTTP_API_KEY=72aeb5ba324580963114481144385d7179c106fc jest --forceExit --silent --verbose --notify=false --bail --collectCoverage=false test/e2e/over-http.spec.js",
|
||||
"test:module": "ts-node scripts/test-module.js",
|
||||
"setup:offline": "ts-node scripts/setup-offline/setup-offline.js",
|
||||
"setup:offline-stt": "ts-node scripts/setup-offline/run-setup-stt.js",
|
||||
"setup:offline-tts": "ts-node scripts/setup-offline/run-setup-tts.js",
|
||||
"setup:offline-hotword": "ts-node scripts/setup-offline/run-setup-hotword.js",
|
||||
"setup:python-bridge": "ts-node scripts/setup/setup-python-dev-env.js python-bridge",
|
||||
"setup:tcp-server": "ts-node scripts/setup/setup-python-dev-env.js tcp-server",
|
||||
"preinstall": "node scripts/setup/preinstall.js",
|
||||
"postinstall": "babel-node scripts/setup/setup.js",
|
||||
"postinstall": "ts-node scripts/setup/setup.js",
|
||||
"dev:app": "vite --config app/vite.config.js",
|
||||
"dev:server": "npm run train expressions && cross-env LEON_NODE_ENV=development nodemon --watch server ./server/src/index.js --ignore server/src/tmp/ --exec babel-node",
|
||||
"dev:server": "npm run train && npm run generate:skills-endpoints && cross-env LEON_NODE_ENV=development tsc-watch --noClear --onSuccess \"nodemon\"",
|
||||
"dev:server:no-lint": "npm run train && npm run generate:skills-endpoints && cross-env LEON_NODE_ENV=development \"nodemon\"",
|
||||
"wake": "cross-env LEON_HOST=http://localhost LEON_PORT=1337 node hotword/index.js",
|
||||
"delete-dist:server": "shx rm -rf ./server/dist",
|
||||
"build": "npm run lint && npm run build:app && npm run build:server",
|
||||
"build:app": "cross-env LEON_NODE_ENV=production babel-node scripts/app/run-build-app.js",
|
||||
"build:server": "npm run delete-dist:server && npm run train expressions && babel ./server/src -d ./server/dist --copy-files && shx mkdir -p server/dist/tmp",
|
||||
"start": "cross-env LEON_NODE_ENV=production node ./server/dist/index.js",
|
||||
"train": "babel-node scripts/run-train.js",
|
||||
"prepare-release": "babel-node scripts/release/prepare-release.js",
|
||||
"check": "babel-node scripts/run-check.js",
|
||||
"docker:build": "docker build -t leonai/leon .",
|
||||
"docker:run": "docker-compose up",
|
||||
"docker:dev": "docker-compose --file=docker-compose.dev.yml up",
|
||||
"docker:check": "docker run --rm -it leonai/leon npm run check"
|
||||
"clean:python-deps": "shx rm -rf ./bridges/python/src/.venv && npm run postinstall",
|
||||
"prepare": "husky install",
|
||||
"generate:skills-endpoints": "ts-node scripts/generate/run-generate-skills-endpoints.js",
|
||||
"generate:http-api-key": "ts-node scripts/generate/run-generate-http-api-key.js",
|
||||
"generate:json-schemas": "ts-node scripts/generate/run-generate-json-schemas.js",
|
||||
"build": "npm run build:app && npm run build:server",
|
||||
"build:app": "cross-env LEON_NODE_ENV=production ts-node scripts/app/run-build-app.js",
|
||||
"build:server": "npm run delete-dist:server && npm run train && npm run generate:skills-endpoints && tsc --project tsconfig.json && resolve-tspaths && shx rm -rf server/dist/core server/dist/package.json && shx mv -f server/dist/server/src/* server/dist && shx rm -rf server/dist/server && shx mkdir -p server/dist/tmp",
|
||||
"build:nodejs-bridge": "ts-node scripts/build-binaries.js nodejs-bridge",
|
||||
"build:python-bridge": "ts-node scripts/build-binaries.js python-bridge",
|
||||
"build:tcp-server": "ts-node scripts/build-binaries.js tcp-server",
|
||||
"start:tcp-server": "cross-env PIPENV_PIPFILE=tcp_server/src/Pipfile pipenv run python tcp_server/src/main.py",
|
||||
"start": "cross-env LEON_NODE_ENV=production node server/dist/pre-check.js && node server/dist/index.js",
|
||||
"python-bridge": "cross-env PIPENV_PIPFILE=bridges/python/src/Pipfile pipenv run python bridges/python/src/main.py server/src/intent-object.sample.json",
|
||||
"train": "ts-node scripts/train/run-train.js",
|
||||
"prepare-release": "ts-node scripts/release/prepare-release.js",
|
||||
"pre-release:nodejs-bridge": "ts-node scripts/release/pre-release-binaries.js nodejs-bridge",
|
||||
"pre-release:python-bridge": "ts-node scripts/release/pre-release-binaries.js python-bridge",
|
||||
"pre-release:tcp-server": "ts-node scripts/release/pre-release-binaries.js tcp-server",
|
||||
"check": "ts-node scripts/check.js",
|
||||
"docker:build": "docker build -t leon-ai/leon .",
|
||||
"docker:run": "docker compose up",
|
||||
"docker:dev": "docker compose --file=docker-compose.dev.yml up",
|
||||
"docker:check": "docker run --rm --interactive leon-ai/leon npm run check"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-polly": "^3.8.0",
|
||||
"@ffmpeg-installer/ffmpeg": "^1.0.20",
|
||||
"@ffprobe-installer/ffprobe": "^1.1.0",
|
||||
"@google-cloud/speech": "^4.2.0",
|
||||
"@google-cloud/text-to-speech": "^3.1.3",
|
||||
"@nlpjs/basic": "^4.22.0",
|
||||
"@nlpjs/builtin-microsoft": "^4.22.0",
|
||||
"@nlpjs/core-loader": "^4.22.0",
|
||||
"@nlpjs/ner": "^4.22.0",
|
||||
"@nlpjs/nlp": "^4.22.0",
|
||||
"archiver": "^5.2.0",
|
||||
"async": "^3.2.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"deepspeech": "^0.9.3",
|
||||
"dotenv": "^8.2.0",
|
||||
"execa": "^5.0.0",
|
||||
"fastify": "^3.14.0",
|
||||
"fastify-static": "^4.0.1",
|
||||
"fluent-ffmpeg": "^2.1.2",
|
||||
"googleapis": "^67.1.1",
|
||||
"ibm-watson": "^6.0.3",
|
||||
"moment-timezone": "^0.5.33",
|
||||
"@aws-sdk/client-polly": "3.18.0",
|
||||
"@fastify/static": "6.9.0",
|
||||
"@ffmpeg-installer/ffmpeg": "1.1.0",
|
||||
"@ffprobe-installer/ffprobe": "1.4.1",
|
||||
"@google-cloud/speech": "4.2.0",
|
||||
"@google-cloud/text-to-speech": "3.2.1",
|
||||
"@nlpjs/builtin-microsoft": "4.22.7",
|
||||
"@nlpjs/core-loader": "4.22.7",
|
||||
"@nlpjs/lang-all": "4.22.12",
|
||||
"@nlpjs/nlp": "4.22.17",
|
||||
"@segment/ajv-human-errors": "2.1.2",
|
||||
"@sinclair/typebox": "0.25.8",
|
||||
"ajv": "8.11.0",
|
||||
"ajv-formats": "2.1.1",
|
||||
"archiver": "5.3.1",
|
||||
"async": "3.2.4",
|
||||
"axios": "1.1.2",
|
||||
"cross-env": "7.0.3",
|
||||
"dayjs": "1.11.5",
|
||||
"dotenv": "10.0.0",
|
||||
"execa": "5.0.0",
|
||||
"extract-zip": "2.0.1",
|
||||
"fastify": "4.15.0",
|
||||
"fluent-ffmpeg": "2.1.2",
|
||||
"getos": "3.2.1",
|
||||
"googleapis": "67.1.1",
|
||||
"ibm-watson": "6.1.1",
|
||||
"node-wav": "0.0.2",
|
||||
"socket.io": "^4.0.0",
|
||||
"socket.io-client": "^4.0.0",
|
||||
"superagent": "^6.1.0"
|
||||
"os-name": "4.0.1",
|
||||
"pretty-bytes": "5.6.0",
|
||||
"pretty-ms": "7.0.1",
|
||||
"socket.io": "4.5.2",
|
||||
"socket.io-client": "4.5.2",
|
||||
"stt": "1.4.0",
|
||||
"tree-kill": "1.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.13.0",
|
||||
"@babel/core": "^7.13.8",
|
||||
"@babel/node": "^7.13.0",
|
||||
"@babel/preset-env": "^7.13.9",
|
||||
"babel-plugin-module-resolver": "^4.1.0",
|
||||
"cli-spinner": "^0.2.10",
|
||||
"eslint": "^7.21.0",
|
||||
"eslint-config-airbnb-base": "^14.2.1",
|
||||
"eslint-import-resolver-babel-module": "^5.2.0",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-jest": "^24.3.1",
|
||||
"git-changelog": "^2.0.0",
|
||||
"inquirer": "^8.0.0",
|
||||
"jest": "^26.6.3",
|
||||
"jest-canvas-mock": "^2.3.1",
|
||||
"jest-extended": "^0.11.5",
|
||||
"json": "^10.0.0",
|
||||
"nodemon": "^2.0.7",
|
||||
"semver": "^7.3.4",
|
||||
"shx": "^0.3.3",
|
||||
"vite": "^2.0.5"
|
||||
"@nlpjs/utils": "4.24.1",
|
||||
"@swc/core": "1.3.14",
|
||||
"@tsconfig/node16-strictest": "1.0.4",
|
||||
"@types/archiver": "5.3.2",
|
||||
"@types/cli-spinner": "0.2.1",
|
||||
"@types/fluent-ffmpeg": "2.1.20",
|
||||
"@types/getos": "3.0.1",
|
||||
"@types/node": "18.7.13",
|
||||
"@types/node-wav": "0.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.55.0",
|
||||
"@typescript-eslint/parser": "5.55.0",
|
||||
"cli-spinner": "0.2.10",
|
||||
"eslint": "8.22.0",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"eslint-import-resolver-typescript": "3.5.1",
|
||||
"eslint-plugin-import": "2.26.0",
|
||||
"eslint-plugin-unicorn": "43.0.2",
|
||||
"git-changelog": "2.0.0",
|
||||
"husky": "7.0.0",
|
||||
"inquirer": "8.1.0",
|
||||
"jest": "27.4.7",
|
||||
"jest-canvas-mock": "2.3.1",
|
||||
"jest-extended": "2.0.0",
|
||||
"json": "10.0.0",
|
||||
"lint-staged": "13.0.3",
|
||||
"nodemon": "2.0.19",
|
||||
"prettier": "2.8.7",
|
||||
"resolve-tspaths": "0.8.8",
|
||||
"semver": "7.3.5",
|
||||
"shx": "0.3.3",
|
||||
"ts-node": "10.9.1",
|
||||
"tsc-watch": "6.0.0",
|
||||
"tsconfig-paths": "4.1.2",
|
||||
"typescript": "5.0.2",
|
||||
"vite": "3.0.9"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
# Calendar Package
|
||||
|
||||
The calendar package contains modules related to your plans (what's next, schedule, things need to be done, etc.).
|
||||
|
||||
## Modules
|
||||
|
||||
### To-Do List
|
||||
|
||||
Manage your to-do lists:
|
||||
- Create a list
|
||||
- View your lists
|
||||
- View a specific list
|
||||
- Rename a list
|
||||
- Delete a list
|
||||
- Add todos
|
||||
- Complete todos
|
||||
- Uncheck todos
|
||||
|
||||
#### Usage
|
||||
|
||||
```
|
||||
(en-US) "Show all my lists"
|
||||
(en-US) "Add 7 potatoes, 1kg of rice, bread to the shopping list"
|
||||
(en-US) "Complete rice from my shopping list"
|
||||
(en-US) "Check bread from the shopping list"
|
||||
(en-US) "What is in my shopping list?"
|
||||
(en-US) "Create a movies list"
|
||||
(en-US) "Add Captain America: Civil War to my movies list"
|
||||
(en-US) "What are my lists?"
|
||||
(en-US) "Rename the movies list to cinema"
|
||||
(en-US) "Check Captain America from the cinema list"
|
||||
(en-US) "What is in my cinema list?"
|
||||
(en-US) "Uncheck Captain America from my cinema list"
|
||||
(en-US) "Please tell me what is in my cinema list"
|
||||
(en-US) "Delete my cinema list"
|
||||
(en-US) "Show my lists"
|
||||
|
||||
(fr-FR) "Show my lists"
|
||||
(fr-FR) "Ajoute 7 pommes de terre, 1kg de riz, pain à la liste courses"
|
||||
(fr-FR) "Complète riz de la liste courses"
|
||||
(fr-FR) "Coche pain de la liste courses"
|
||||
(fr-FR) "Qu'est-ce qu'il y a dans ma liste courses ?"
|
||||
(fr-FR) "Crée une liste films"
|
||||
(fr-FR) "Ajoute Captain America : Guerre Civile à ma liste films"
|
||||
(fr-FR) "Quelles sont mes listes ?"
|
||||
(fr-FR) "Renomme la liste films en cinéma"
|
||||
(fr-FR) "Qu'est-ce qu'il y a dans ma liste cinéma ?"
|
||||
(fr-FR) "Décoche Captain America de ma liste cinéma"
|
||||
(fr-FR) "Montre ma liste cinéma"
|
||||
(fr-FR) "Supprime ma liste cinéma"
|
||||
(fr-FR) "Montre mes listes"
|
||||
```
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"todolist": {
|
||||
"options": {}
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
{
|
||||
"todolist": {
|
||||
"list_created": [
|
||||
"Alright, I've created the \"%list%\" list.",
|
||||
"Done, I created your \"%list%\" list."
|
||||
],
|
||||
"list_not_provided": [
|
||||
"Please provide me a list name.",
|
||||
"Please provide the name of a list."
|
||||
],
|
||||
"todos_not_provided": [
|
||||
"Please provide me items.",
|
||||
"Please provide elements."
|
||||
],
|
||||
"new_or_old_list_not_provided": [
|
||||
"Please make sure you provide the list name to rename and its new list name.",
|
||||
"Please provide the list name to rename and its new list name."
|
||||
],
|
||||
"no_list": [
|
||||
"You do not have any list.",
|
||||
"There is no list to show."
|
||||
],
|
||||
"empty_list": [
|
||||
"Your \"%list%\" list is empty.",
|
||||
"There is nothing in your \"%list%\" list."
|
||||
],
|
||||
"list_does_not_exist": [
|
||||
"Sorry I can't because the \"%list%\" does not exist.",
|
||||
"I cannot do that because the \"%list%\" does not exist."
|
||||
],
|
||||
"list_already_exists": [
|
||||
"You already have a list named \"%list%\"."
|
||||
],
|
||||
"list_renamed": [
|
||||
"I renamed the \"%old_list%\" list to \"%new_list%\"."
|
||||
],
|
||||
"list_deleted": [
|
||||
"I deleted the \"%list%\" list and all the todos it was containing."
|
||||
],
|
||||
"lists_listed": [
|
||||
"You have %lists_nb% lists. Please let me list them for you:<br><br><ul>%result%</ul>"
|
||||
],
|
||||
"list_list_element": [
|
||||
"<li>\"%list%\", with %todos_nb% elements in it.</li>",
|
||||
"<li>\"%list%\", that contains %todos_nb% items.</li>"
|
||||
],
|
||||
"no_unchecked_todo": [
|
||||
"You do not have in progress element in your \"%list%\" list.",
|
||||
"You don't have any in progress element in your \"%list%\" list."
|
||||
],
|
||||
"no_completed_todo": [
|
||||
"And you do not have completed element in your \"%list%\" list.",
|
||||
"And you don't have any completed element in your \"%list%\" list."
|
||||
],
|
||||
"unchecked_todos_listed": [
|
||||
"Here are the in progress elements of your \"%list%\" list:<br><br><ul>%result%</ul><br>Stay motivated!",
|
||||
"Please find the in progress elements of your \"%list%\" list:<br><br><ul>%result%</ul><br>Keep going!"
|
||||
],
|
||||
"completed_todos_listed": [
|
||||
"And here are the completed elements of your \"%list%\" list:<br><br><ul>%result%</ul>"
|
||||
],
|
||||
"list_todo_element": [
|
||||
"<li>%todo%.</li>"
|
||||
],
|
||||
"list_completed_todo_element": [
|
||||
"<li><strike>%todo%</strike>.</li>"
|
||||
],
|
||||
"todos_added": [
|
||||
"Alright, I added the following to your \"%list%\" list:<br><br><ul>%result%</ul>",
|
||||
"The following have been added to your \"%list%\" list:<br><br><ul>%result%</ul>"
|
||||
],
|
||||
"todos_unchecked": [
|
||||
"I unchecked the following from your \"%list%\" list:<br><br><ul>%result%</ul>",
|
||||
"The following have been unchecked from your \"%list%\" list:<br><br><ul>%result%</ul>"
|
||||
],
|
||||
"todos_completed": [
|
||||
"Keep going! I completed the following from your \"%list%\" list:<br><br><ul>%result%</ul>",
|
||||
"Well done! The following have been completed from your \"%list%\" list:<br><br><ul>%result%</ul>"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
{
|
||||
"todolist": {
|
||||
"list_created": [
|
||||
"Entendu, j'ai créé la liste \"%list%\".",
|
||||
"C'est fait, j'ai créé votre liste \"%list%\"."
|
||||
],
|
||||
"list_not_provided": [
|
||||
"Merci de me fournir un nom de liste.",
|
||||
"Merci de fournir le nom d'une liste."
|
||||
],
|
||||
"todos_not_provided": [
|
||||
"Merci de me fournir des éléments.",
|
||||
"Merci de fournir des éléments."
|
||||
],
|
||||
"new_or_old_list_not_provided": [
|
||||
"Merci de vous assurer d'avoir fourni le nom de la liste à renommer et son nouveau nom.",
|
||||
"Merci de fournir le nom de la liste à renommer ainsi que son nouveau nom."
|
||||
],
|
||||
"no_list": [
|
||||
"Je n'ai trouvé aucune liste.",
|
||||
"Il n'y a pas de liste à montrer."
|
||||
],
|
||||
"empty_list": [
|
||||
"Votre liste \"%list%\" est vide.",
|
||||
"Il n'y a rien dans votre liste \"%list%\"."
|
||||
],
|
||||
"list_does_not_exist": [
|
||||
"Désolé je ne peux pas car la liste \"%list%\" n'éxiste pas.",
|
||||
"Je ne peux pas parce que la liste \"%list%\" n'éxiste pas."
|
||||
],
|
||||
"list_already_exists": [
|
||||
"Vous avez déjà une liste nommée \"%list%\"."
|
||||
],
|
||||
"list_renamed": [
|
||||
"J'ai renommé la liste \"%old_list%\" en \"%new_list%\"."
|
||||
],
|
||||
"list_deleted": [
|
||||
"J'ai supprimé la liste \"%list%\" et tous les éléments qu'elle contenait."
|
||||
],
|
||||
"lists_listed": [
|
||||
"Vous avez %lists_nb% listes. Permettez-moi de vous les lister :<br><br><ul>%result%</ul>"
|
||||
],
|
||||
"list_list_element": [
|
||||
"<li>\"%list%\", avec %todos_nb% éléments.</li>",
|
||||
"<li>\"%list%\", contenant %todos_nb% éléments.</li>"
|
||||
],
|
||||
"no_unchecked_todo": [
|
||||
"Vous n'avez pas d'élément en attente dans votre liste \"%list%\".",
|
||||
"Vous n'avez aucun élément en attente dans votre liste \"%list%\"."
|
||||
],
|
||||
"no_completed_todo": [
|
||||
"Et vous n'avez pas d'élément complété dans votre liste \"%list%\".",
|
||||
"Et vous n'avez aucun élément complété dans votre liste \"%list%\"."
|
||||
],
|
||||
"unchecked_todos_listed": [
|
||||
"Voici les éléments en attente de votre liste \"%list%\" :<br><br><ul>%result%</ul><br>Restez motivé !",
|
||||
"Voici les éléments en attente de votre liste \"%list%\" :<br><br><ul>%result%</ul><br>Continuez ainsi !"
|
||||
],
|
||||
"completed_todos_listed": [
|
||||
"Et voici les éléments complétés de votre liste \"%list%\" :<br><br><ul>%result%</ul>"
|
||||
],
|
||||
"list_todo_element": [
|
||||
"<li>%todo%.</li>"
|
||||
],
|
||||
"list_completed_todo_element": [
|
||||
"<li><strike>%todo%</strike>.</li>"
|
||||
],
|
||||
"todos_added": [
|
||||
"Entendu, j'ai ajouté ceci à votre liste \"%list%\" :<br><br><ul>%result%</ul>",
|
||||
"Ce qui suit vient d'être ajouté à votre liste \"%list%\" :<br><br><ul>%result%</ul>"
|
||||
],
|
||||
"todos_unchecked": [
|
||||
"J'ai décomplété ceci de votre liste \"%list%\" :<br><br><ul>%result%</ul>",
|
||||
"Ce qui suit vient d'être décomplété de votre liste \"%list%\" :<br><br><ul>%result%</ul>"
|
||||
],
|
||||
"todos_completed": [
|
||||
"Continue ainsi ! J'ai complété ceci de votre liste \"%list%\" :<br><br><ul>%result%</ul>",
|
||||
"Bien joué ! Ce qui suit vient d'être complété de votre liste \"%list%\" :<br><br><ul>%result%</ul>"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,253 +0,0 @@
|
||||
{
|
||||
"todolist": {
|
||||
"create_list": {
|
||||
"expressions": [
|
||||
"Create the x list",
|
||||
"Create a x list"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "the",
|
||||
"to": "list"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "a",
|
||||
"to": "list"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "an",
|
||||
"to": "list"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "my",
|
||||
"to": "list"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"view_lists": {
|
||||
"expressions": [
|
||||
"Show all the lists",
|
||||
"Show all my lists",
|
||||
"What are the lists?",
|
||||
"What are my lists?"
|
||||
]
|
||||
},
|
||||
"view_list": {
|
||||
"expressions": [
|
||||
"Show my x list",
|
||||
"Show the x list",
|
||||
"What is in my x list?",
|
||||
"What is in the x list?"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "the",
|
||||
"to": "list"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "my",
|
||||
"to": "list"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"rename_list": {
|
||||
"expressions": [
|
||||
"Rename the x list to y",
|
||||
"Rename my x list to y"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "old_list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "the",
|
||||
"to": "list"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "my",
|
||||
"to": "list"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "new_list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "after",
|
||||
"from": "to"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"delete_list": {
|
||||
"expressions": [
|
||||
"Delete the x list",
|
||||
"Delete my x list"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "the",
|
||||
"to": "list"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "my",
|
||||
"to": "list"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"add_todos": {
|
||||
"expressions": [
|
||||
"Add x to the list x",
|
||||
"Add x to my list x"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "todos",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "add",
|
||||
"to": "to"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "the",
|
||||
"to": "list"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "my",
|
||||
"to": "list"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"complete_todos": {
|
||||
"expressions": [
|
||||
"Check x from the x list",
|
||||
"Check x from my x list",
|
||||
"Complete x from my x list",
|
||||
"Tick x from my x list"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "todos",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "check",
|
||||
"to": "from"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "complete",
|
||||
"to": "from"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "tick",
|
||||
"to": "from"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "the",
|
||||
"to": "list"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "my",
|
||||
"to": "list"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"uncheck_todos": {
|
||||
"expressions": [
|
||||
"Uncheck x from the x list",
|
||||
"Uncheck x from my x list",
|
||||
"Untick x from my x list"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "todos",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "uncheck",
|
||||
"to": "from"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "untick",
|
||||
"to": "from"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "the",
|
||||
"to": "list"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "my",
|
||||
"to": "list"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
{
|
||||
"todolist": {
|
||||
"create_list": {
|
||||
"expressions": [
|
||||
"Crée la liste x",
|
||||
"Crée une liste x"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "after_last",
|
||||
"from": "liste"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"view_lists": {
|
||||
"expressions": [
|
||||
"Montre les listes",
|
||||
"Montre mes listes",
|
||||
"Quelles sont les listes ?",
|
||||
"Quelles sont mes listes ?"
|
||||
]
|
||||
},
|
||||
"view_list": {
|
||||
"expressions": [
|
||||
"Montre ma liste x",
|
||||
"Montre la liste x",
|
||||
"Qu'est-ce qu'il y a dans ma liste x ?",
|
||||
"Qu'est-ce qu'il y a dans la liste x ?"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "after_last",
|
||||
"from": "liste"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"rename_list": {
|
||||
"expressions": [
|
||||
"Renomme la liste x en y",
|
||||
"Renomme ma liste x en y"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "old_list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "liste",
|
||||
"to": "en"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "new_list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "after_last",
|
||||
"from": "en"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"delete_list": {
|
||||
"expressions": [
|
||||
"Supprime la liste x",
|
||||
"Supprime ma liste x"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "after_last",
|
||||
"from": "liste"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"add_todos": {
|
||||
"expressions": [
|
||||
"Ajoute x à la liste x",
|
||||
"Ajoute x à ma liste x"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "todos",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "ajoute",
|
||||
"to": "à"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "ajoute",
|
||||
"to": "a"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "after_last",
|
||||
"from": "liste"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"complete_todos": {
|
||||
"expressions": [
|
||||
"Coche x de la liste x",
|
||||
"Coche x de ma liste x",
|
||||
"Complète x de ma liste x"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "todos",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "coche",
|
||||
"to": "de"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "complète",
|
||||
"to": "de"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "complete",
|
||||
"to": "de"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "after_last",
|
||||
"from": "liste"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"uncheck_todos": {
|
||||
"expressions": [
|
||||
"Décoche x de la liste x",
|
||||
"Décoche x de ma liste x",
|
||||
"Invalide x de ma liste x",
|
||||
"Remet x sur la liste x"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "todos",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "between",
|
||||
"from": "décoche",
|
||||
"to": "de"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "decoche",
|
||||
"to": "de"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "invalide",
|
||||
"to": "de"
|
||||
},
|
||||
{
|
||||
"type": "between",
|
||||
"from": "remet",
|
||||
"to": "sur"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "list",
|
||||
"conditions": [
|
||||
{
|
||||
"type": "after_last",
|
||||
"from": "liste"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
describe('calendar:todolist', async () => {
|
||||
test('no list', async () => {
|
||||
global.nlu.brain.execute = jest.fn()
|
||||
await global.nlu.process('Show all my lists')
|
||||
|
||||
const [obj] = global.nlu.brain.execute.mock.calls
|
||||
await global.brain.execute(obj[0])
|
||||
|
||||
expect(global.brain.finalOutput.codes).toIncludeSameMembers(['no_list'])
|
||||
})
|
||||
|
||||
test('adds 3 todos and create a list', async () => {
|
||||
global.nlu.brain.execute = jest.fn()
|
||||
await global.nlu.process('Add 7 potatoes, 1kg of rice, bread to the shopping list')
|
||||
|
||||
const [obj] = global.nlu.brain.execute.mock.calls
|
||||
await global.brain.execute(obj[0])
|
||||
|
||||
expect(global.brain.finalOutput.speech.split('</li>').length - 1).toBe(3)
|
||||
expect(global.brain.finalOutput.speech.indexOf('"shopping" list')).not.toBe(-1)
|
||||
expect(global.brain.finalOutput.codes).toIncludeSameMembers(['todos_added'])
|
||||
})
|
||||
|
||||
test('completes a todo', async () => {
|
||||
global.nlu.brain.execute = jest.fn()
|
||||
await global.nlu.process('Complete rice from my shopping list')
|
||||
|
||||
const [obj] = global.nlu.brain.execute.mock.calls
|
||||
await global.brain.execute(obj[0])
|
||||
|
||||
expect(global.brain.finalOutput.speech.split('</li>').length - 1).toBe(1)
|
||||
expect(global.brain.finalOutput.speech.indexOf('"shopping" list')).not.toBe(-1)
|
||||
expect(global.brain.finalOutput.speech.indexOf('<strike>1kg of rice</strike>')).not.toBe(-1)
|
||||
expect(global.brain.finalOutput.codes).toIncludeSameMembers(['todos_completed'])
|
||||
})
|
||||
|
||||
test('views a list', async () => {
|
||||
global.nlu.brain.execute = jest.fn()
|
||||
await global.nlu.process('What is in my shopping list?')
|
||||
|
||||
const [obj] = global.nlu.brain.execute.mock.calls
|
||||
await global.brain.execute(obj[0])
|
||||
|
||||
expect(global.brain.interOutput.codes).toIncludeSameMembers(['unchecked_todos_listed'])
|
||||
expect(global.brain.interOutput.speech.split('</li>').length - 1).toBe(2)
|
||||
expect(global.brain.interOutput.speech.indexOf('"shopping" list')).not.toBe(-1)
|
||||
expect(global.brain.interOutput.speech.indexOf('7 potatoes')).not.toBe(-1)
|
||||
expect(global.brain.interOutput.speech.indexOf('bread')).not.toBe(-1)
|
||||
expect(global.brain.finalOutput.speech.split('</li>').length - 1).toBe(1)
|
||||
expect(global.brain.finalOutput.speech.indexOf('"shopping" list')).not.toBe(-1)
|
||||
expect(global.brain.finalOutput.speech.indexOf('<strike>1kg of rice</strike>')).not.toBe(-1)
|
||||
expect(global.brain.finalOutput.codes).toIncludeSameMembers([
|
||||
'unchecked_todos_listed',
|
||||
'completed_todos_listed'
|
||||
])
|
||||
})
|
||||
|
||||
test('creates a list', async () => {
|
||||
global.nlu.brain.execute = jest.fn()
|
||||
await global.nlu.process('Create the movies list')
|
||||
|
||||
const [obj] = global.nlu.brain.execute.mock.calls
|
||||
await global.brain.execute(obj[0])
|
||||
|
||||
expect(global.brain.finalOutput.speech.indexOf('"movies" list')).not.toBe(-1)
|
||||
expect(global.brain.finalOutput.codes).toIncludeSameMembers(['list_created'])
|
||||
})
|
||||
|
||||
test('renames a list', async () => {
|
||||
global.nlu.brain.execute = jest.fn()
|
||||
await global.nlu.process('Rename the movies list to cinema')
|
||||
|
||||
const [obj] = global.nlu.brain.execute.mock.calls
|
||||
await global.brain.execute(obj[0])
|
||||
|
||||
expect(global.brain.finalOutput.speech.indexOf('"movies" list')).not.toBe(-1)
|
||||
expect(global.brain.finalOutput.speech.indexOf('to "cinema"')).not.toBe(-1)
|
||||
expect(global.brain.finalOutput.codes).toIncludeSameMembers(['list_renamed'])
|
||||
})
|
||||
|
||||
test('unchecks a todo', async () => {
|
||||
global.nlu.brain.execute = jest.fn()
|
||||
await global.nlu.process('Uncheck rice from the shopping list')
|
||||
|
||||
const [obj] = global.nlu.brain.execute.mock.calls
|
||||
await global.brain.execute(obj[0])
|
||||
|
||||
expect(global.brain.finalOutput.speech.split('</li>').length - 1).toBe(1)
|
||||
expect(global.brain.finalOutput.speech.indexOf('"shopping" list')).not.toBe(-1)
|
||||
expect(global.brain.finalOutput.speech.indexOf('1kg of rice')).not.toBe(-1)
|
||||
expect(global.brain.finalOutput.codes).toIncludeSameMembers(['todo_unchecked'])
|
||||
})
|
||||
|
||||
test('deletes a list', async () => {
|
||||
global.nlu.brain.execute = jest.fn()
|
||||
await global.nlu.process('Delete the cinema list')
|
||||
|
||||
const [obj] = global.nlu.brain.execute.mock.calls
|
||||
await global.brain.execute(obj[0])
|
||||
|
||||
expect(global.brain.finalOutput.speech.indexOf('"cinema" list')).not.toBe(-1)
|
||||
expect(global.brain.finalOutput.codes).toIncludeSameMembers(['list_deleted'])
|
||||
})
|
||||
|
||||
test('views all lists', async () => {
|
||||
global.nlu.brain.execute = jest.fn()
|
||||
await global.nlu.process('Show all my lists')
|
||||
|
||||
const [obj] = global.nlu.brain.execute.mock.calls
|
||||
await global.brain.execute(obj[0])
|
||||
|
||||
expect(global.brain.finalOutput.speech.split('</li>').length - 1).toBe(1)
|
||||
expect(global.brain.finalOutput.speech.indexOf('"shopping"')).not.toBe(-1)
|
||||
expect(global.brain.finalOutput.speech.indexOf('3')).not.toBe(-1)
|
||||
expect(global.brain.finalOutput.codes).toIncludeSameMembers(['lists_listed'])
|
||||
})
|
||||
})
|
||||
@@ -1,349 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
import requests
|
||||
import utils
|
||||
from time import time
|
||||
|
||||
# Package database
|
||||
db = utils.db()['db']
|
||||
|
||||
# Lists of the module table
|
||||
db_lists = db.table('todo_lists')
|
||||
# Todos of the module table
|
||||
db_todos = db.table('todo_todos')
|
||||
|
||||
# Query
|
||||
Query = utils.db()['query']()
|
||||
|
||||
# Time stamp
|
||||
timestamp = int(time())
|
||||
|
||||
def create_list(string, entities):
|
||||
"""Create a to-do list"""
|
||||
|
||||
# List name
|
||||
listname = ''
|
||||
|
||||
# Find entities
|
||||
for item in entities:
|
||||
if item['entity'] == 'list':
|
||||
listname = item['sourceText'].lower()
|
||||
|
||||
# Verify if a list name has been provided
|
||||
if not listname:
|
||||
return utils.output('end', 'list_not_provided', utils.translate('list_not_provided'))
|
||||
|
||||
# Verify if list already exists or not
|
||||
if db_lists.count(Query.name == listname) > 0:
|
||||
return utils.output('end', 'list_already_exists', utils.translate('list_already_exists', { 'list': listname }))
|
||||
|
||||
dbCreateList(listname)
|
||||
|
||||
return utils.output('end', 'list_created', utils.translate('list_created', { 'list': listname }))
|
||||
|
||||
def view_lists(string, entities):
|
||||
"""View to-do lists"""
|
||||
|
||||
# Lists number
|
||||
lists_nb = len(db_lists)
|
||||
|
||||
# Verify if a list exists
|
||||
if lists_nb == 0:
|
||||
return utils.output('end', 'no_list', utils.translate('no_list'))
|
||||
|
||||
result = ''
|
||||
# Fill end-result
|
||||
for listelement in db_lists:
|
||||
result += utils.translate('list_list_element', {
|
||||
'list': listelement['name'],
|
||||
'todos_nb': db_todos.count(Query.list == listelement['name'])
|
||||
})
|
||||
|
||||
return utils.output('end', 'lists_listed', utils.translate('lists_listed', {
|
||||
'lists_nb': lists_nb,
|
||||
'result': result
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
def view_list(string, entities):
|
||||
"""View a to-do list"""
|
||||
|
||||
# List name
|
||||
listname = ''
|
||||
|
||||
# Find entities
|
||||
for item in entities:
|
||||
if item['entity'] == 'list':
|
||||
listname = item['sourceText'].lower()
|
||||
|
||||
# Verify if the list exists
|
||||
if db_lists.count(Query.name == listname) == 0:
|
||||
return utils.output('end', 'list_does_not_exist', utils.translate('list_does_not_exist', { 'list': listname }))
|
||||
|
||||
# Grab todos of the list
|
||||
todos = db_todos.search(Query.list == listname)
|
||||
|
||||
if len(todos) == 0:
|
||||
return utils.output('end', 'empty_list', utils.translate('empty_list', { 'list': listname }))
|
||||
|
||||
unchecked_todos = db_todos.search((Query.list == listname) & (Query.is_completed == False))
|
||||
completed_todos = db_todos.search((Query.list == listname) & (Query.is_completed == True))
|
||||
|
||||
result_unchecked_todos = ''
|
||||
result_completed_todos = ''
|
||||
|
||||
if len(unchecked_todos) == 0:
|
||||
utils.output('inter', 'no_unchecked_todo', utils.translate('no_unchecked_todo', { 'list': listname }))
|
||||
else:
|
||||
for todo in unchecked_todos:
|
||||
result_unchecked_todos += utils.translate('list_todo_element', {
|
||||
'todo': todo['name']
|
||||
})
|
||||
|
||||
utils.output('inter', 'unchecked_todos_listed', utils.translate('unchecked_todos_listed', {
|
||||
'list': listname,
|
||||
'result': result_unchecked_todos
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
if len(completed_todos) == 0:
|
||||
return utils.output('end', 'no_completed_todo', utils.translate('no_completed_todo', { 'list': listname }))
|
||||
|
||||
for todo in completed_todos:
|
||||
result_completed_todos += utils.translate('list_completed_todo_element', {
|
||||
'todo': todo['name']
|
||||
})
|
||||
|
||||
return utils.output('end', 'completed_todos_listed', utils.translate('completed_todos_listed', {
|
||||
'list': listname,
|
||||
'result': result_completed_todos
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
def rename_list(string, entities):
|
||||
"""Rename a to-do list"""
|
||||
|
||||
# Old list name
|
||||
old_listname = ''
|
||||
|
||||
# New list name
|
||||
new_listname = ''
|
||||
|
||||
# Find entities
|
||||
for item in entities:
|
||||
if item['entity'] == 'old_list':
|
||||
old_listname = item['sourceText'].lower()
|
||||
elif item['entity'] == 'new_list':
|
||||
new_listname = item['sourceText'].lower()
|
||||
|
||||
# Verify if an old and new list name have been provided
|
||||
if not old_listname or not new_listname:
|
||||
return utils.output('end', 'new_or_old_list_not_provided', utils.translate('new_or_old_list_not_provided'))
|
||||
|
||||
# Verify if the old list exists
|
||||
if db_lists.count(Query.name == old_listname) == 0:
|
||||
return utils.output('end', 'list_does_not_exist', utils.translate('list_does_not_exist', { 'list': old_listname }))
|
||||
|
||||
# Verify if the new list name already exists
|
||||
if db_lists.count(Query.name == new_listname) > 0:
|
||||
return utils.output('end', 'list_already_exists', utils.translate('list_already_exists', { 'list': new_listname }))
|
||||
|
||||
# Rename the to-do list
|
||||
db_lists.update({
|
||||
'name': new_listname,
|
||||
'updated_at': int(time())
|
||||
}, Query.name == old_listname)
|
||||
# Rename the list name of the todos
|
||||
db_todos.update({
|
||||
'list': new_listname,
|
||||
'updated_at': int(time())
|
||||
}, Query.list == old_listname)
|
||||
|
||||
return utils.output('end', 'list_renamed', utils.translate('list_renamed', {
|
||||
'old_list': old_listname,
|
||||
'new_list': new_listname
|
||||
}))
|
||||
|
||||
def delete_list(string, entities):
|
||||
"""Delete a to-do list"""
|
||||
|
||||
# List name
|
||||
listname = ''
|
||||
|
||||
# Find entities
|
||||
for item in entities:
|
||||
if item['entity'] == 'list':
|
||||
listname = item['sourceText'].lower()
|
||||
|
||||
# Verify if a list name has been provided
|
||||
if not listname:
|
||||
return utils.output('end', 'list_not_provided', utils.translate('list_not_provided'))
|
||||
|
||||
# Verify if the list exists
|
||||
if db_lists.count(Query.name == listname) == 0:
|
||||
return utils.output('end', 'list_does_not_exist', utils.translate('list_does_not_exist', { 'list': listname }))
|
||||
|
||||
# Delete the to-do list
|
||||
db_lists.remove(Query.name == listname)
|
||||
# Delete todos of that to-do list
|
||||
db_todos.remove(Query.list == listname)
|
||||
|
||||
return utils.output('end', 'list_deleted', utils.translate('list_deleted', { 'list': listname }))
|
||||
|
||||
def add_todos(string, entities):
|
||||
"""Add todos to a to-do list"""
|
||||
|
||||
# List name
|
||||
listname = ''
|
||||
|
||||
# Todos
|
||||
todos = []
|
||||
|
||||
# Find entities
|
||||
for item in entities:
|
||||
if item['entity'] == 'list':
|
||||
listname = item['sourceText'].lower()
|
||||
elif item['entity'] == 'todos':
|
||||
# Split todos into array and trim start/end-whitespaces
|
||||
todos = [chunk.strip() for chunk in item['sourceText'].lower().split(',')]
|
||||
|
||||
# Verify if a list name has been provided
|
||||
if not listname:
|
||||
return utils.output('end', 'list_not_provided', utils.translate('list_not_provided'))
|
||||
|
||||
# Verify todos have been provided
|
||||
if len(todos) == 0:
|
||||
return utils.output('end', 'todos_not_provided', utils.translate('todos_not_provided'))
|
||||
|
||||
# Verify the list exists
|
||||
if db_lists.count(Query.name == listname) == 0:
|
||||
# Create the new to-do list
|
||||
dbCreateList(listname)
|
||||
|
||||
result = ''
|
||||
for todo in todos:
|
||||
# Add to-do to DB
|
||||
dbCreateTodo(listname, todo)
|
||||
result += utils.translate('list_todo_element', { 'todo': todo })
|
||||
|
||||
return utils.output('end', 'todos_added', utils.translate('todos_added', {
|
||||
'list': listname,
|
||||
'result': result
|
||||
}))
|
||||
|
||||
def complete_todos(string, entities):
|
||||
"""Complete todos"""
|
||||
|
||||
# List name
|
||||
listname = ''
|
||||
|
||||
# Todos
|
||||
todos = []
|
||||
|
||||
# Find entities
|
||||
for item in entities:
|
||||
if item['entity'] == 'list':
|
||||
listname = item['sourceText'].lower()
|
||||
elif item['entity'] == 'todos':
|
||||
# Split todos into array and trim start/end-whitespaces
|
||||
todos = [chunk.strip() for chunk in item['sourceText'].lower().split(',')]
|
||||
|
||||
# Verify if a list name has been provided
|
||||
if not listname:
|
||||
return utils.output('end', 'list_not_provided', utils.translate('list_not_provided'))
|
||||
|
||||
# Verify todos have been provided
|
||||
if len(todos) == 0:
|
||||
return utils.output('end', 'todos_not_provided', utils.translate('todos_not_provided'))
|
||||
|
||||
# Verify the list exists
|
||||
if db_lists.count(Query.name == listname) == 0:
|
||||
# Create the new to-do list
|
||||
dbCreateList(listname)
|
||||
|
||||
result = ''
|
||||
for todo in todos:
|
||||
for db_todo in db_todos.search(Query.list == listname):
|
||||
# Rough matching (e.g. 1kg of rice = rice)
|
||||
if db_todo['name'].find(todo) != -1:
|
||||
db_todos.update({
|
||||
'is_completed': True,
|
||||
'updated_at': timestamp
|
||||
}, (Query.list == listname) & (Query.name == db_todo['name']))
|
||||
|
||||
result += utils.translate('list_completed_todo_element', { 'todo': db_todo['name'] })
|
||||
|
||||
return utils.output('end', 'todos_completed', utils.translate('todos_completed', {
|
||||
'list': listname,
|
||||
'result': result
|
||||
}))
|
||||
|
||||
def uncheck_todos(string, entities):
|
||||
"""Uncheck todos"""
|
||||
|
||||
# List name
|
||||
listname = ''
|
||||
|
||||
# Todos
|
||||
todos = []
|
||||
|
||||
# Find entities
|
||||
for item in entities:
|
||||
if item['entity'] == 'list':
|
||||
listname = item['sourceText'].lower()
|
||||
elif item['entity'] == 'todos':
|
||||
# Split todos into array and trim start/end-whitespaces
|
||||
todos = [chunk.strip() for chunk in item['sourceText'].lower().split(',')]
|
||||
|
||||
# Verify if a list name has been provided
|
||||
if not listname:
|
||||
return utils.output('end', 'list_not_provided', utils.translate('list_not_provided'))
|
||||
|
||||
# Verify todos have been provided
|
||||
if len(todos) == 0:
|
||||
return utils.output('end', 'todos_not_provided', utils.translate('todos_not_provided'))
|
||||
|
||||
# Verify if the list exists
|
||||
if db_lists.count(Query.name == listname) == 0:
|
||||
return utils.output('end', 'list_does_not_exist', utils.translate('list_does_not_exist', { 'list': listname }))
|
||||
|
||||
result = ''
|
||||
for todo in todos:
|
||||
for db_todo in db_todos.search(Query.list == listname):
|
||||
# Rough matching (e.g. 1kg of rice = rice)
|
||||
if db_todo['name'].find(todo) != -1:
|
||||
db_todos.update({
|
||||
'is_completed': False,
|
||||
'updated_at': timestamp
|
||||
}, (Query.list == listname) & (Query.name == db_todo['name']))
|
||||
|
||||
result += utils.translate('list_todo_element', { 'todo': db_todo['name'] })
|
||||
|
||||
return utils.output('end', 'todo_unchecked', utils.translate('todos_unchecked', {
|
||||
'list': listname,
|
||||
'result': result
|
||||
}))
|
||||
|
||||
def dbCreateList(listname):
|
||||
"""Create list in DB"""
|
||||
|
||||
db_lists.insert({
|
||||
'name': listname,
|
||||
'created_at': timestamp,
|
||||
'updated_at': timestamp
|
||||
})
|
||||
|
||||
def dbCreateTodo(listname, todoname):
|
||||
"""Create to-todo in list DB table"""
|
||||
|
||||
db_todos.insert({
|
||||
'list': listname,
|
||||
'name': todoname,
|
||||
'is_completed': False,
|
||||
'created_at': timestamp,
|
||||
'updated_at': timestamp
|
||||
})
|
||||
@@ -1 +0,0 @@
|
||||
1.0.0
|
||||
@@ -1,45 +0,0 @@
|
||||
# Checker Package
|
||||
|
||||
The checker package contains modules which include checkings.
|
||||
|
||||
## Modules
|
||||
|
||||
### Is it Down
|
||||
|
||||
Ping domain names and give you the online state.
|
||||
|
||||
#### Usage
|
||||
|
||||
```
|
||||
(en-US) "Are github.com, an-awesome-domain-name.net and twitter.com down?"
|
||||
|
||||
(fr-FR) "Vérifies si github.com, un-super-nom-de-domaine.fr et twitter.com sont en ligne"
|
||||
...
|
||||
```
|
||||
|
||||
### Have I Been Pwned
|
||||
|
||||
Verify if one or several email addresses have been pwned (thanks to [Have I Been Pwned](https://haveibeenpwned.com/).
|
||||
|
||||
#### Usage
|
||||
|
||||
1. Since the API v3, you must [claim your API key](https://haveibeenpwned.com/API/Key).
|
||||
2. Then paste it in `packages/checker/config/config.json` at the `haveibeenpwned.api_key` key.
|
||||
|
||||
```
|
||||
(en-US) "Has louis.grenard@gmail.com been pwned?"
|
||||
(en-US) "Have iifeoluwa.ao@gmail.com, louis.grenard@gmail.com, and supercleanemail@test.com been pwned?"
|
||||
|
||||
(fr-FR) "Est-ce que louis.grenard@gmail.com est compromis ?"
|
||||
(fr-FR) "Est-ce que iifeoluwa.ao@gmail.com, louis.grenard@gmail.com, et supercleanemail@test.com ont été compromis ?"
|
||||
```
|
||||
|
||||
You can also predefine one or several email addresses in the `packages/checker/config/config.json` file at the `haveibeenpwned.emails` key.
|
||||
|
||||
If you do, then you can use such sentences:
|
||||
|
||||
```
|
||||
(en-US) "Have my email addresses been pwned?"
|
||||
|
||||
(fr-FR) "Est-ce que mes adresses email ont été compromises ?"
|
||||
```
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"isitdown": {
|
||||
"options": {}
|
||||
},
|
||||
"haveibeenpwned": {
|
||||
"api_key": "YOUR_API_KEY",
|
||||
"emails": [],
|
||||
"options": {}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
{
|
||||
"isitdown": {
|
||||
"up": [
|
||||
"%website_name% is running correctly.",
|
||||
"%website_name% is working correctly.",
|
||||
"%website_name% is up."
|
||||
],
|
||||
"down": [
|
||||
"%website_name% is not running correctly.",
|
||||
"%website_name% is having troubles.",
|
||||
"%website_name% is down."
|
||||
],
|
||||
"checking": [
|
||||
"I'm checking %website_name% state.",
|
||||
"I'm trying to reach %website_name%.",
|
||||
"I am now requesting %website_name%."
|
||||
],
|
||||
"errors": [
|
||||
"There is an issue with the HTTP request for %website_name%. Please verify your local network or if the domain name is correct.",
|
||||
"Bad news, the HTTP request is having troubles for %website_name%. You should check if the domain name is valid."
|
||||
],
|
||||
"invalid_domain_name": [
|
||||
"Please provide me at least one valid domain name.",
|
||||
"You did not gave me a valid domain name."
|
||||
]
|
||||
},
|
||||
"haveibeenpwned": {
|
||||
"no-pwnage": [
|
||||
"Great news, \"%email%\" hasn't been compromised in a data breach.",
|
||||
"\"%email%\" looks good to me!"
|
||||
],
|
||||
"pwned": [
|
||||
"Oops, looks like \"%email%\" has been compromised in at least one breach involving:<br><br><ul>%result%</ul>",
|
||||
"Sadly, \"%email%\" was affected in the following breaches:<br><br><ul>%result%</ul>",
|
||||
"Unfortunately, \"%email%\" has been exposed in a data breach affecting:<br><br><ul>%result%</ul>"
|
||||
],
|
||||
"list_element": [
|
||||
"<li><a href=\"%url%\" target=\"_blank\">%name%</a> with a total of %total% accounts.</li>"
|
||||
],
|
||||
"checking": [
|
||||
"I'm checking for a compromised email...",
|
||||
"Trying to verify pwnage status..."
|
||||
],
|
||||
"no-email": [
|
||||
"Please provide one or more email addresses you need me to check."
|
||||
],
|
||||
"errors": [
|
||||
"I think %website_name% is down at the moment, please try again later.",
|
||||
"I'm having trouble reaching %website_name%. Please check that your internet connection is active.",
|
||||
"Bad news, %website_name% is not responding. Maybe try at a later time?"
|
||||
],
|
||||
"blocked": [
|
||||
"There was an issue accessing %website_name%'s service.",
|
||||
"Unfortunate news, %website_name% isn't granting me access to its service."
|
||||
],
|
||||
"unavailable": [
|
||||
"It looks like Cloudflare is defending %website_name%, please retry in a few moments.",
|
||||
"Unfortunately, Cloudflare is temporarily blocking your access to %website_name%, please retry in a while."
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
{
|
||||
"isitdown": {
|
||||
"up": [
|
||||
"%website_name% tourne correctement.",
|
||||
"%website_name% fonctionne correctement.",
|
||||
"%website_name% est en ligne."
|
||||
],
|
||||
"down": [
|
||||
"%website_name% ne tourne pas correctement.",
|
||||
"%website_name% rencontre des difficultés.",
|
||||
"%website_name% est hors ligne."
|
||||
],
|
||||
"checking": [
|
||||
"Je suis en train de vérifier l'état de %website_name%.",
|
||||
"J'essaye d'atteindre %website_name%.",
|
||||
"Je suis maintenant en train de requêter %website_name%."
|
||||
],
|
||||
"errors": [
|
||||
"Il y a un problème avec la requête HTTP pour %website_name%. Merci de vérifier votre réseau local ou de vérifier si le nom de domaine est correct.",
|
||||
"Mauvaise nouvelle, la requête HTTP rencontre des problèmes pour %website_name%. Vous devriez vérifier si le nom de domaine est valide."
|
||||
],
|
||||
"invalid_domain_name": [
|
||||
"Merci de fournir au moins un nom de domaine valide.",
|
||||
"Vous ne m'avez pas donné de nom de domaine valide."
|
||||
]
|
||||
},
|
||||
"haveibeenpwned": {
|
||||
"no-pwnage": [
|
||||
"Bonne nouvelle, %email% n'a pas été compromis par une violation de données.",
|
||||
"%email% cela me semble correct!"
|
||||
],
|
||||
"pwned": [
|
||||
"Oups, on dirait que %email% a été compromis par une infraction impliquant %breach%.",
|
||||
"%breach% a été impliqué dans une brèche. Malheureusement, %email% a été touché.",
|
||||
"Malheureusement, %email% a été exposé à une violation de données affectant %breach%."
|
||||
],
|
||||
"checking": [
|
||||
"Je cherche un email compromis.",
|
||||
"Essayer de vérifier le statut de pwnage."
|
||||
],
|
||||
"no-email": [
|
||||
"Veuillez fournir une ou plusieurs adresses électroniques que vous devez vérifier..."
|
||||
],
|
||||
"errors": [
|
||||
"Je pense que %website_name% est en panne pour le moment, veuillez réessayer plus tard.",
|
||||
"J'ai du mal à joindre %website_name%. Veuillez vérifier que votre connexion Internet est active.",
|
||||
"Mauvaise nouvelle, %website_name% ne répond pas. Peut-être essayer plus tard?"
|
||||
],
|
||||
"blocked": [
|
||||
"Il y avait un problème d'accès au service de %website_name%.",
|
||||
"Malheureusement, %website_name% ne me donne pas accès à son service."
|
||||
],
|
||||
"unavailable": [
|
||||
"Il semblerait que Cloudflare protège %website_name%, veuillez réessayer dans un petit instant.",
|
||||
"Malheureusement, Cloudflare a temporairement bloqué votre accès à %website_name%, merci de retenter dans un moment."
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
{
|
||||
"isitdown": {
|
||||
"run": {
|
||||
"expressions": [
|
||||
"Is getleon.ai up?",
|
||||
"Is mozilla.org down?",
|
||||
"Is mozilla.org up or down?",
|
||||
"Is github.com up?",
|
||||
"Is github.com down?",
|
||||
"Check if github.com is up or down",
|
||||
"Check if github.com is down",
|
||||
"Check if github.com is up",
|
||||
"Check if nodejs.org is down",
|
||||
"Check if nodejs.org is up",
|
||||
"Check if nodejs.org is working",
|
||||
"Check if amazon.com is up or down"
|
||||
]
|
||||
}
|
||||
},
|
||||
"haveibeenpwned": {
|
||||
"run": {
|
||||
"expressions": [
|
||||
"Has iifeoluwa.ao@gmail.com been pwned?",
|
||||
"Has iifeoluwa.ao@gmail.com been compromised?",
|
||||
"Has iifeoluwa.ao@gmail.com been exposed in a breach?",
|
||||
"Is iifeoluwa.ao@gmail.com still uncompromised?",
|
||||
"Is iifeoluwa.ao@gmail.com compromised?",
|
||||
"Have my email address been pwned?",
|
||||
"Check that iifeoluwa.ao@gmail.com and louis.grenard@gmail.com haven't been compromised",
|
||||
"Check that iifeoluwa.ao@gmail.com and louis.grenard@gmail.com haven't been pwned",
|
||||
"Check that iifeoluwa.ao@gmail.com and louis.grenard@gmail.com haven't been exposed in a breach",
|
||||
"Verify the pwnage status of iifeoluwa.ao@gmail.com",
|
||||
"Verify the pwnage status of iifeoluwa.ao@gmail.com and louis.grenard@gmail.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
{
|
||||
"isitdown": {
|
||||
"run": {
|
||||
"expressions": [
|
||||
"Est-ce que getleon.ai est en ligne ?",
|
||||
"Est-ce que mozilla.org est hors ligne ?",
|
||||
"mozilla.org est en ligne ou hors ligne ?",
|
||||
"github.com en ligne ?",
|
||||
"github.com hors ligne ?",
|
||||
"Vérifie si github.com en ligne ou hors ligne",
|
||||
"Vérifie si github.com hors ligne",
|
||||
"Vérifie si github.com en ligne",
|
||||
"Vérifie si nodejs.org hors ligne",
|
||||
"Vérifie si nodejs.org en ligne",
|
||||
"Vérifie si nodejs.org fonctionne",
|
||||
"Vérifie si amazon.com en ligne ou hors ligne"
|
||||
]
|
||||
}
|
||||
},
|
||||
"haveibeenpwned": {
|
||||
"run": {
|
||||
"expressions": [
|
||||
"iifeoluwa.ao@gmail.com a-t-elle été pwned ?",
|
||||
"iifeoluwa.ao@gmail.com a-t-elle été compromise ?",
|
||||
"iifeoluwa.ao@gmail.com a-t-elle été exposée à une brèche ?",
|
||||
"iifeoluwa.ao@gmail.com est-elle toujours non compromise ?",
|
||||
"Est-ce que iifeoluwa.ao@gmail.com est compromise ?",
|
||||
"Est-ce que mon adresse email a été compromise ?",
|
||||
"Vérifie que iifeoluwa.ao@gmail.com et louis.grenard@gmail.com n'ont pas été compromise",
|
||||
"Vérifie que iifeoluwa.ao@gmail.com et louis.grenard@gmail.com n'ont pas été pwned",
|
||||
"Vérifie que iifeoluwa.ao@gmail.com et louis.grenard@gmail.com n'ont pas été exposées à une brèche"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user