Compare commits

...

707 Commits

Author SHA1 Message Date
louistiti 754bd7380f build(bridge/python): 1.2.0 2023-11-14 22:38:34 +08:00
louistiti d32cda3663 build(bridge/nodejs): 1.1.0 2023-11-14 22:35:27 +08:00
louistiti c8d2e8c985 chore: bump to 1.0.0-beta.10+dev 2023-11-12 22:22:56 +08:00
louistiti 2a15434919 Merge branch 'feat-improve-ner-types' into develop 2023-11-12 18:16:37 +08:00
louistiti b2c375861b feat: identify entities from utterance samples for a better prioritization of classifications 2023-11-12 18:14:16 +08:00
Théo LUDWIG ae6fec335d fix(skill/date_time): add follow up utterance samples 2023-07-24 23:00:30 +02:00
louistiti 16302ec6e4 Merge branch 'develop' into feat-improve-ner-types 2023-07-23 11:26:38 +08:00
Louis Grenard 4d03e1bb4e docs(README): add knowledge base LLM scenario 2023-07-23 11:15:23 +08:00
Théo LUDWIG 69ce669b4c feat(tcp server): remove unnecessary data from entity + detect most populated city 2023-07-02 11:09:22 +02:00
Théo LUDWIG c512b422e7 feat(web app): add "Show more" when answer is "too big" 2023-07-01 23:33:41 +02:00
Théo LUDWIG 2ad6541c3e feat(skill/help): helps you get started with Leon 2023-07-01 23:28:55 +02:00
Théo LUDWIG 379326d7c1 feat(bridge/nodejs): simplify leon.setAnswerData 2023-07-01 23:24:29 +02:00
Théo LUDWIG 1359f5d210 feat(bridge/python): simplify leon.set_answer_data 2023-07-01 23:23:34 +02:00
Théo LUDWIG 64858ec6fe feat(tcp server): add Country information to City 2023-07-01 19:01:57 +02:00
Théo LUDWIG 166175192d feat(tcp server): better detect cities thanks to alternate names 2023-07-01 19:00:34 +02:00
Théo LUDWIG 97de1d1c3f fix(skill/date_time): correct time zone with toLocaleString method 2023-07-01 18:24:19 +02:00
louistiti 563792bd0a fix(tcp server): use root path for the time_zones.txt file 2023-06-30 22:35:58 +08:00
Théo LUDWIG 076db4c3eb fix(skill/date_time): determine correctly isDaylightSavingTime 2023-06-30 15:11:17 +02:00
Théo LUDWIG 02e1de8ffa fix: precise units used in time zone data 2023-06-29 23:14:14 +02:00
Théo LUDWIG cc01bd18b2 feat(skill/date_time): time zone 2023-06-29 23:03:03 +02:00
Théo LUDWIG 2478adbaa2 feat(server): add spacy data in entity resolution 2023-06-29 22:33:25 +02:00
Théo LUDWIG 45b177d0fb feat(tcp server): add support for time zone and more city/country data 2023-06-29 22:32:12 +02:00
Théo LUDWIG c0deafcd69 feat(server): improve NER types 2023-06-29 00:04:37 +02:00
louistiti eea6b0392d feat(skill/date_time): add new utterance samples 2023-06-29 00:17:29 +08:00
louistiti 9845612c68 Merge branch 'feat/skill-utilities-date-time' into develop 2023-06-28 23:39:25 +08:00
louistiti d46ec1d3d5 Merge branch 'feat/skill-leon-age' into develop 2023-06-28 23:39:15 +08:00
louistiti f1a65f53bc feat(skill/age): add new utterance samples 2023-06-28 23:39:07 +08:00
Théo LUDWIG 1410b72362 chore(skill/date_time): add test folder 2023-06-27 18:35:03 +02:00
Théo LUDWIG e9245b522f fix(skill/date_time): separate current date and current time 2023-06-25 22:46:10 +02:00
Théo LUDWIG 636eb0f139 feat(skill/date_time): days countdown 2023-06-25 12:27:30 +02:00
Théo LUDWIG 8645ef01fd fix: improve types for Node.js skill SDK 2023-06-25 12:08:36 +02:00
Théo LUDWIG 18867bde89 fix(server): improve json schema description for skill config 2023-06-25 12:07:41 +02:00
Théo LUDWIG d061a6c4bf feat(skill/date_time): get current week number of the year 2023-06-24 19:57:47 +02:00
Théo LUDWIG e2ec76275a feat(skill/date_time): get current date and time 2023-06-24 19:30:55 +02:00
Théo LUDWIG 767bace201 feat(skill/age): ask Leon his age 2023-06-24 13:23:19 +02:00
louistiti e70d0a0029 feat(web app): add init messages 2023-05-30 23:52:35 +08:00
louistiti 595fe78679 Merge branch 'python-sdk' into develop 2023-05-29 22:55:36 +08:00
louistiti 69cb6a610f build(bridge/nodejs): bump to 1.0.0 2023-05-29 22:01:32 +08:00
louistiti 10a03d90e3 build(bridge/python): bump to 1.1.0 2023-05-29 22:01:06 +08:00
louistiti 251950384e refactor(server): rename obj to skillAnswer 2023-05-28 12:53:44 +08:00
louistiti 8c91d245e8 refactor(server): remove speech prop from skill output backward compatibility 2023-05-28 12:49:56 +08:00
louistiti df343ce94f fix(skill/akinator): typo ShowNextActionSuggestions to showNextActionSuggestions 2023-05-28 10:12:40 +08:00
louistiti 7c73f435af fix(skill/akinator): disable urllib3 cert warning 2023-05-28 10:07:23 +08:00
louistiti b5ef7242af fix(skill/have_i_been_pwned): use current_entities instead of entities 2023-05-28 09:23:50 +08:00
Divlo 16e1f7a34a chore: remove dead code 2023-05-28 01:32:57 +02:00
Divlo e42a54d593 refactor(skill/akinator): usage of new SDK 2023-05-28 01:10:03 +02:00
Divlo cd3bcd5d6e refactor(server): leon over http with /api/utterance 2023-05-28 00:31:40 +02:00
Divlo 2ea6237b1f chore: remove /api/downloads 2023-05-27 23:53:20 +02:00
Divlo 9782526c42 chore: remove legacy Python bridge/utils 2023-05-27 23:48:39 +02:00
Divlo 3bf7150387 refactor(skill/have_i_been_pwned): usage of new SDK 2023-05-27 23:34:15 +02:00
Divlo c00c85fd4f fix(bridge): better types and network error 2023-05-27 20:29:01 +02:00
Divlo a76d05f68a refactor(skill/product_hunt_trends): usage of new SDK 2023-05-27 20:21:03 +02:00
Divlo f17a4d3a2a refactor(skill/github_trends): usage of new SDK 2023-05-27 18:06:31 +02:00
Divlo 850ea46ec6 style(skill/mbti): add missing space for consistency (oops) 2023-05-27 12:54:16 +02:00
Divlo a540307241 refactor(skill/mbti): usage of new SDK 2023-05-27 12:43:19 +02:00
Divlo e440e4f715 refactor(skill/speed_test): usage of new SDK 2023-05-27 12:00:13 +02:00
louistiti d1fe81ddc6 refactor: modify settings method from isAlreadySet to isSettingSet 2023-05-27 09:47:09 +08:00
louistiti 3648fef5fb refactor(bridge/python): add key to settings.isAlreadySet 2023-05-27 09:00:00 +08:00
louistiti 1f9137bb20 refactor(bridge/nodejs): add key to setting.isAlreadySet 2023-05-27 08:47:24 +08:00
louistiti 2e6abef507 chore: lint 2023-05-27 08:06:11 +08:00
louistiti a55fbcd532 fix: ignore error if skill.json isn't found when getting skill info 2023-05-27 08:05:22 +08:00
Divlo 924317c614 refactor(skill/is_it_down): usage of new SDK 2023-05-27 00:14:51 +02:00
Divlo 0c44916aa2 chore(bridge): add comments (jsdoc/docstring) for settings 2023-05-26 23:50:36 +02:00
Divlo 2a0cc0644e chore: remove youtube_downloader skill 2023-05-26 23:34:37 +02:00
Divlo 4f5b385fd7 chore: rename config.json to settings.json 2023-05-26 23:31:25 +02:00
Divlo 30e405bbe3 feat(bridge/python): add Settings module 2023-05-26 23:03:02 +02:00
Divlo 8c105a043d feat(bridge/nodejs): add Settings module 2023-05-26 23:01:54 +02:00
Divlo 99b5e7ab6d chore: remove synchronization capability 2023-05-26 22:58:26 +02:00
Divlo b9dbc5012c Revert "chore: add __init__.py files to avoid mypy linting error"
This reverts commit 0b16eebfbd.
2023-05-26 10:12:43 +02:00
Divlo 0b16eebfbd chore: add __init__.py files to avoid mypy linting error
Ref: https://github.com/python/mypy/issues/8686#issuecomment-1178977365
2023-05-25 22:56:38 +02:00
Divlo c078505846 refactor(skill/todo_list): usage of new SDK 2023-05-25 22:47:58 +02:00
Divlo 421232a6dc refactor(skills): usage of datetime ISO 8601 string format instead of timestamp 2023-05-25 19:05:51 +02:00
louistiti c62368ddad chore: comments and French punctuation 2023-05-25 08:34:20 +08:00
Divlo f956e1abc6 fix(bridge): memory path always defined 2023-05-25 01:04:28 +02:00
Divlo dc88ac244d perf(skill/guess_the_number): only store one game at a time to avoid increasing the size of memory unnecessarily 2023-05-25 00:38:34 +02:00
Divlo 4cd01a4baf refactor(skill/random_number): usage of new SDK 2023-05-25 00:12:59 +02:00
Divlo 06cda4a1f0 fix(bridge/nodejs): allow memory that stores null value 2023-05-25 00:04:25 +02:00
Divlo dc7615723d fix(bridge/python): allow memory that stores null value 2023-05-24 23:57:44 +02:00
Divlo 14275be5f7 refactor(skill/introduction): usage of new SDK 2023-05-24 23:57:18 +02:00
Divlo 158df2f0f1 refactor(skill/greeting): usage of new SDK 2023-05-24 23:57:05 +02:00
Divlo 6bed516f89 refactor(skill/rochambeau): usage of new SDK 2023-05-24 23:22:43 +02:00
Divlo 7e72928ad6 refactor(skill/guess_the_number): usage of new SDK 2023-05-24 23:10:14 +02:00
louistiti 4a7e77141e refactor: remove Python shebangs 2023-05-24 20:32:43 +08:00
louistiti 25ab60e5a2 feat: add Leon user agent from bridges 2023-05-24 19:53:34 +08:00
Divlo f8e6012cbe fix(bridge/python): add types 2023-05-23 19:50:19 +02:00
louistiti 1c5d2874b0 refactor(bridge/python): add memory comments 2023-05-23 21:37:12 +08:00
louistiti 3449c14d47 feat(bridge/python): functional memory 2023-05-23 21:27:35 +08:00
louistiti 51f57e3255 feat(bridge/python): memory write method 2023-05-23 20:10:48 +08:00
louistiti 7fd4be1248 feat(bridge/python): memory read method 2023-05-23 20:09:09 +08:00
louistiti 3b77d64d4f feat(bridge/python): memory clear method 2023-05-23 20:06:35 +08:00
louistiti ab7e2a9b10 refactor(bridge/nodejs): remove Aurora index file 2023-05-22 22:54:00 +08:00
louistiti b2e4ebf1be feat(bridge/python): support widget answer 2023-05-22 22:17:53 +08:00
louistiti 3c9a210081 feat(bridge/python): leon.answer usage 2023-05-22 21:14:52 +08:00
louistiti 7a9068283b refactor(bridge/python): new bridge main file 2023-05-22 20:32:36 +08:00
louistiti 66dc0aab0f feat(skill/timekeeper): boilerplate 2023-05-22 20:18:13 +08:00
Divlo 91e48af263 feat(bridge/python): add Network module (WIP) 2023-05-21 23:20:58 +02:00
louistiti 3a230633d8 feat(bridge/python): memory kick off 2023-05-21 19:12:30 +08:00
louistiti 6c3a03d16a feat(bridge/python): add widget class 2023-05-21 19:03:54 +08:00
louistiti 8a60b3d0d3 Merge branch 'python-sdk-fixes' into python-sdk 2023-05-21 18:51:42 +08:00
Divlo cb3d3bf5a8 fix(bridge/nodejs): add lang to action params 2023-05-20 20:34:12 +02:00
Divlo f3257ad7b0 style(bridge/python): format with autopep8 2023-05-20 20:33:37 +02:00
Divlo cb29848f45 fix(bridge/python): better typings 2023-05-20 19:49:56 +02:00
Divlo ebaa3c4f9b fix(bridge/python): inconsistent indentation TabError 2023-05-20 19:49:07 +02:00
louistiti de17719537 feat(bridge/python): typing (WIP) 2023-05-20 23:28:44 +08:00
louistiti 47d5a48ac9 fix(bridge/python): import INTENT_OBJECT to leon 2023-05-20 23:17:42 +08:00
louistiti e8ceed62eb feat(bridge/python): leon.answer 2023-05-20 23:16:50 +08:00
louistiti bbc1f8a79c feat(bridge/python): leon.set_answer_data 2023-05-20 23:09:45 +08:00
louistiti 289efb5610 feat(bridge/python): leon.get_src_config 2023-05-20 22:49:17 +08:00
louistiti 05a4b2c773 feat(bridge/python): Leon singleton 2023-05-20 22:42:30 +08:00
louistiti a32ad86342 feat(bridge/python): add constants 2023-05-20 22:40:38 +08:00
louistiti a2eacc3930 fix(server): add lang back to the intent object till Python bridge is updated 2023-05-19 22:09:01 +08:00
louistiti a8c079fd5c feat: provide built-in context data to skills 2023-05-19 21:47:23 +08:00
louistiti b389bdd8c6 feat(server): provide sentiment analysis to NLU result 2023-05-19 21:40:24 +08:00
louistiti 750d1de8b4 chore: merge branch 'skill-text-n-speech-difference' into develop 2023-05-18 21:14:09 +08:00
louistiti d295105fa6 chore: disable import/order ESLint rule for skills 2023-05-18 21:06:04 +08:00
louistiti e2899c8d9a refactor(skill/good_bye): rollback as speech/text answer is only supported in logic skills 2023-05-18 20:38:26 +08:00
louistiti 7f9b60a6cd feat(server): differentiate skill text answer from speech answer (WIP) 2023-05-18 00:00:40 +08:00
louistiti 9e77953976 refactor(bridge/nodejs): use AnswerConfig type from core schema 2023-05-17 22:21:11 +08:00
louistiti cb6462b749 feat: define new skill answer format 2023-05-17 18:31:39 +08:00
Louis Grenard 07a3b1701d docs: update README.md 2023-05-16 23:14:02 +08:00
Louis Grenard f6300a3fb8 docs: update README.md 2023-05-16 23:14:02 +08:00
louistiti 46299ef4eb Merge branch 'skill-widget-ideas' into develop 2023-05-16 23:08:00 +08:00
louistiti 259dc53213 Merge branch 'skill-widget-ideas' into develop 2023-05-16 23:08:00 +08:00
louistiti 51152a0fe3 refactor(bridge/nodejs): protected memory constructor 2023-05-16 23:07:12 +08:00
louistiti 01305af669 refactor(bridge/nodejs): protected memory constructor 2023-05-16 23:07:12 +08:00
Divlo 5539130dd9 fix: typo missing "GB" for Free RAM 2023-05-15 23:42:27 +02:00
Divlo efd1061f30 fix: typo missing "GB" for Free RAM 2023-05-15 23:42:27 +02:00
Divlo f6a501d4e1 fix(bridge/nodejs): improve Memory types with external skill memory 2023-05-15 22:58:40 +02:00
Divlo 839c7bfc3c fix(bridge/nodejs): improve Memory types with external skill memory 2023-05-15 22:58:40 +02:00
Divlo d3ba85cb36 feat(bridge/nodejs): add Widget abstract class 2023-05-15 21:18:54 +02:00
Divlo 623039415a feat(bridge/nodejs): add Widget abstract class 2023-05-15 21:18:54 +02:00
louistiti 7a75c985e0 Merge branch 'skill-widget-poc' into develop 2023-05-15 21:31:02 +08:00
louistiti 0f2a579a66 refactor(web app): remove original app rendering 2023-05-15 21:30:42 +08:00
louistiti 63573083fa feat(web app): render widget 2023-05-15 21:25:20 +08:00
louistiti 34aa188643 feat: skill -> core -> client widget support 2023-05-15 01:13:18 +08:00
louistiti 76dfe72f5f feat(web app): kick off Aurora structure 2023-05-15 00:00:21 +08:00
louistiti 7a31158497 feat(web app): set up React 2023-05-14 23:43:42 +08:00
louistiti 96145bb2f7 feat(web app): add vite React plugin 2023-05-14 23:23:17 +08:00
louistiti 17cb808aab chore: install required npm deps 2023-05-14 23:22:01 +08:00
louistiti b757d2d4ae chore: upgrade vite to latest 2023-05-14 23:20:41 +08:00
louistiti ce001c2e65 feat(bridge/nodejs): support read memory from other skills 2023-05-14 21:00:52 +08:00
louistiti a3b8c40714 refactor(scripts): unify skills setup over one iteration only 2023-05-14 12:10:55 +08:00
louistiti 0283878a90 refactor(bridge/nodejs): force run to be the skill action entry point 2023-05-14 09:15:05 +08:00
louistiti 3ed19bd6d0 Merge branch 'nodejs-bridge-memory' into develop 2023-05-14 08:58:28 +08:00
louistiti c163f5971c feat(bridge/nodejs): sync return new memory value on write 2023-05-14 08:58:19 +08:00
louistiti 6a01e1e743 Merge branch 'nodejs-bridge-improvements' into nodejs-bridge-memory 2023-05-14 08:52:03 +08:00
louistiti b06eab9107 style(bridge/nodejs): memory exception/error renaming 2023-05-14 08:51:52 +08:00
Divlo 12ce47b937 fix(bridge/nodejs): usage of getleon.ai to try network available 2023-05-14 00:39:56 +02:00
Divlo c8fc0068d1 feat(bridge/nodejs): improvements to memory 2023-05-14 00:39:30 +02:00
louistiti e32bf370db Merge branch 'nodejs-bridge-memory' into develop 2023-05-14 00:11:10 +08:00
louistiti 9ef4f234b8 Merge branch 'develop' into nodejs-bridge-memory 2023-05-14 00:08:18 +08:00
louistiti 6d2292f508 fix(server): pre-check add process.cwd() to all constant paths 2023-05-14 00:06:43 +08:00
louistiti b897ae160f feat(bridge/nodejs): simple get / set memory 2023-05-13 23:52:54 +08:00
louistiti a51d92bf08 refactor(bridge/nodejs): remove Prisma 2023-05-13 19:04:54 +08:00
louistiti 6d495cf43c refactor(scripts): explicit Node.js bridge npm packages install 2023-05-13 00:30:15 +08:00
louistiti d6933a9e35 refactor(bridge/nodejs): remove lowdb and tiny custom ORM in favor of Prisma 2023-05-13 00:26:51 +08:00
louistiti 127a10f8ed feat(scripts): install Node.js bridge npm packages on setup 2023-05-12 23:54:57 +08:00
louistiti ef223a2901 feat(bridge/nodejs): make use of Prisma from skill action (PoC) 2023-05-11 23:39:17 +08:00
louistiti 9a06c64a5d feat(bridge/nodejs): Prisma SQLite setup 2023-05-11 23:26:42 +08:00
louistiti ad5edb5ad5 feat(bridge/nodejs): support nested props find in memory 2023-05-11 22:30:22 +08:00
louistiti ee0b080522 feat(bridge/nodejs): support updateOne memory method 2023-05-11 21:50:29 +08:00
louistiti be04b10645 feat(bridge/nodejs): support findMany memory method 2023-05-11 21:41:51 +08:00
louistiti ab62a65e57 feat(bridge/nodejs): support findOne memory method 2023-05-11 21:40:22 +08:00
louistiti 99ac5f18c8 feat(bridge/nodejs): give public access to Low instance 2023-05-11 21:21:26 +08:00
louistiti 87a7077854 refactor(bridge/nodejs): rename create with createOne 2023-05-11 21:04:18 +08:00
louistiti af2a124165 refactor(bridge/nodejs): rename insert to create 2023-05-11 20:59:26 +08:00
louistiti 8e55c481d4 feat(bridge/nodejs): support insertMany memory method 2023-05-11 20:51:19 +08:00
louistiti d7b814761f feat(bridge/nodejs): tiny ORM kick off 2023-05-11 20:49:40 +08:00
louistiti 4dde49e545 feat(bridge/nodejs): memory database pattern (WIP) 2023-05-10 23:29:41 +08:00
Divlo 34b29d0e61 fix(bridge/nodejs): memory ESM dynamic imports 2023-05-10 00:45:21 +02:00
louistiti 954126315f refactor(bridge/nodejs): TSConfig ESM NCC 2023-05-09 21:48:07 +08:00
louistiti e240a2db3c feat(bridge/nodejs): memory ESM debugging (WIP) 2023-05-09 21:39:18 +08:00
louistiti 4abb68c1b3 Merge branch 'nodejs-bridge' into develop 2023-05-08 22:05:42 +08:00
louistiti 3ea1a3666b feat(bridge/nodejs): add isNetworkAvailable network method 2023-05-08 22:03:30 +08:00
louistiti d3e0810298 fix(bridge/nodejs): temporize data buffer on output 2023-05-08 22:01:46 +08:00
louistiti ef6d46cf8e refactor(scripts): remove cmd output on install Node.js skills packages 2023-05-08 21:57:41 +08:00
louistiti e65ecd5b67 fix(scripts): install Node.js skills packages timestamp comparison 2023-05-08 21:45:06 +08:00
louistiti 5946a00427 feat(scripts): skill package install/uninstall package script 2023-05-08 21:35:14 +08:00
louistiti 6b239ae38b style(scripts): fix linting 2023-05-08 21:24:26 +08:00
louistiti 224158812f feat(scripts): install Node.js skills packages 2023-05-08 21:23:33 +08:00
Divlo ee9794cd9f Revert "feat(bridge/nodejs): add leon.getVersions"
This reverts commit ec819e1765.
2023-05-08 10:58:31 +02:00
Divlo ad497d36c3 style: fix linting 2023-05-07 21:44:55 +02:00
Divlo 5eb62ddcf5 chore: add leon-nodejs-bridge as local dependency 2023-05-07 21:43:03 +02:00
Divlo ec819e1765 feat(bridge/nodejs): add leon.getVersions 2023-05-07 21:38:09 +02:00
louistiti 2c2f49290a Merge branch 'nodejs-bridge' into develop 2023-05-07 21:28:28 +08:00
louistiti f936652007 Merge branch 'nodejs-bridge-improvements' into nodejs-bridge 2023-05-07 21:26:12 +08:00
Divlo 950985ca86 feat(bridge/nodejs): finish network implementation 2023-05-07 15:07:20 +02:00
louistiti 8147d8423b feat(scripts): add Node.js bridge on check script 2023-05-07 20:09:37 +08:00
louistiti 3f556494c2 Merge branch 'nodejs-bridge-improvements' into nodejs-bridge 2023-05-07 19:07:05 +08:00
Divlo 426c816ca4 build(bridge/nodejs): avoid installing dependencies each time we build 2023-05-07 01:14:44 +02:00
louistiti dd0eab51b6 Merge branch 'HEAD' into nodejs-bridge 2023-05-06 22:47:36 +08:00
Divlo 07e253f663 build(bridge/nodejs): usage of ncc 2023-05-06 15:38:49 +02:00
Divlo de08807f1a feat(bridge/nodejs): add Network module (WIP) 2023-05-06 14:21:24 +02:00
Divlo 2cb030f47b fix(bridge/nodejs): usage of types from server/core/brain/types 2023-05-06 14:03:56 +02:00
Divlo 673cf0426f fix(bridge/nodejs): build error 2023-05-06 13:55:43 +02:00
louistiti e89b5b0ea3 refactor(bridge/nodejs): isolate types from bridge 2023-05-06 18:26:22 +08:00
Divlo 6b76e6a102 fix(bridge/nodejs): stricter leon.getSRCConfig types 2023-05-05 20:24:01 +02:00
Divlo 1625aaf3cd fix(bridge/nodejs): typings improvements 2023-05-05 20:00:51 +02:00
louistiti b65cfb70d6 feat(bridge/nodejs): final answer bridge 2023-05-05 21:21:27 +08:00
louistiti 89a6c04a1e refactor(bridge/nodejs): new answer types (WIP) 2023-05-05 00:34:16 +08:00
louistiti e42655a5ff refactor(server): remove skill answer type complexity 2023-05-04 22:34:29 +08:00
louistiti c9678fe34f refactor(bridge/python): flush standard output every time 2023-05-04 21:40:11 +08:00
louistiti 8349e41205 feat(bridge/nodejs): answers 2023-05-03 23:28:12 +08:00
louistiti 759e67ac40 fix(bridge/nodejs): SDK mapping 2023-05-03 16:02:57 +08:00
louistiti fc1fa56eab Merge branch 'develop' into nodejs-bridge 2023-05-03 14:54:51 +08:00
louistiti 8f5bd3a9a5 feat: add free RAM check 2023-05-03 14:54:23 +08:00
louistiti a836a7cc8c feat(bridge/nodejs): resolve SDK mapping 2023-05-03 09:27:23 +08:00
louistiti 2df22770e0 refactor(bridge/nodejs): SDK mapping 2023-05-03 08:39:06 +08:00
louistiti 9b839d3e66 feat(bridge/nodejs): first draft 2023-05-02 23:53:41 +08:00
louistiti 2e3796642d refactor(server): send heartbeat every 6 hours instead 2023-05-02 16:43:04 +08:00
louistiti b027905ed0 refactor(bridge/nodejs): package.json new dist entry point path 2023-05-01 23:01:46 +08:00
louistiti 4c9dfe667b build(bridge/nodejs): bump 0.0.1-alpha.0 2023-05-01 22:49:32 +08:00
louistiti ed215feb81 refactor(scripts): Node.js bridge bin dist 2023-05-01 22:48:31 +08:00
louistiti cd82a3a11b chore: bump to 1.0.0-beta.9+dev 2023-05-01 10:23:19 +08:00
louistiti b7a4f69565 build: release 1.0.0-beta.8 2023-05-01 10:09:29 +08:00
louistiti 7b8a324658 fix(server): catch error on start for telemetry client 2023-05-01 01:54:19 +08:00
louistiti 59cfded2bb feat(server): send Node.js bridge version to telemetry 2023-05-01 01:26:28 +08:00
louistiti 8dc8c05d7d refactor(scripts): add bin level for Node.js bridge 2023-05-01 01:13:19 +08:00
louistiti 0e4ec4fb97 refactor(scripts): exclude current Node.js bridge archive from new archive 2023-05-01 00:49:35 +08:00
louistiti bb00677568 feat(scripts): add build for Node.js bridge 2023-05-01 00:36:03 +08:00
louistiti 308b63f576 fix(scripts): tmp setup Node.js bridge removal 2023-04-30 23:49:21 +08:00
louistiti 40819e8e17 feat(bridge/nodejs): release process 2023-04-30 23:39:39 +08:00
louistiti 0fba50905f feat(bridge/nodejs): entry point build 2023-04-30 21:36:07 +08:00
louistiti 419bfe3d78 refactor(scripts): commit-msg scopes 2023-04-30 20:35:56 +08:00
louistiti 1847248f12 feat: add instanceID on check script 2023-04-30 10:45:51 +08:00
louistiti eed4a9597c refactor(server): get Node.js version from process.versions.node 2023-04-30 10:32:01 +08:00
louistiti c3452d2170 feat(server): add minimum RAM requirement on pre-check 2023-04-30 10:31:18 +08:00
louistiti 0a14567776 refactor: round up total RAM on check script 2023-04-30 10:13:41 +08:00
louistiti 71573b78d1 refactor: instance ID log on postinstall 2023-04-29 21:04:29 +08:00
louistiti 722dba875b feat: do not download binaries if the latest version is already installed 2023-04-29 20:58:10 +08:00
louistiti 593419639e refactor: naming 2023-04-27 20:24:16 +08:00
louistiti 8b2f06e305 feat(server): bootstrap Node.js bridge entry point 2023-04-27 20:16:08 +08:00
louistiti 12e4b7bccf ci: use ubuntu-20.04 for the draft-release job 2023-04-26 23:00:01 +08:00
louistiti 63a6c2d161 ci: force ubuntu-20.04 and npm install as there is no package-lock.json anymore 2023-04-26 22:49:54 +08:00
louistiti f0e898e3c0 ci: remove npm caching 2023-04-26 22:45:34 +08:00
louistiti 10bb4af4dc build: bump Python bridge to 1.0.1 2023-04-26 22:35:48 +08:00
louistiti 1af3fc2011 style: better info message on prompt false for pre release binaries 2023-04-26 22:34:47 +08:00
louistiti 781cb072a3 fix: use version.py to prompt version bump confirmation on pre-release binaries 2023-04-26 22:33:10 +08:00
louistiti 73fe21f02e Merge branch 'fix-python-bridge-requests-certs' into develop 2023-04-26 22:24:44 +08:00
louistiti 0947bd7877 fix(server): close error log file handler 2023-04-26 21:31:12 +08:00
Divlo 07d2a41ecb fix(python bridge): include requests.certs file 2023-04-23 22:32:43 +02:00
louistiti 9a66b677e0 feat(server): sanitize current OS profile session name on telemetry error 2023-04-23 22:14:06 +08:00
louistiti fe580cfb92 feat: sanitize current OS profile session name for better privacy 2023-04-23 22:12:19 +08:00
louistiti 075f4458a0 feat(server): support isGitpod telemetry 2023-04-22 23:51:08 +08:00
louistiti 094b1218e6 refactor(server): replace HAS_LOGGER by IS_TELEMETRY_ENABLED for the Telemetry service 2023-04-18 20:09:42 +08:00
louistiti b16475766a fix(server): create errors.log if it does not exist before parsing logs 2023-04-18 09:21:05 +08:00
louistiti e5fdeba50b fix(server): ensure the errors.log file exist before reporting errors 2023-04-18 09:05:35 +08:00
louistiti 12b0fe6525 Merge branch 'telemetry' into develop 2023-04-16 16:46:58 +08:00
louistiti 302e1e11e0 feat(server): switch telemetry to production mode 2023-04-16 16:46:51 +08:00
louistiti 8d5bca0d2b refactor(server): handle telemetry on NLU edge cases 2023-04-16 15:36:59 +08:00
louistiti 994cca7bf4 refactor: do not call any core singletons during setup 2023-04-15 00:32:28 +08:00
louistiti a03afa78be refactor(server): telemetry utterance less parameters 2023-04-13 22:44:28 +08:00
louistiti a1f93a6922 fix(server): await for logical skill execution 2023-04-13 22:20:06 +08:00
louistiti 2678f6f04a feat(server): add isProduction data to telemetry 2023-04-13 00:41:02 +08:00
louistiti 03acb35e84 feat(server): complete telemetry client 2023-04-13 00:11:23 +08:00
louistiti 337854ab02 feat: kick off telemetry client 2023-04-12 00:25:40 +08:00
louistiti 19c569b76a Merge branch 'develop' into telemetry 2023-04-11 22:39:50 +08:00
louistiti 5b4cd9da81 Merge branch 'feat/better-json-schemas-developer-experience' into develop 2023-04-11 20:20:07 +08:00
louistiti 40069ab5f0 feat(server): kick off telemetry 2023-04-10 22:35:37 +08:00
Divlo 8c89cbf43c Merge branch 'develop' into feat/better-json-schemas-developer-experience 2023-04-05 00:13:34 +02:00
louistiti 5061cac591 Merge branch 'http-server-refactoring' into develop 2023-04-04 23:09:49 +08:00
louistiti f660506d98 chore(server): add TODO for HTTP API skills routes 2023-04-04 23:08:54 +08:00
louistiti 25f81d3c3c Merge branch 'refactor/fastify-api' into http-server-refactoring 2023-04-04 23:03:03 +08:00
Divlo d261967920 refactor(server): http-server with over http enabled 2023-04-03 20:58:02 +02:00
Divlo 907fb1a129 Merge branch 'http-server-refactoring' into refactor/fastify-api 2023-04-03 19:19:21 +02:00
Divlo 7d63108e8d fix(server): async hooks http-server 2023-04-03 19:12:54 +02:00
louistiti 274d7d52fd refactor(server): remove legacy server/src/tts/tts.js 2023-04-03 23:26:52 +08:00
louistiti d815ab8bff refactor(server): socket server interfaces 2023-04-03 23:24:54 +08:00
louistiti 35da3a388a refactor(server): socket server typing 2023-04-03 23:22:07 +08:00
Divlo a29296c612 refactor(server): api and plugins for http-server 2023-04-03 17:20:00 +02:00
louistiti b93180a822 fix(server): ASR not getting ready 2023-04-03 23:04:18 +08:00
louistiti 9fa0c2e1ba chore: re-enable linter on commit 2023-04-03 22:29:21 +08:00
louistiti 2115054de6 Merge branch 'refactor/fs-promises' into http-server-refactoring 2023-04-03 21:59:20 +08:00
louistiti f167f64cfb fix: simultaneous skills execution; Akinator new step 0 2023-04-03 21:55:36 +08:00
Divlo abc6b21df2 fix: make cleanActiveContext synchronous 2023-04-03 08:33:45 +02:00
Divlo bd66bb5cb7 refactor: usage of fs.promises 2023-04-02 20:34:50 +02:00
Divlo c49f931da4 style: fix linting 2023-04-02 19:18:15 +02:00
louistiti 070f0e1469 refactor(server): change HTTP server props accessiblity 2023-04-02 19:11:37 +08:00
louistiti bf4806c987 refactor(server): finish NLU typing 2023-04-02 18:42:00 +08:00
louistiti 37e5ca0e87 refactor(server): simpler error handler from the NLU action execution 2023-04-02 18:04:25 +08:00
louistiti a6011e3cc6 refactor(server): NLP.js process raw type 2023-04-02 18:00:10 +08:00
louistiti 44882129a7 refactor(server): NLU default values 2023-04-02 16:56:53 +08:00
louistiti 8282c37a5a refactor(server): slot filling 2023-03-27 22:23:10 +08:00
louistiti 26ff4520c8 refactor(server): action loop 2023-03-27 22:09:32 +08:00
louistiti e2f0df2cb6 refactor(server): unify join path 2023-03-27 21:51:40 +08:00
louistiti 7259ceda59 refactor(server): unify skill config getter 2023-03-27 21:42:33 +08:00
louistiti 7f99372130 Merge branch 'develop' into http-server-refactoring 2023-03-26 18:52:19 +08:00
Louis Grenard 0cbd438a34 docs: question LLMs to large language models 2023-03-26 10:23:11 +08:00
Louis Grenard 71b30a7f97 docs: add current state to the README 2023-03-26 10:21:22 +08:00
louistiti bfdc60fa65 refactor(server): slot filling 2023-03-22 23:54:58 +08:00
louistiti 99af936803 refactor(server): action loop 2023-03-22 23:34:39 +08:00
louistiti d41e960373 refactor(server): brain types 2023-03-22 22:31:42 +08:00
louistiti ae04ba369c refactor(server): NLP conversation 2023-03-22 22:19:29 +08:00
louistiti afff309d43 refactor(server): skillConfigPath naming unification 2023-03-22 22:08:35 +08:00
louistiti 16c25c9036 chore: upgrade async to latest 2023-03-20 23:46:27 +08:00
louistiti cd551197ea chore: upgrade Fastify to latest 2023-03-20 23:37:55 +08:00
louistiti f6077d58f1 chore: upgrade to TypeScript 5+ 2023-03-20 23:35:07 +08:00
louistiti eb026cb74a refactor(server): move some NER methods from NLU to NER 2023-03-20 23:15:26 +08:00
louistiti 7d6698df17 refactor(server): NLU method accessibility 2023-03-20 22:45:11 +08:00
louistiti a215fc8770 refactor(server): default NLU result 2023-03-20 22:35:44 +08:00
louistiti a8e3fb8b87 refactor(server): NER 2023-03-20 22:04:04 +08:00
louistiti 6820501da6 refactor(server): remove JavaScript NER and NLU 2023-03-20 21:22:33 +08:00
louistiti b51bf4b1c2 refactor(server): model loader error handling 2023-03-20 20:52:42 +08:00
louistiti 5369da1734 refactor(server): models loader 2023-03-18 10:47:44 +08:00
louistiti d5d8d56124 refactor(server): brain done 2023-03-15 22:30:22 +08:00
louistiti fbcc089e2b refactor(server): brain options 2023-03-07 23:22:35 +08:00
louistiti 76dacb4f5e refactor(server): brain logic action skill execution 2023-03-07 22:20:40 +08:00
louistiti 24ec0f0927 refactor(server): start brain refactoring 2023-03-05 23:07:34 +08:00
louistiti b8aac89c4d refactor(server): brain NLU result renaming 2023-03-04 06:48:04 +08:00
louistiti 72a4f787a3 refactor(server): brain typing done 2023-02-25 09:32:11 +08:00
louistiti 137032b1c0 refactor(server): fix brain answers types 2023-02-25 08:46:23 +08:00
louistiti 5011d906e7 chore: more comment and remove socket server legacy comments 2023-02-21 00:15:42 +08:00
louistiti 35d171e421 chore: comment for what to do next 2023-02-21 00:11:32 +08:00
louistiti 20e7a98241 refactor(server): continue brain typing 2023-02-21 00:00:14 +08:00
louistiti abf811f2e4 refactor(server): handle skill result in brain 2023-02-20 22:58:15 +08:00
louistiti 4d7c49e1ee refactor(server): load models and init core instances only once 2023-02-20 21:56:22 +08:00
louistiti e182da0048 refactor(server): remove unecessary socket connections 2023-02-20 20:26:38 +08:00
louistiti f81255aa20 refactor(server): better STT/TTS logs 2023-02-20 20:31:42 +08:00
louistiti 7aaca4dfc8 refactor(server): only keep types file at the first-node level 2023-02-20 00:30:17 +08:00
louistiti 4a74ee030a refactor(server): BrainProcessResult action; nextAction type to skill config schema action [string] 2023-02-20 00:09:38 +08:00
louistiti 7c76e538ab refactor(server): define BrainProcessResult and refactor schema types naming 2023-02-20 00:07:42 +08:00
louistiti 87ed70d313 refactor(server): define NLUSlot 2023-02-19 23:15:34 +08:00
louistiti 98bb70bee6 refactor(server): define SkillOutputType 2023-02-19 20:56:35 +08:00
louistiti a77f0e2473 refactor(server): implement all NER entity types 2023-02-19 20:48:48 +08:00
louistiti 03b128a544 chore: new ESLint rules for TypeScript 2023-02-19 00:02:15 +08:00
louistiti 9c6a60f92c refactor(server): set SkillConfig actions type in brain 2023-02-18 23:49:10 +08:00
louistiti 311923255e fix(server): fail when first execute a dialog action 2023-02-18 19:51:56 +08:00
louistiti cb77b4fc95 refactor(server): get correct audio duration from TTS 2023-02-18 19:16:26 +08:00
louistiti 4883d7723b refactor(server): synthesizers and parsers debug (tmp) 2023-02-13 23:57:29 +08:00
louistiti eb72a61bad refactor(server): brain tmp 2023-02-12 23:21:19 +08:00
louistiti 6dfeb6480f chore: add save-exact npm option to install exact packages version 2023-02-11 19:35:15 +08:00
louistiti 51f9a29679 chore: lock all deps 2023-02-11 11:36:08 +08:00
louistiti d51bf36566 refactor(server): NLU and brain kick off (tmp) 2023-02-10 22:18:56 +08:00
louistiti 9c9f944350 refactor(server): switch from brain instance within NLU to singleton brain 2023-02-09 21:15:49 +08:00
louistiti 7b557da549 refactor(server): NLP.js TS declarations + NLU kick off 2023-02-09 21:01:33 +08:00
louistiti 849749b900 refactor(server): add lang to TTS init 2023-02-07 22:41:02 +08:00
louistiti 528da32d03 refactor(server): STT parser abstract class 2023-02-07 22:36:59 +08:00
louistiti 9ef7476267 refactor(server): Watson synthesizer + synthesizer abstract class 2023-02-07 22:21:42 +08:00
louistiti 0f897942fa refactor(server): remove already-refactored synthesizers 2023-02-07 21:55:14 +08:00
louistiti 885f3738fc refactor(server): TTS Google Cloud synthesizer 2023-02-07 21:35:27 +08:00
louistiti ab0d88accf refactor(server): add STT parser parent class 2023-02-07 21:30:47 +08:00
louistiti 1146322196 refactor(server): TTS Flite synthesizer + synthesizer parent class 2023-02-07 21:26:14 +08:00
louistiti 157e28a063 Merge remote-tracking branch 'origin/develop' into http-server-refactoring 2023-02-03 00:18:56 +08:00
louistiti c8bc9ecbb0 refactor(server): HTTP server; brain entries; STT parsers; TTS synthesizers (WIP) 2023-02-03 00:14:23 +08:00
Louis Grenard 18ba094647 docs: add sponsor to README.md 2023-01-31 23:22:31 +08:00
Divlo 31e44cde37 fix(server): improve schemas by adding descriptions 2023-01-06 22:20:55 +01:00
Divlo 248dbb84f0 chore: add $schema property to all JSON files 2023-01-06 21:48:35 +01:00
Divlo 609fb676e4 feat(server): pre-check validate $schema property 2023-01-06 21:48:14 +01:00
Divlo 5d866664b2 fix(server): remove additionalProperties in schemas to allow $schema property 2023-01-06 21:18:27 +01:00
Divlo ba09ef10b1 feat: add generate:json-schemas script 2023-01-06 21:18:19 +01:00
louistiti 19ce6eb9c2 refactor(server): socket server and brain (WIP) 2022-11-20 23:21:06 +08:00
louistiti 934689ecf7 chore: merge branch 'develop' into http-server-refactoring 2022-11-19 21:15:35 +08:00
louistiti 2f56a14d68 chore: delete package-lock.json file due to @ffmpeg-installer/ffmpeg optionalDependencies binaries 2022-11-19 21:14:36 +08:00
louistiti cc05ce3d76 chore: format pre-check 2022-11-19 21:13:00 +08:00
louistiti 5959b43e0a chore: upgrade TypeScript to latest 2022-11-19 21:12:43 +08:00
louistiti b9a6ee08fe refactor(server): split socket server (WIP) 2022-11-19 20:57:45 +08:00
louistiti b1739bbe6b Merge branch 'develop' into http-server-refactoring 2022-11-14 23:57:41 +08:00
louistiti cad6d7f725 Merge branch 'feat/add-typebox-ajv' into develop 2022-11-14 23:56:08 +08:00
louistiti a08ddb2e26 Merge branch 'develop' into feat/add-typebox-ajv 2022-11-14 23:56:03 +08:00
louistiti c7aa84f9c4 docs: remove sponsor 2022-11-14 23:50:58 +08:00
louistiti ec10030951 refactor: modify voice config samples default values 2022-11-14 23:49:44 +08:00
louistiti b298667e3d Merge branch 'docs/fix-contributing-python-environment' into develop 2022-11-14 23:41:13 +08:00
louistiti 69e90c3b5f refactor(server): HTTP server and structure (wip) 2022-11-14 00:49:24 +08:00
Divlo 2ada7f2efa docs: make clear that commands should be run on Ubuntu in CONTRIBUTING to set up the Python Environment 2022-11-13 13:41:51 +01:00
Divlo 28c15885fd fix: improve error display in pre-check 2022-11-13 13:36:54 +01:00
Divlo 194a9b1bbb fix: add http_api property to skill config schema
http_api is used by `skills/news/github_trends/config/en.json`.
2022-11-13 13:08:32 +01:00
Divlo 4ce9676319 fix: include voice configuration sample schemas 2022-11-13 13:02:51 +01:00
Divlo fb75b40fb6 feat: validate JSON Schemas with AJV 2022-11-13 13:00:15 +01:00
Divlo d973ab4318 chore: delete schemas.ts files outside server 2022-11-13 12:48:43 +01:00
Divlo f8b08f38b1 fix: stricter JSON Schemas
- Type.Strict()
- Type.Object({ additionalProperties: false })
- Type.String({ format: 'email' | 'uri' })
2022-11-13 12:46:31 +01:00
louistiti b3b10e326f refactor(server): prepare upcoming core singletons registration 2022-11-13 01:12:20 +08:00
louistiti efe865a4c5 refactor(server): reorganize TCP client accessors 2022-11-13 00:40:14 +08:00
louistiti a37ac96411 refactor(server): protect TCP client from mutability 2022-11-13 00:16:53 +08:00
louistiti 8a16a3d97e refactor(server): LEON_NODE_ENV constant 2022-11-12 23:20:48 +08:00
louistiti 3d9d9496b7 fix(server): reset connection state and connection counter 2022-11-12 23:09:22 +08:00
louistiti 862112ed5f refactor(server): TCP client connect method 2022-11-12 22:51:47 +08:00
louistiti ea76739d88 refactor(server): TCP client to singleton 2022-11-12 22:31:49 +08:00
louistiti c53feba8f5 chore: latest package-lock.json 2022-11-12 10:00:22 +08:00
louistiti 62d511f967 chore: merge 2022-11-12 09:48:14 +08:00
louistiti 664359158e chore: merge 2022-11-12 09:46:50 +08:00
louistiti 8ecde83b89 refactor(server): TCP client to TypeScript 2022-11-11 23:32:33 +08:00
louistiti 420f87daca docs: add contributing guide for the Python bridge and TCP server 2022-11-11 22:54:28 +08:00
louistiti c722050aec refactor: add types to schemas object on pre-checking 2022-11-11 22:27:47 +08:00
louistiti c434b550a5 Merge branch 'feat/add-typebox-ajv' into develop 2022-11-11 21:50:55 +08:00
louistiti 06a2adf62b feat: add pre-checking for all JSON configs 2022-11-11 21:43:24 +08:00
louistiti bb0cf69659 feat: add pre-checking for all JSON configs 2022-11-11 11:43:24 +08:00
louistiti e50fadd142 Merge branch 'develop' into feat/add-typebox-ajv 2022-11-08 20:59:25 +08:00
louistiti 327cbff184 Merge branch 'develop' into feat/add-typebox-ajv 2022-11-08 20:59:25 +08:00
louistiti 62853a340f feat: add total RAM data to the checking script 2022-11-08 20:10:46 +08:00
louistiti 86852a8cac feat: add total RAM data to the checking script 2022-11-08 20:10:46 +08:00
louistiti efc94a2ac3 Merge branch 'develop' into feat/add-typebox-ajv 2022-11-06 23:13:49 +08:00
louistiti fd4f429b86 Merge branch 'develop' into feat/add-typebox-ajv 2022-11-06 23:13:49 +08:00
louistiti f5404920fa Merge branch 'develop' into feat/add-typebox-ajv 2022-11-06 23:13:49 +08:00
louistiti a0d8c7251c refactor: add full intent object path on skill execution during checking 2022-11-06 22:25:39 +08:00
louistiti 303ebea3f3 refactor: add full intent object path on skill execution during checking 2022-11-06 22:25:39 +08:00
louistiti c38012afcf refactor: add full intent object path on skill execution during checking 2022-11-06 22:25:39 +08:00
louistiti becac3b0f6 fix(server): Python bridge fails to execute on Windows intent object absolute path because of whitespace 2022-11-06 22:18:09 +08:00
louistiti 0245712e24 fix(server): Python bridge fails to execute on Windows intent object absolute path because of whitespace 2022-11-06 22:18:09 +08:00
louistiti 4b003a852e fix(server): Python bridge fails to execute on Windows intent object absolute path because of whitespace 2022-11-06 22:18:09 +08:00
louistiti ddf389ffd1 chore: add Python bridge npm script 2022-11-06 21:57:04 +08:00
louistiti 1d59b0a774 chore: add Python bridge npm script 2022-11-06 21:57:04 +08:00
louistiti 74582899a2 chore: add Python bridge npm script 2022-11-06 21:57:04 +08:00
louistiti 8a91dcb85d refactor(web app): minor style improvements 2022-11-05 23:33:15 +08:00
louistiti 8fbc4bb23f refactor(web app): minor style improvements 2022-11-05 23:33:15 +08:00
louistiti 61d31d9b52 refactor(web app): minor style improvements 2022-11-05 23:33:15 +08:00
louistiti a81e536fd5 refactor(web app): adapt new Vite config 2022-11-05 23:17:18 +08:00
louistiti 25fdaeeab2 refactor(web app): adapt new Vite config 2022-11-05 23:17:18 +08:00
louistiti c4885cb324 refactor(web app): adapt new Vite config 2022-11-05 23:17:18 +08:00
Divlo 71e0f1933c refactor: domain, skill-config and skill in skills/schemas.ts 2022-11-01 21:51:19 +01:00
Divlo 65246dc7cd refactor: domain, skill-config and skill in skills/schemas.ts 2022-11-01 21:51:19 +01:00
Divlo 32fd041495 refactor: domain, skill-config and skill in skills/schemas.ts 2022-11-01 21:51:19 +01:00
louistiti 6c292994fd feat: add data schemas 2022-11-02 00:21:14 +08:00
louistiti 6e8c326a9c feat: add data schemas 2022-11-02 00:21:14 +08:00
louistiti a4e9b1e1cc feat: add data schemas 2022-11-02 00:21:14 +08:00
louistiti 29d7f16b2c feat: add voice configuration schemas 2022-11-01 22:09:52 +08:00
louistiti e3c0a180af feat: add voice configuration schemas 2022-11-01 22:09:52 +08:00
louistiti 360c4d4f6f feat: add voice configuration schemas 2022-11-01 22:09:52 +08:00
louistiti 1a580d1051 Merge branch 'develop' into feat/add-typebox-ajv 2022-11-01 21:45:50 +08:00
louistiti f13df6ab76 Merge branch 'develop' into feat/add-typebox-ajv 2022-11-01 21:45:50 +08:00
louistiti 239472b61e Merge branch 'develop' into feat/add-typebox-ajv 2022-11-01 21:45:50 +08:00
Louis Grenard 83c501dc8d docs: add new sponsor 2022-11-01 21:44:44 +08:00
Louis Grenard 67d07ed7e6 docs: add new sponsor 2022-11-01 21:44:44 +08:00
Louis Grenard 18a728ff4b docs: add new sponsor 2022-10-30 22:23:40 +08:00
Louis Grenard b77e3a99e9 docs: add new sponsor 2022-10-30 22:23:40 +08:00
louistiti daba510755 feat: add distro level info in check report 2022-10-29 11:48:16 +08:00
louistiti dcc04de6bc feat: add distro level info in check report 2022-10-29 11:48:16 +08:00
louistiti 38693e42ef Merge branch 'fix/docker-issues-with-ssl' into develop 2022-10-23 22:55:04 +08:00
louistiti ceaff26d2d Merge branch 'fix/docker-issues-with-ssl' into develop 2022-10-23 22:55:04 +08:00
Divlo db373b66a6 fix(docker): issues with SSL 2022-10-23 12:37:36 +02:00
Divlo fb03359400 fix(docker): issues with SSL 2022-10-23 12:37:36 +02:00
Divlo d8e40c9cce refactor(server): replace unknown return type with TypeBox schema types 2022-10-23 11:09:07 +02:00
Divlo ecca030ab9 refactor(server): replace unknown return type with TypeBox schema types 2022-10-23 11:09:07 +02:00
Divlo 35322b39e3 refactor(server): replace unknown return type with TypeBox schema types 2022-10-23 11:09:07 +02:00
Divlo be079b87c8 feat(server): add JSON models with TypeBox
Later, we will be able to validate JSON files thanks to AJV.
2022-10-23 11:05:55 +02:00
Divlo 2a7b2f45d6 feat(server): add JSON models with TypeBox
Later, we will be able to validate JSON files thanks to AJV.
2022-10-23 11:05:55 +02:00
Divlo 2a48bc6343 feat(server): add JSON models with TypeBox
Later, we will be able to validate JSON files thanks to AJV.
2022-10-23 11:05:55 +02:00
louistiti 5acd22a885 Merge branch 'python-bridge-tcp-server-binaries' into develop 2022-10-23 12:01:21 +08:00
louistiti 632a048c6b Merge branch 'python-bridge-tcp-server-binaries' into develop 2022-10-23 12:01:21 +08:00
louistiti e1e4910399 fix(docker): based on Ubuntu image 2022-10-23 11:46:15 +08:00
louistiti 5bd67be2e5 fix(docker): based on Ubuntu image 2022-10-23 11:46:15 +08:00
louistiti 482f7bfbb8 chore(docker): .dockerignore path 2022-10-23 10:58:25 +08:00
louistiti 2d6f16a311 chore(docker): .dockerignore path 2022-10-23 10:58:25 +08:00
louistiti 3f8027af2a refactor: from superagent to axios 2022-10-23 10:55:03 +08:00
louistiti da063b73bc refactor: from superagent to axios 2022-10-23 10:55:03 +08:00
louistiti 3f97a12153 fix(python bridge): remove unecessary sqlite3 import 2022-10-23 10:07:14 +08:00
louistiti 6bee56580b fix(python bridge): remove unecessary sqlite3 import 2022-10-23 10:07:14 +08:00
louistiti ad1708abbb feat: ignore given warnings for TCP server binary on check script 2022-10-23 01:58:13 +08:00
louistiti bd1671c440 feat: ignore given warnings for TCP server binary on check script 2022-10-23 01:58:13 +08:00
louistiti e527110b9c feat: add binaries download progress 2022-10-23 01:00:55 +08:00
louistiti 0cf39c181f feat: add binaries download progress 2022-10-23 01:00:55 +08:00
louistiti c0886c086f Merge branch 'feat/download-unzip-python-bridge-tcp-server-binaries' into python-bridge-tcp-server-binaries 2022-10-22 23:23:08 +08:00
louistiti e459c1011c Merge branch 'feat/download-unzip-python-bridge-tcp-server-binaries' into python-bridge-tcp-server-binaries 2022-10-22 23:23:08 +08:00
louistiti 9928509171 refactor: minor setup-python-binaries renaming 2022-10-22 23:22:50 +08:00
louistiti 16444ae79f refactor: minor setup-python-binaries renaming 2022-10-22 23:22:50 +08:00
louistiti 75a351e77d chore: fix typo in report logs 2022-10-22 17:50:35 +08:00
louistiti 5c02e906fa chore: fix typo in report logs 2022-10-22 17:50:35 +08:00
louistiti b74e7beb29 ci: pre-release TCP server workflow 2022-10-22 15:14:17 +08:00
louistiti 03b0d08ae0 ci: pre-release TCP server workflow 2022-10-22 15:14:17 +08:00
louistiti 2183ffa4f0 refactor: send check report to the production URL 2022-10-19 23:28:33 +08:00
louistiti 6dbdfe7ba5 refactor: send check report to the production URL 2022-10-19 23:28:33 +08:00
Divlo 8ab9c2e4df feat: download and unzip TCP Server + Python Bridge on postinstall 2022-10-19 13:23:28 +02:00
Divlo c912b637ee feat: download and unzip TCP Server + Python Bridge on postinstall 2022-10-19 13:23:28 +02:00
louistiti fcce24d68c feat: send report to Pastebin and generate URL 2022-10-19 01:17:57 +08:00
louistiti 4df23cfe45 feat: send report to Pastebin and generate URL 2022-10-19 01:17:57 +08:00
louistiti 76e700e9ce feat: provide Python bridge and TCP server version in report 2022-10-19 00:40:34 +08:00
louistiti 65592b9af5 feat: provide Python bridge and TCP server version in report 2022-10-19 00:40:34 +08:00
louistiti 2463759717 refactor: check script according to binaries changes 2022-10-19 00:22:37 +08:00
louistiti 8f9937ddee refactor: check script according to binaries changes 2022-10-19 00:22:37 +08:00
louistiti 02c28b85f6 refactor: remove unnecessary checks 2022-10-16 23:25:58 +08:00
louistiti 5042bcc95d refactor: remove unnecessary checks 2022-10-16 23:25:58 +08:00
louistiti f54e8407c0 ci: remove tests for Ubuntu AArch64 2022-10-16 01:14:45 +08:00
louistiti cc6503e6f7 ci: remove tests for Ubuntu AArch64 2022-10-16 01:14:45 +08:00
louistiti 46a8bc61ea ci: test Ubuntu AArch64 2022-10-15 23:36:34 +08:00
louistiti 8de9d84f1f ci: test Ubuntu AArch64 2022-10-15 23:36:34 +08:00
louistiti 9aaa3d740d ci: build on Ubuntu AArch64 2022-10-15 23:24:45 +08:00
louistiti 29c582c89e ci: build on Ubuntu AArch64 2022-10-15 23:24:45 +08:00
louistiti 401f60e05b ci: split macOS ARM64 build into isolated job 2022-10-15 22:25:05 +08:00
louistiti bc53a36cd8 ci: split macOS ARM64 build into isolated job 2022-10-15 22:25:05 +08:00
louistiti a4fbba5fd0 ci: add macOS ARM64 self-hosted runner 2022-10-15 22:09:12 +08:00
louistiti 84cdc7fa60 ci: add macOS ARM64 self-hosted runner 2022-10-15 22:09:12 +08:00
louistiti 6ea6c84b3d refactor: remove setuptools and wheel force install for macOS ARM64 arch 2022-10-15 21:38:22 +08:00
louistiti 1dc0451f0f refactor: remove setuptools and wheel force install for macOS ARM64 arch 2022-10-15 21:38:22 +08:00
louistiti 6e2790b738 refactor: remove Rust compiler version number from TCP server setup 2022-10-15 21:11:29 +08:00
louistiti 1beebcccd2 refactor: remove Rust compiler version number from TCP server setup 2022-10-15 21:11:29 +08:00
louistiti 92ea9a081e feat: install additional resources for macOS ARM64 arch 2022-10-15 21:03:44 +08:00
louistiti b6b42c422c feat: install additional resources for macOS ARM64 arch 2022-10-15 21:03:44 +08:00
louistiti 23d6dd5e91 chore: ignore Fleet folder 2022-10-15 20:46:57 +08:00
louistiti bda75915b2 chore: ignore Fleet folder 2022-10-15 20:46:57 +08:00
Divlo b099d53871 fix(docker): install Python binaries from postinstall script 2022-10-13 22:59:39 +02:00
Divlo c6ad1968e7 fix(docker): install Python binaries from postinstall script 2022-10-13 22:59:39 +02:00
louistiti a5cbbf93a9 ci: try pre-release with all OSes 2022-10-13 01:42:36 +08:00
louistiti bc37bd1687 ci: try pre-release with all OSes 2022-10-13 01:42:36 +08:00
louistiti fc3e36713c ci: remove the lock file for Windows 2022-10-13 01:29:37 +08:00
louistiti 7161cd5996 ci: remove the lock file for Windows 2022-10-13 01:29:37 +08:00
louistiti 350072cf8c ci: remove skip lock for Windows 2022-10-13 01:22:40 +08:00
louistiti 23b7d5b49e ci: remove skip lock for Windows 2022-10-13 01:22:40 +08:00
louistiti b0849c0046 ci: add PIP_NO_BINARY 2022-10-13 01:11:12 +08:00
louistiti 599f9561e4 ci: add PIP_NO_BINARY 2022-10-13 01:11:12 +08:00
louistiti 0efed9d5f3 ci: set up MSBuild if Windows 2022-10-13 01:03:14 +08:00
louistiti bd45220c66 ci: set up MSBuild if Windows 2022-10-13 01:03:14 +08:00
louistiti 08d7fdf0dd ci: make use of Pipenv 2022.7.24 and skip lock on Windows 2022-10-13 00:53:58 +08:00
louistiti 53757651c8 ci: make use of Pipenv 2022.7.24 and skip lock on Windows 2022-10-13 00:53:58 +08:00
louistiti 42a3130394 ci: try with --deploy flag to install Python deps 2022-10-13 00:10:45 +08:00
louistiti bd1bde0814 ci: try with --deploy flag to install Python deps 2022-10-13 00:10:45 +08:00
louistiti 24c15c73c8 Merge branch 'develop' into python-bridge-tcp-server-binaries 2022-10-12 23:53:16 +08:00
louistiti ad044814a5 Merge branch 'develop' into python-bridge-tcp-server-binaries 2022-10-12 23:53:16 +08:00
louistiti 7d7552e95b docs: remove typo 2022-10-12 23:52:53 +08:00
louistiti fc2a37a7a6 ci: try Windows Pipenv deps install 2022-10-12 23:50:46 +08:00
louistiti aede3cbf52 ci: try Windows Pipenv deps install 2022-10-12 23:50:46 +08:00
louistiti a863c872b0 ci: try to build on Windows without catching exceptions 2022-10-12 23:37:23 +08:00
louistiti 79115d1b25 ci: try to build on Windows without catching exceptions 2022-10-12 23:37:23 +08:00
louistiti e5eeffa2bc Merge branch 'develop' into python-bridge-tcp-server-binaries 2022-10-12 23:11:07 +08:00
louistiti 404a1d5b3f Merge branch 'develop' into python-bridge-tcp-server-binaries 2022-10-12 23:11:07 +08:00
Louis Grenard 5e6caf7521 docs: add MacStadium to the README thanks section 2022-10-12 23:10:20 +08:00
louistiti 050d1f35b2 ci: tru the Windows runner without the rm command 2022-10-11 00:47:45 +08:00
louistiti 8a191b9c91 ci: tru the Windows runner without the rm command 2022-10-11 00:47:45 +08:00
louistiti 8a746d7ff8 ci: remove Pipfile.lock on Windows 2022-10-11 00:43:31 +08:00
louistiti 56a9a796bd ci: remove Pipfile.lock on Windows 2022-10-11 00:43:31 +08:00
louistiti 39bf7c678a ci: upgrade Pip to latest and try Windows runner 2022-10-11 00:36:27 +08:00
louistiti 5bc0a7f97b ci: upgrade Pip to latest and try Windows runner 2022-10-11 00:36:27 +08:00
louistiti 0188dd7ed8 ci: test to upload artifact with default name 2022-10-11 00:03:36 +08:00
louistiti 7fe7b2feaa ci: test to upload artifact with default name 2022-10-11 00:03:36 +08:00
louistiti adc63c94ba ci: upload artifacts then download and pre-release 2022-10-10 09:11:56 +08:00
louistiti ee0134598c ci: upload artifacts then download and pre-release 2022-10-10 09:11:56 +08:00
louistiti 47e9c291b4 ci: remove Windows 2022-10-10 09:02:03 +08:00
louistiti b19e5ad0cb ci: remove Windows 2022-10-10 09:02:03 +08:00
louistiti ff53b7a3f2 ci: remove Pipenv cache from pre-release binaries workflows 2022-10-10 00:14:37 +08:00
louistiti de442741e5 ci: remove Pipenv cache from pre-release binaries workflows 2022-10-10 00:14:37 +08:00
louistiti aafde0543f ci: install Pipenv on pre-release binaries workflows 2022-10-10 00:04:28 +08:00
louistiti f43e17aad4 ci: install Pipenv on pre-release binaries workflows 2022-10-10 00:04:28 +08:00
louistiti 4760c4d6de ci: checkout repo first on pre-release binaries workflows 2022-10-10 00:01:24 +08:00
louistiti ddbe4f0fd1 ci: checkout repo first on pre-release binaries workflows 2022-10-10 00:01:24 +08:00
louistiti c2865f73fb refactor: exit pre-release binaries script 2022-10-09 23:58:59 +08:00
louistiti f17a601d8e refactor: exit pre-release binaries script 2022-10-09 23:58:59 +08:00
louistiti 32ee4fef51 ci: add environment variables to locate virtual env 2022-10-09 23:58:05 +08:00
louistiti 5bace9545a ci: add environment variables to locate virtual env 2022-10-09 23:58:05 +08:00
louistiti 0f348ba48e Merge remote-tracking branch 'origin/develop' into python-bridge-tcp-server-binaries 2022-10-09 23:53:49 +08:00
louistiti f170a1dd8e Merge remote-tracking branch 'origin/develop' into python-bridge-tcp-server-binaries 2022-10-09 23:53:49 +08:00
louistiti cb37b4fcd2 refactor: pre-release binaries script give only workflow name 2022-10-09 23:53:40 +08:00
louistiti 91eac5c875 refactor: pre-release binaries script give only workflow name 2022-10-09 23:53:40 +08:00
Louis Grenard 4c19994fed ci: pre-release-tcp-server.yml GitHub Action workflow 2022-10-09 23:52:37 +08:00
Louis Grenard 8d4e8ba3a8 ci: pre-release-python-bridge.yml GitHub Action workflow 2022-10-09 23:51:22 +08:00
louistiti 6618f3a6a5 fix: rename GitHub workflows from the pre-release-binaries script 2022-10-09 23:39:22 +08:00
louistiti 518889b459 fix: rename GitHub workflows from the pre-release-binaries script 2022-10-09 23:39:22 +08:00
louistiti 0df61ae714 ci: pre-release TCP server 2022-10-09 22:03:26 +08:00
louistiti cc8a32d17d ci: pre-release TCP server 2022-10-09 22:03:26 +08:00
louistiti b9792d28d7 ci: pre-release Python bridge 2022-10-09 22:00:56 +08:00
louistiti a00b01c041 ci: pre-release Python bridge 2022-10-09 22:00:56 +08:00
louistiti 3f6e6ccdea refactor: rename GitHub workflows release script as pre-release 2022-10-09 21:27:12 +08:00
louistiti 7db5c064d9 refactor: rename GitHub workflows release script as pre-release 2022-10-09 21:27:12 +08:00
louistiti 4fcf8dceda feat: trigger GitHub workflows script done 2022-10-09 21:16:42 +08:00
louistiti ed8390a36c feat: trigger GitHub workflows script done 2022-10-09 21:16:42 +08:00
louistiti 3fe89bfda3 feat(tcp server): versioning 2022-10-09 00:31:52 +08:00
louistiti 1d45c2e715 feat(tcp server): versioning 2022-10-09 00:31:52 +08:00
louistiti 2b8ac0eb2b feat(python bridge): versioning 2022-10-09 00:29:30 +08:00
louistiti 784f86f6f3 feat(python bridge): versioning 2022-10-09 00:29:30 +08:00
louistiti 0ae31f6cc8 feat(server): add warning hint on macOS TCP server cold start 2022-10-07 19:18:36 +08:00
louistiti 9d865291f0 feat(server): add warning hint on macOS TCP server cold start 2022-10-07 19:18:36 +08:00
louistiti cb1a192a6d fix: comply macOS x86_64 and macOS arm64 to Python sysconfig.get_platform() 2022-10-07 18:25:51 +08:00
louistiti bc7dd0f836 fix: comply macOS x86_64 and macOS arm64 to Python sysconfig.get_platform() 2022-10-07 18:25:51 +08:00
louistiti 90530e4e60 refactor: remove LC_ALL and LANG env vars 2022-10-07 18:23:10 +08:00
louistiti 8d64ad9650 refactor: remove LC_ALL and LANG env vars 2022-10-07 18:23:10 +08:00
louistiti 6a4bde6c88 chore: explicit exclusion of TCP server and Python bridge on TypeScript watcher 2022-10-07 15:47:55 +08:00
louistiti b3fdde9d83 chore: explicit exclusion of TCP server and Python bridge on TypeScript watcher 2022-10-07 15:47:55 +08:00
louistiti 7111983ef5 perf(tcp server): option to download spaCy models through mirror in China 2022-10-07 15:31:37 +08:00
louistiti ea6fc4108a perf(tcp server): option to download spaCy models through mirror in China 2022-10-07 15:31:37 +08:00
louistiti b201f3f1b1 fix(tcp server): handle Windows child process does not throw exception 2022-10-07 14:10:32 +08:00
louistiti 40958f2fb4 fix(tcp server): handle Windows child process does not throw exception 2022-10-07 14:10:32 +08:00
louistiti cace69e9af perf(tcp server): do not download Python deps but spaCy models when necessary 2022-10-07 13:44:48 +08:00
louistiti 8e0d18a596 perf(tcp server): do not download Python deps but spaCy models when necessary 2022-10-07 13:44:48 +08:00
louistiti 432c590ee7 feat: on Python dev env setup, provide Windows hint related to Microsoft C++ Build Tools 2022-10-07 13:24:58 +08:00
louistiti 861d773cdd feat: on Python dev env setup, provide Windows hint related to Microsoft C++ Build Tools 2022-10-07 13:24:58 +08:00
louistiti 061f555e11 fix: always make use of latest Python build deps 2022-10-07 13:16:35 +08:00
louistiti 6bd9f0ef9d fix: always make use of latest Python build deps 2022-10-07 13:16:35 +08:00
louistiti 7bb9780ab1 feat: add hint on failed build 2022-10-07 12:07:48 +08:00
louistiti d69157439c feat: add hint on failed build 2022-10-07 12:07:48 +08:00
louistiti 999328819a feat: map Python bridge and TCP server binaries to runtime code 2022-10-07 11:53:43 +08:00
louistiti 1a3d4f2204 feat: map Python bridge and TCP server binaries to runtime code 2022-10-07 11:53:43 +08:00
louistiti 0e697183b2 perf(tcp server): optimize spaCy models checking 2022-10-07 11:26:39 +08:00
louistiti b59f6a7264 perf(tcp server): optimize spaCy models checking 2022-10-07 11:26:39 +08:00
louistiti 05b62871fb feat: universal build binaries script 2022-10-07 10:41:04 +08:00
louistiti bf902fd2d9 feat: universal build binaries script 2022-10-07 10:41:04 +08:00
louistiti 9724d7b943 feat: pack TCP server and optimize setup scripts 2022-10-07 02:37:43 +08:00
louistiti a8272e1bf9 feat: pack TCP server and optimize setup scripts 2022-10-07 02:37:43 +08:00
louistiti 109561495c feat(tcp server): set up script 2022-10-06 23:20:30 +08:00
louistiti b96070085b feat(tcp server): set up script 2022-10-06 23:20:30 +08:00
louistiti 286892eb30 chore: upgrade archiver to latest 2022-10-06 19:48:17 +08:00
louistiti 48688dc6e6 chore: upgrade archiver to latest 2022-10-06 19:48:17 +08:00
louistiti 3eea6a8fe8 feat(python bridge): pack build 2022-10-06 19:45:35 +08:00
louistiti 9dd9b010ed feat(python bridge): pack build 2022-10-06 19:45:35 +08:00
louistiti 472e388508 feat(python bridge): build script 2022-10-06 19:01:50 +08:00
louistiti 0888ae5033 feat(python bridge): build script 2022-10-06 19:01:50 +08:00
louistiti 1a953e007d feat(python bridge): set up script 2022-10-06 16:27:20 +08:00
louistiti 2d7be3348a feat(python bridge): set up script 2022-10-06 16:27:20 +08:00
louistiti 0fd4dd67c7 refactor(tcp server): move tokenizers private libraries to lib location 2022-10-06 08:34:30 +08:00
louistiti bee3fbb9e2 refactor(tcp server): move tokenizers private libraries to lib location 2022-10-06 08:34:30 +08:00
louistiti 6146fa1f15 fix(tcp server): include private libraries of the tokenizers package 2022-10-06 01:25:26 +08:00
louistiti 55db68400d fix(tcp server): include private libraries of the tokenizers package 2022-10-06 01:25:26 +08:00
louistiti 3361d9b37e feat(tcp server): include tokenizers files on build 2022-10-06 01:11:52 +08:00
louistiti 7d2432c56c feat(tcp server): include tokenizers files on build 2022-10-06 01:11:52 +08:00
louistiti 39dacb87e0 chore(tcp server): upgrade to latest setuptools version 2022-10-06 00:59:20 +08:00
louistiti 48731e8ddf chore(tcp server): upgrade to latest setuptools version 2022-10-06 00:59:20 +08:00
louistiti 2c9b675cae refactor(tcp server): remove cx_Freeze from Pipfile to install it individually during the dev phase 2022-10-06 00:13:54 +08:00
louistiti 4d0a97f9c2 refactor(tcp server): remove cx_Freeze from Pipfile to install it individually during the dev phase 2022-10-06 00:13:54 +08:00
louistiti 0d02b2e9fa fix: remove requests.certs import from the TCP server and Python bridge setups 2022-10-05 01:31:46 +08:00
louistiti 133310bd7d fix: remove requests.certs import from the TCP server and Python bridge setups 2022-10-05 01:31:46 +08:00
louistiti d8b20660a2 fix: upgrade cx_Freeze to 6.11.1 with --no-binary to avoid OpenSSL conflict with urllib3 2022-10-04 23:57:18 +08:00
louistiti 69bf9cebb3 fix: upgrade cx_Freeze to 6.11.1 with --no-binary to avoid OpenSSL conflict with urllib3 2022-10-04 23:57:18 +08:00
louistiti 5715786be2 chore: add TCP server and Python bridge as high-level nodes 2022-10-04 17:16:41 +08:00
louistiti 91e39a0a37 chore: add TCP server and Python bridge as high-level nodes 2022-10-04 17:16:41 +08:00
louistiti 0a4baf67ac feat: isolate TCP server 2022-10-04 17:10:14 +08:00
louistiti 586ca11106 feat: isolate TCP server 2022-10-04 17:10:14 +08:00
louistiti 39b605f6f4 chore: transparent distribution structure 2022-10-04 14:30:10 +08:00
louistiti 20b967b4ea chore: transparent distribution structure 2022-10-04 14:30:10 +08:00
louistiti a27ab96e18 feat: Python bridge binary build with cx_Freeze 2022-10-04 14:19:56 +08:00
louistiti dd9d024975 feat: Python bridge binary build with cx_Freeze 2022-10-04 14:19:56 +08:00
louistiti f1dcb07d5b feat: Python bridge build on macOS x86_64 arch 2022-10-02 15:43:48 +08:00
louistiti 8d1ab6973a feat: Python bridge build on macOS x86_64 arch 2022-10-02 15:43:48 +08:00
louistiti 38226ca84e feat(server): add execution time 2022-09-27 19:49:09 +08:00
louistiti b7d496e6d6 feat: add skill execution time in check script 2022-09-27 19:46:41 +08:00
louistiti 4d2fb56109 Merge branch 'chore/eslint-rule-prefer-node-protocol' into develop 2022-09-27 08:46:48 +08:00
Divlo f4a53da7fd chore: add unicorn/prefer-node-protocol ESLint rule 2022-09-26 22:10:27 +02:00
louistiti defc70128c refactor: add ESLint rules about imports 2022-09-27 00:01:03 +08:00
louistiti f68da11f6b refactor(server): make use of node:* import for all Node.js built-in modules 2022-09-26 23:28:25 +08:00
louistiti 0a49cb17fa refactor(server): remove node:* imports 2022-09-26 22:48:12 +08:00
louistiti 7081464abc refactor(server): add explicit return types 2022-09-26 22:46:12 +08:00
louistiti 7544534ea4 refactor(server): skill domain helper to static class 2022-09-26 21:36:07 +08:00
louistiti 46c0b579aa refactor(server): OS helper to static class 2022-09-26 21:32:59 +08:00
louistiti a80e8ba65d refactor(server): log helper to static class 2022-09-26 21:29:56 +08:00
louistiti 88d86117ac refactor(server): loader helper to static class 2022-09-26 21:24:07 +08:00
louistiti f4d625500f refactor(server): lang helper to static class 2022-09-26 21:17:36 +08:00
louistiti afec850fc9 refactor(server): date helper to static class 2022-09-26 21:13:33 +08:00
louistiti 9065d713e9 refactor(server): string helper from singleton to static 2022-09-26 00:44:40 +08:00
louistiti 1a4e09f908 refactor(server): simplify helpers singleton 2022-09-25 23:37:30 +08:00
Louis Grenard 4a59ba1d9c chore: update sponsor 2022-09-25 08:44:31 +08:00
louistiti cc317842d8 chore: clean up ESLint comments and new Prettier/ESLint script 2022-09-21 23:29:29 +08:00
louistiti c65f60e2b7 refactor(server): provide explicit class name to helpers 2022-09-21 23:08:11 +08:00
louistiti 2378dc37b1 Merge branch 'refactor/server-helpers' into develop 2022-09-21 23:01:36 +08:00
louistiti 82f6ee80fe refactor(server): skill domain helper to singleton 2022-09-21 23:01:16 +08:00
louistiti 84aadc0245 refactor(server): string helper to singleton 2022-09-21 22:24:48 +08:00
louistiti a5e48ec9e7 refactor(server): OS helper to singleton 2022-09-21 22:15:02 +08:00
louistiti e7cb31e706 chore(server): add comments on loader helper 2022-09-21 21:51:19 +08:00
louistiti 713ece380b refactor(server): rename lang helper methods 2022-09-21 21:46:05 +08:00
louistiti 8d3aee8da7 refactor(server): lang helper to singleton 2022-09-21 21:31:19 +08:00
louistiti f21e43c16a refactor(server): date helper to singleton 2022-09-21 20:43:50 +08:00
louistiti 4f1683dc55 refactor(server): capitalize singleton helpers instance constants 2022-09-21 20:25:00 +08:00
Divlo 74be62b812 chore: ignore core/skills-endpoints.json 2022-09-20 22:19:06 +02:00
Divlo 8d6a1167da chore: delete old unused ISSUE_TEMPLATE 2022-09-20 21:51:57 +02:00
Divlo c68b16191a chore: remove unneeded eslint disable comments 2022-09-20 21:49:41 +02:00
Divlo ef8374d03b perf: improve scripts/lint 2022-09-20 21:47:29 +02:00
Divlo 285bfa6e78 refactor(server): add getSkillConfig 2022-09-20 21:43:34 +02:00
Divlo a28eede95b refactor(server): os helper to TypeScript 2022-09-20 21:34:56 +02:00
Divlo 247167202d refactor(server): remove inconsistencies 2022-09-20 21:33:02 +02:00
Divlo 949138627e refactor(server): loader helper to TypeScript 2022-09-16 20:58:24 +02:00
Divlo b7f20710db refactor(server): log helper to TypeScript 2022-09-16 19:36:58 +02:00
Divlo c979a9ea08 refactor(server): lang helper to TypeScript 2022-09-16 17:17:54 +02:00
louistiti dabd657acf refactor(server): add comments to the skill domain helper 2022-09-13 23:16:12 +08:00
louistiti 6f7bcc5e37 refactor(server): skill domain helper to TypeScript 2022-09-13 23:06:57 +08:00
louistiti dbd659d75f feat: add OS info in the checking report 2022-09-13 00:45:23 +08:00
louistiti ed97b9361f feat: add spaCy model checking 2022-09-13 00:09:37 +08:00
louistiti 35a9f6e0ea refactor(server): string helper to TypeScript 2022-09-12 16:00:46 +08:00
louistiti da0233495d refactor(server): replace Moment.js by Day.js 2022-09-12 12:45:25 +08:00
louistiti ebe31f4b60 chore: upgrade moment-timezone to latest 2022-09-12 10:45:04 +08:00
louistiti 6dbe1e514f refactor(server): date helper to TypeScript 2022-09-12 10:41:16 +08:00
louistiti b4909564c7 chore: upgrade Coqui STT to latest 2022-09-10 11:51:23 +08:00
louistiti e8b596a8d8 chore: upgrade hotword deps 2022-09-10 10:55:13 +08:00
Louis Grenard 54336cdd01 docs: update skills list link 2022-09-05 13:45:01 +08:00
louistiti bf065fcbc6 chore: upgrade FFprobe to latest 2022-09-04 23:59:18 +08:00
louistiti e541e32c53 chore: upgrade Socket.IO to latest 2022-09-04 23:53:05 +08:00
louistiti 6872ee9735 chore: upgrade Vite to latest 2022-09-04 23:50:17 +08:00
louistiti e0bb25b1d9 fix(web app): when suggestions are null new npm deps tree was creating conflict 2022-09-04 23:48:55 +08:00
louistiti cf563f5f32 feat(server): detach the TCP server from the main process in dev 2022-09-04 18:54:16 +08:00
louistiti 891b032543 fix: recursive compilation through the server folder 2022-09-04 14:28:36 +08:00
louistiti 49ffb0b1f3 style(server): typo 2022-09-04 14:25:41 +08:00
louistiti aa7a152f7b refactor(server): make use of consts for TCP server matters 2022-09-04 14:23:23 +08:00
louistiti 58dc881a83 refactor(server): make use of consts for logger matters 2022-09-04 14:18:53 +08:00
louistiti 819e57a2c2 refactor(server): make use of consts for HTTP API matters 2022-09-04 14:17:06 +08:00
louistiti d05d572b70 refactor(server): make use of consts for voice config matters 2022-09-04 14:10:42 +08:00
louistiti e07ec87838 refactor(server): init dotenv earlier and make use of consts for time zone matters 2022-09-04 13:56:05 +08:00
louistiti cb173a6319 refactor(server): make use of consts for HTTP config matters 2022-09-04 13:32:58 +08:00
louistiti ddffd80985 refactor(server): make use of consts for lang matters 2022-09-04 13:28:10 +08:00
louistiti e1719115ea refactor(server): make use of consts for env matters 2022-09-04 13:13:03 +08:00
louistiti a903f20d7e chore: merge 2022-09-04 11:57:05 +08:00
louistiti 783858f811 chore: keep an exact ESLint version for JetBrains IDEs issue 2022-09-04 11:56:02 +08:00
louistiti 4e7ee1bb5e feat: make sure there is no .venv folder before the Python deps setup 2022-09-03 21:12:53 +08:00
louistiti a79459e5a6 chore: Prettier and lint-staged setup 2022-09-03 20:59:18 +08:00
louistiti 6d836d2d93 chore: upgrade Fastify to latest 2022-09-03 20:56:44 +08:00
louistiti e905dcc86b feat: lint-staged config 2022-09-03 20:56:15 +08:00
louistiti 4485b97ec2 chore: upgrade Fastify to latest 2022-09-03 19:57:19 +08:00
louistiti 0ea9bec001 Merge branch 'ts-kickoff' into develop 2022-09-03 19:25:04 +08:00
louistiti be4761602c chore: new deps tree 2022-09-03 19:24:06 +08:00
louistiti 27bd5a082f feat: remove Babel 2022-09-03 19:16:13 +08:00
louistiti 019c462bfa feat: complete Prettier setup 2022-09-03 19:12:41 +08:00
louistiti ba9f3f22f6 feat: basic Prettier setup 2022-09-03 18:37:56 +08:00
louistiti b9945729bb feat: new ESLint config 2022-09-03 18:17:16 +08:00
louistiti 935246d09a feat: make use of tsc-watch for dev server 2022-09-03 17:29:22 +08:00
louistiti ebda0da64e chore: install resolve-tspaths dev dep. 2022-09-03 13:08:54 +08:00
louistiti 36730025fc chore: upgrade nodemon to latest 2022-09-03 12:06:00 +08:00
louistiti 6d3d441fbf feat: extend from main TypeScript config 2022-09-03 12:02:40 +08:00
louistiti 9e48c5264c fix: resolve alias paths after compilation 2022-09-03 11:58:10 +08:00
louistiti 844fcc8a86 refactor: correct build:server executions order 2022-09-03 10:12:49 +08:00
louistiti 04c5bedd2b chore: move nodemon config to a config file 2022-09-03 10:05:27 +08:00
louistiti 4ca98cdbab chore: extend TypeScript config 2022-09-03 09:51:35 +08:00
louistiti 9645c3de68 refactor: TypeScript build kick off 2022-08-29 00:59:35 +08:00
louistiti 781e072b23 refactor: TypeScript entry point 2022-08-28 14:12:59 +08:00
louistiti 3498293098 refactor: make use of ts-node 2022-08-28 11:37:32 +08:00
louistiti fa7bc53ee9 chore: bump 1.0.0-beta.8+dev 2022-08-24 21:35:26 +08:00
445 changed files with 16552 additions and 46812 deletions
-23
View File
@@ -1,23 +0,0 @@
{
"presets": [
["@babel/preset-env", {
"targets": {
"node": "current"
}
}]
],
"plugins": [
["module-resolver", {
"alias": {
"@@": ".",
"@": "./server/src"
},
"compilerOptions": {
"paths": {
"@@": ".",
"@": "./server/src"
}
}
}]
]
}
+9 -2
View File
@@ -1,2 +1,9 @@
node_modules/
bridges/python/.venv/*
__pycache__/
**/dist/*
**/build/
**/node_modules/
**/tmp/*
**/src/.venv/*
logs/*
*.pyc
.DS_Store
-1
View File
@@ -12,5 +12,4 @@ end_of_line = lf
insert_final_newline = true
[*.py]
indent_style = tab
indent_size = 4
+3 -12
View File
@@ -31,24 +31,15 @@ LEON_HTTP_API_KEY=
# Language used for the HTTP API
LEON_HTTP_API_LANG=en-US
# Enable/disable collaborative logger
LEON_LOGGER=true
# 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 ... skill" 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
+68 -32
View File
@@ -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,61 @@
"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": ["skills/**/*.ts"],
"rules": {
"import/order": "off"
}
},
{
"files": ["*.ts"],
"rules": {
"@typescript-eslint/explicit-function-return-type": "error"
}
}
]
}
+10 -10
View File
@@ -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
+98 -23
View File
@@ -19,10 +19,9 @@ Here are few examples about how you could help on Leon, by:
- [Improving the documentation](https://github.com/leon-ai/docs.getleon.ai) (translations, typos, better writing, etc.).
- [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.
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/leon-ai/leon)
@@ -106,27 +105,32 @@ 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
- scripts
- server
- tcp server
- web app
- skill/skill_name
### Examples
@@ -148,6 +152,77 @@ By sponsoring the project you make the project sustainable and faster to develop
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/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).
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).
-7
View File
@@ -1,7 +0,0 @@
<!--
Thanks for your interest in Leon! ❤️
Please check if there is no similar issue before creating this one.
-->
+1
View File
@@ -12,6 +12,7 @@ Please place an x (no spaces - [x]) in all [ ] that apply.
-->
### Documentation Is:
- [ ] Missing
- [ ] Needed
- [ ] Confusing
+2 -1
View File
@@ -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,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
+14 -8
View File
@@ -1,30 +1,36 @@
__pycache__/
.idea/
.fleet/
.vscode/
**/dist/
**/dist/*
**/build/
**/node_modules/
test/coverage/
**/tmp/*
bridges/python/.venv/*
downloads/*
**/src/.venv/*
logs/*
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
.last-skill-npm-install
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
skills/**/src/settings.json
skills/**/memory/*.json
core/data/models/*.nlp
package.json.backup
.python-version
schemas/**/*.json
+1 -1
View File
@@ -6,6 +6,6 @@ if ! [ -x "$(command -v npm)" ]; then
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
npm run lint && node_modules/@babel/node/bin/babel-node.js scripts/commit-msg.js
npx ts-node scripts/commit-msg.js
fi
+4
View File
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged
+3
View File
@@ -0,0 +1,3 @@
{
"*": ["npm run lint"]
}
+2
View File
@@ -1 +1,3 @@
engine-strict=true
package-lock=false
save-exact=true
+5
View File
@@ -0,0 +1,5 @@
{
"semi": false,
"trailingComma": "none",
"singleQuote": true
}
+294 -259
View File
@@ -1,327 +1,362 @@
# [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
_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.*
_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
- remove legacy packages [07743657](https://github.com/leon-ai/leon/commit/07743657cd2954e7f850c08eea7c032c24b28a96)
- 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)
- 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:**
- 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)
- 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)
- 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
- 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)
- 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)
- 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)
- 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.*
_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)
- 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)
- **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)
- 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)
- 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)
- 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.*
_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)
- **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)
- 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)
- 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.
+22 -31
View File
@@ -1,4 +1,4 @@
FROM ubuntu:latest
FROM ubuntu:20.04
ENV IS_DOCKER true
# Replace shell with bash so we can source files
@@ -15,18 +15,23 @@ RUN apt-get update && apt-get install --yes -q --no-install-recommends \
curl \
git \
wget \
libssl-dev \
zlib1g-dev \
libbz2-dev \
libreadline-dev \
libsqlite3-dev \
llvm \
libncurses5-dev \
xz-utils \
tk-dev libxml2-dev \
libxmlsec1-dev \
libffi-dev \
liblzma-dev
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
@@ -34,28 +39,14 @@ USER docker
WORKDIR /home/docker
# Install Node.js with nvm
ENV NVM_DIR /home/docker/nvm
ENV NODE_VERSION v16.17.0
ENV NVM_DIR /home/docker/.nvm
ENV NODE_VERSION v16.18.0
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash
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 Python with pyenv
RUN git clone --depth=1 https://github.com/pyenv/pyenv.git .pyenv
ENV PYENV_ROOT="/home/docker/.pyenv"
ENV PATH="${PYENV_ROOT}/shims:${PYENV_ROOT}/bin:${PATH}"
ENV PYTHON_VERSION=3.9.10
RUN pyenv install ${PYTHON_VERSION}
RUN pyenv global ${PYTHON_VERSION}
# Install Pipenv
ENV PYTHON_BIN_PATH /home/docker/.local/bin
ENV PATH="${PYTHON_BIN_PATH}:${PATH}"
RUN python -m pip install --user --force-reinstall pipenv virtualenv
ENV PATH $NVM_DIR/versions/node/$NODE_VERSION/bin:$PATH
# Install Leon
WORKDIR /home/docker/leon
+76 -33
View File
@@ -7,7 +7,7 @@
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>
@@ -28,14 +28,47 @@
<a href="https://blog.getleon.ai/the-story-behind-leon/">Story</a>
</p>
<br>
<h2 align="center">📢 Notice 📢</h2>
<p align="center">
<a href="https://blog.getleon.ai/a-much-better-nlp-and-future-1-0-0-beta-7/"><img width="400" src="https://blog.getleon.ai/static/a62ac28a01cb6898e299dced40875a68/c1b63/beta-7.png" /></a>
<br>
Many exciting things are coming up, hence no new documentation and test are going to be written until the official release of Leon. Feel free to <a href="https://discord.gg/MNQqqKg"><b>join us on Discord</b></a> to know more and to read the <a href="https://blog.getleon.ai/a-much-better-nlp-and-future-1-0-0-beta-7/"><b>"A Much Better NLP and Future" blog post</b></a>.
</p>
<br><br>
---
## 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!
While I would love to devote more time to Leon, I'm currently unable to do so because I have bills to pay. 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, knowledge base, 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>
---
@@ -52,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
> Skills structure.
> 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).
> 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.
@@ -63,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
> - 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 (skills).
> You can find what he is able to do by browsing the [packages list](https://github.com/leon-ai/leon/tree/develop/packages).
> 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.
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/leon-ai/leon)
@@ -157,7 +194,7 @@ You'll find a write-up on this [blog post](https://blog.getleon.ai/the-story-beh
- [Blog](https://blog.getleon.ai)
- [GitHub issues](https://github.com/leon-ai/leon/issues)
- [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)
- [#LeonAI](<https://twitter.com/search?f=live&q=%23LeonAI%20(from%3Agrenlouis%20OR%20from%3Alouistiti_fr)&src=typed_query>)
## 👨 Author
@@ -169,28 +206,27 @@ You'll find a write-up on this [blog post](https://blog.getleon.ai/the-story-beh
<tbody>
<tr>
<td align="center" valign="middle" width="128">
<a href="https://github.com/phareal">
<img src="https://github.com/phareal.png?size=128" />
phareal
<a href="https://github.com/Appwrite">
<img src="https://github.com/Appwrite.png?size=128" />
Appwrite
</a><br>
<sub><sup>30 USD / month</sup></sub>
<sub><sup>250 USD / month</sup></sub>
</td>
<td align="center" valign="middle" width="128">
<a href="https://antmedia.io/?utm_source=github&utm_medium=banner&utm_campaign=opensource&utm_id=1">
<img src="https://github.com/ant-media.png?size=128" />
Ant Media
</a><br>
<sub><sup>17 USD / month</sup></sub>
<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/KeithIMyers">
<img src="https://github.com/KeithIMyers.png?size=128" />
Keith Myers
<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/">
<a href="http://sponsor.getleon.ai/">
You?
</a>
</td>
@@ -208,17 +244,24 @@ The focus is not only limited to the activity you see on GitHub but also a lot o
### Special Thanks
<a href="https://www.aoz.studio">
<img src="https://user-images.githubusercontent.com/1731544/153794939-c42f1b10-a15d-4e82-b448-dc95bfe85b1c.png" alt="AOZ Studio" width="64" />
</a>
<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>
&nbsp; &nbsp; &nbsp;
<a href="https://www.macstadium.com/">
<img src="https://getleon.ai/img/thanks/mac-stadium.svg" alt="MacStadium" width="128" />
</a>
&nbsp; &nbsp; &nbsp;
<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@getleon.ai>
## Cheers!
![Cheers!](https://github.githubassets.com/images/icons/emoji/unicode/1f379.png "Cheers!")
![Cheers!](https://github.githubassets.com/images/icons/emoji/unicode/1f379.png 'Cheers!')
+133 -41
View File
@@ -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;
}
@@ -47,8 +125,10 @@ table {
}
:root {
--black-color: #151718;
--white-color: #FFF;
--black-color: #000;
--light-black-color: #222426;
--white-color: #fff;
--grey-color: #323739;
}
a {
@@ -66,7 +146,7 @@ body {
font-weight: 400;
}
body > * {
transition: opacity .5s;
transition: opacity 0.5s;
}
body.settingup > * {
opacity: 0;
@@ -81,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;
}
}
@@ -115,7 +195,7 @@ input {
color: var(--white-color);
width: 100%;
border: none;
border-bottom: 2px solid var(--white-color);
border-bottom: 2px solid var(--grey-color);
background: none;
font-weight: 400;
font-size: 4em;
@@ -124,7 +204,7 @@ input {
small {
color: var(--white-color);
font-size: .7em;
font-size: 0.7em;
}
.hide {
@@ -144,14 +224,14 @@ small {
top: 10%;
height: 50%;
overflow-y: auto;
border: 2px solid var(--white-color);
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;
}
@@ -166,7 +246,7 @@ small {
padding: 0 8px;
opacity: 0;
margin-top: 20px;
transition: opacity .3s;
transition: opacity 0.3s;
}
#is-typing.on {
opacity: 1;
@@ -181,16 +261,16 @@ small {
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;
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% {
@@ -207,6 +287,17 @@ small {
.bubble-container.leon {
text-align: left;
}
.show-more {
margin: 3px;
text-decoration: underline;
}
.show-more:hover {
cursor: pointer;
text-decoration: none;
}
.show-all {
max-height: 100% !important;
}
.bubble {
padding: 6px 12px;
@@ -216,16 +307,17 @@ small {
word-break: break-word;
text-align: left;
opacity: 0;
animation: fadeIn .2s ease-in forwards;
animation: fadeIn 0.2s ease-in forwards;
overflow: hidden;
}
#feed .me .bubble {
background-color: #1C75DB;
background-color: #1c75db;
color: var(--white-color);
right: 0;
}
#feed .leon .bubble {
background-color: #EEE;
color: var(--black-color);
background-color: var(--light-black-color);
color: var(--white-color);
}
@keyframes fadeIn {
100% {
@@ -251,7 +343,7 @@ small {
padding: 2px 8px;
font-size: inherit;
cursor: pointer;
transition: background-color .2s, color .2s;
transition: background-color 0.2s, color 0.2s;
}
.suggestion:hover {
color: var(--black-color);
@@ -284,7 +376,7 @@ small {
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;
}
#mic-button:not(.enabled) {
margin-left: -26px;
@@ -293,13 +385,13 @@ small {
background-color: var(--white-color);
}
#mic-button.enabled {
background-color: #00E676;
background-color: #00e676;
}
#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;
+49 -46
View File
@@ -1,50 +1,53 @@
<!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="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>
<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="root"></div>
<div id="feed">
<p id="no-bubble" class="hide">
You can start to interact with Leon, don't be shy.
</p>
</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>
<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>
+9
View File
@@ -0,0 +1,9 @@
function App() {
return (
<>
<p>Hello from React</p>
</>
)
}
export default App
+9
View File
@@ -0,0 +1,9 @@
import type React from 'react'
interface Props {
children: React.ReactNode
}
export function Button({ children }: Props) {
return <button>{children}</button>
}
+34 -12
View File
@@ -1,5 +1,7 @@
const MAXIMUM_HEIGHT_TO_SHOW_SEE_MORE = 340
export default class Chatbot {
constructor () {
constructor() {
this.et = new EventTarget()
this.feed = document.querySelector('#feed')
this.typing = document.querySelector('#is-typing')
@@ -8,7 +10,7 @@ export default class Chatbot {
this.parsedBubbles = JSON.parse(this.bubbles)
}
async init () {
async init() {
await this.loadFeed()
this.scrollDown()
@@ -21,19 +23,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 +45,26 @@ 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() {
/**
* TODO: widget: load widget from local storage
*/
return new Promise((resolve) => {
if (this.parsedBubbles === null || this.parsedBubbles.length === 0) {
this.noBubbleMessage.classList.remove('hide')
@@ -72,7 +77,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 +87,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')
@@ -92,12 +97,29 @@ export default class Chatbot {
this.feed.appendChild(container).appendChild(bubble)
if (container.clientHeight > MAXIMUM_HEIGHT_TO_SHOW_SEE_MORE) {
bubble.style.maxHeight = `${MAXIMUM_HEIGHT_TO_SHOW_SEE_MORE}px`
const showMore = document.createElement('p')
const showMoreText = 'Show more'
showMore.className = 'show-more'
showMore.innerHTML = showMoreText
container.appendChild(showMore)
showMore.addEventListener('click', () => {
bubble.classList.toggle('show-all')
showMore.innerHTML =
showMore.innerHTML === showMoreText ? 'Show less' : showMoreText
})
}
if (save) {
this.saveBubble(who, string)
}
}
saveBubble (who, string) {
saveBubble(who, string) {
if (!this.noBubbleMessage.classList.contains('hide')) {
this.noBubbleMessage.classList.add('hide')
}
+66 -16
View File
@@ -1,8 +1,13 @@
import { io } from 'socket.io-client'
import React from 'react'
import { createRoot } from 'react-dom/client'
import { Button } from './aurora/button'
import Chatbot from './chatbot'
import { INIT_MESSAGES } from './constants'
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')
@@ -12,25 +17,43 @@ export default class Client {
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 (loader) {
async sendInitMessages() {
for (let i = 0; i < INIT_MESSAGES.length; i++) {
const messages = INIT_MESSAGES[i]
const message = messages[Math.floor(Math.random() * messages.length)]
const sendingDelay = Math.floor(Math.random() * 2000) + 1000
const typingFactorDelay = Math.floor(Math.random() * 4) + 2
setTimeout(() => {
this.chatbot.isTyping('leon', true)
}, sendingDelay / typingFactorDelay)
await new Promise((resolve) => setTimeout(resolve, sendingDelay))
this.chatbot.receivedFrom('leon', message)
this.chatbot.isTyping('leon', false)
}
}
init(loader) {
this.chatbot.init()
this.socket.on('connect', () => {
@@ -39,6 +62,10 @@ export default class Client {
this.socket.on('ready', () => {
loader.stop()
if (this.chatbot.parsedBubbles?.length === 0) {
this.sendInitMessages()
}
})
this.socket.on('answer', (data) => {
@@ -46,7 +73,7 @@ export default class Client {
})
this.socket.on('suggest', (data) => {
data.forEach((suggestionText) => {
data?.forEach((suggestionText) => {
this.addSuggestion(suggestionText)
})
})
@@ -62,6 +89,30 @@ export default class Client {
cb('string-received')
})
this.socket.on('widget', (data) => {
/**
* TODO: widget: widget handler to core/skill; dynamic component rendering
*/
console.log('data', data)
const container = document.createElement('div')
container.className = 'widget'
this.chatbot.feed.appendChild(container)
const root = createRoot(container)
// TODO: widget: pass props and dynamic component loading according to type
const widgets = {
Button: (options) => {
return Button({
children: options.text
})
}
}
root.render(widgets[data.type](data.options))
})
this.socket.on('audio-forwarded', (data, cb) => {
const ctx = new AudioContext()
const source = ctx.createBufferSource()
@@ -99,7 +150,7 @@ export default class Client {
}
}
}
}, 1000)
}, 1_000)
}, data.duration + 500)
}
})
@@ -107,18 +158,17 @@ export default class Client {
cb('audio-received')
})
this.socket.on('download', (data) => {
window.location = `${this.serverUrl}/api/v1/downloads?domain=${data.domain}&skill=${data.skill}`
})
if (this.history !== null) {
this.parsedHistory = JSON.parse(this.history)
}
}
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) => {
@@ -135,7 +185,7 @@ export default class Client {
return false
}
save () {
save() {
let val = this._input.value
if (localStorage.getItem('history') === null) {
@@ -157,7 +207,7 @@ export default class Client {
this._input.value = ''
}
addSuggestion (text) {
addSuggestion(text) {
const newSuggestion = document.createElement('button')
newSuggestion.classList.add('suggestion')
newSuggestion.textContent = text
+21
View File
@@ -0,0 +1,21 @@
export const INIT_MESSAGES = [
[
`Hello there! Glad to e-meet meet you, I'm Leon, your open-source personal assistant. While I'm still learning and improving, I promise to do my best to be helpful.`
],
[
`<ul>
<li>We've got lots in the works. Check out <a href="http://roadmap.getleon.ai/" target="_blank">our roadmap</a>.</li>
<li>Stay updated on our progress by checking out our <a href="https://blog.getleon.ai/" target="_blank">blog</a>.</li>
<li>You can also get updates straight to your inbox <a href="https://newsletter.getleon.ai/subscription/form" target="_blank">here</a>.</li>
`
],
[
`Come hang out with us <a href="https://discord.gg/MNQqqKg" target="_blank">on Discord</a>! Once we release our official version, our community will be working together to build new skills for me. You won't want to miss out on the fun!`
],
[
`At the moment, I'm not using a large language model, but we're planning to incorporate some in the future to improve my abilities. You can <a href="https://github.com/leon-ai/leon#how-about-large-language-models-and-leon" target="_blank">learn more about our plans here</a>.`
],
[
`Just so you know, my creator is working tirelessly to improve my skills and features, dedicating 75% of his free time to the project on top of his full-time job. If you'd like to help speed up my development, you can sponsor his work by clicking on this link: <strong><a href='http://sponsor.getleon.ai/' target='_blank'>sponsor.getleon.ai</a></strong>. Your support would mean a lot to us. Thank you for choosing me as your assistant!`
]
]
+9 -4
View File
@@ -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
+3 -3
View File
@@ -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 -77
View File
@@ -1,4 +1,4 @@
import request from 'superagent'
import axios from 'axios'
import Loader from './loader'
import Client from './client'
@@ -11,58 +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}/api/v1/info`)
.end((err, res) => {
if (err || !res.ok) {
console.error(err.response.error.message)
} else {
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, res.body)
let rec = { }
let chunks = []
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
v.innerHTML += client.info.version
client.init(loader)
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
@@ -72,52 +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.')
}
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)
}
})
+4 -7
View File
@@ -14,13 +14,13 @@ const onkeydowninput = (e, client) => {
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
}
@@ -33,7 +33,4 @@ const onkeydowndocument = (e, cb) => {
}
}
export {
onkeydowninput,
onkeydowndocument
}
export { onkeydowninput, onkeydowndocument }
+6 -6
View File
@@ -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)
}
+20
View File
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"useDefineForClassFields": true,
"skipLibCheck": true,
"module": "ESNext",
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
}
}
+13 -3
View File
@@ -1,16 +1,26 @@
import dns from 'node:dns'
import dotenv from 'dotenv'
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
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
},
plugins: [react()]
})
+2
View File
@@ -0,0 +1,2 @@
package-lock=false
save-exact=true
View File
+22
View File
@@ -0,0 +1,22 @@
{
"name": "leon-nodejs-bridge",
"description": "Leon's Node.js bridge to communicate between the core and skills made with JavaScript",
"main": "dist/bin/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"
},
"dependencies": {
"axios": "1.4.0",
"lodash": "4.17.21"
},
"devDependencies": {
"@types/lodash": "4.14.194"
}
}
+32
View File
@@ -0,0 +1,32 @@
import fs from 'node:fs'
import path from 'node:path'
import { SKILLS_PATH as SKILLS_ROOT_PATH } from '@/constants'
import type { SkillConfigSchema } from '@server/schemas/skill-schemas'
import type { IntentObject } from '@sdk/types'
const {
argv: [, , INTENT_OBJ_FILE_PATH]
} = process
export const INTENT_OBJECT: IntentObject = JSON.parse(
fs.readFileSync(INTENT_OBJ_FILE_PATH as string, 'utf8')
)
export const SKILL_PATH = path.join(
SKILLS_ROOT_PATH,
INTENT_OBJECT.domain,
INTENT_OBJECT.skill
)
export const SKILLS_PATH = SKILLS_ROOT_PATH
export const SKILL_CONFIG: SkillConfigSchema = JSON.parse(
fs.readFileSync(
path.join(
SKILL_PATH,
'config',
INTENT_OBJECT.extra_context_data.lang + '.json'
),
'utf8'
)
)
export { LEON_VERSION, NODEJS_BRIDGE_VERSION } from '@/constants'
+49
View File
@@ -0,0 +1,49 @@
import path from 'node:path'
import type { ActionFunction, ActionParams } from '@sdk/types'
import { INTENT_OBJECT } from '@bridge/constants'
;(async (): Promise<void> => {
const {
domain,
skill,
action,
lang,
utterance,
current_entities,
entities,
current_resolvers,
resolvers,
slots,
extra_context_data
} = INTENT_OBJECT
const params: ActionParams = {
lang,
utterance,
current_entities,
entities,
current_resolvers,
resolvers,
slots,
extra_context_data
}
try {
const actionModule = await import(
path.join(
process.cwd(),
'skills',
domain,
skill,
'src',
'actions',
`${action}.ts`
)
)
const actionFunction: ActionFunction = actionModule.run
await actionFunction(params)
} catch (e) {
console.error(`Error while running "${skill}" skill "${action}" action:`, e)
}
})()
+12
View File
@@ -0,0 +1,12 @@
import { Widget } from '../widget'
// TODO: contains the button API. rendering engine <-> SDK
interface ButtonOptions {
text: string
}
export class Button extends Widget<ButtonOptions> {
public constructor(options: ButtonOptions) {
super(options)
}
}
+130
View File
@@ -0,0 +1,130 @@
import type {
AnswerData,
AnswerInput,
AnswerOutput,
AnswerConfig
} from '@sdk/types'
import { INTENT_OBJECT, SKILL_CONFIG } from '@bridge/constants'
class Leon {
private static instance: Leon
constructor() {
if (!Leon.instance) {
Leon.instance = this
}
}
/**
* Apply data to the answer
* @param answerKey The answer key
* @param data The data to apply
* @example setAnswerData('key', { name: 'Leon' })
*/
public setAnswerData(
answerKey: string,
data: AnswerData = null
): AnswerConfig {
try {
// In case the answer key is a raw answer
if (SKILL_CONFIG.answers == null || !SKILL_CONFIG.answers[answerKey]) {
return answerKey
}
const answers = SKILL_CONFIG.answers[answerKey] ?? ''
let answer: AnswerConfig
if (Array.isArray(answers)) {
answer = answers[Math.floor(Math.random() * answers.length)] ?? ''
} else {
answer = answers
}
if (data != null) {
for (const key in data) {
// In case the answer needs speech and text differentiation
if (typeof answer !== 'string' && answer.text) {
answer.text = answer.text.replaceAll(`%${key}%`, String(data[key]))
answer.speech = answer.speech.replaceAll(
`%${key}%`,
String(data[key])
)
} else {
answer = (answer as string).replaceAll(
`%${key}%`,
String(data[key])
)
}
}
}
if (SKILL_CONFIG.variables) {
const { variables } = SKILL_CONFIG
for (const key in variables) {
// In case the answer needs speech and text differentiation
if (typeof answer !== 'string' && answer.text) {
answer.text = answer.text.replaceAll(
`%${key}%`,
String(variables[key])
)
answer.speech = answer.speech.replaceAll(
`%${key}%`,
String(variables[key])
)
} else {
answer = (answer as string).replaceAll(
`%${key}%`,
String(variables[key])
)
}
}
}
return answer
} catch (e) {
console.error('Error while setting answer data:', e)
throw e
}
}
/**
* Send an answer to the core
* @param answerInput The answer input
* @example answer({ key: 'greet' }) // 'Hello world'
* @example answer({ key: 'welcome', data: { name: 'Louis' } }) // 'Welcome Louis'
* @example answer({ key: 'confirm', core: { restart: true } }) // 'Would you like to retry?'
*/
public async answer(answerInput: AnswerInput): Promise<void> {
try {
const answerObject: AnswerOutput = {
...INTENT_OBJECT,
output: {
codes:
answerInput.widget && !answerInput.key
? 'widget'
: (answerInput.key as string),
answer:
answerInput.key != null
? this.setAnswerData(answerInput.key, answerInput.data)
: '',
core: answerInput.core
}
}
if (answerInput.widget) {
answerObject.output.widget = answerInput.widget
}
// "Temporize" for the data buffer output on the core
await new Promise((r) => setTimeout(r, 100))
process.stdout.write(JSON.stringify(answerObject))
} catch (e) {
console.error('Error while creating answer:', e)
}
}
}
export const leon = new Leon()
+99
View File
@@ -0,0 +1,99 @@
import path from 'node:path'
import fs from 'node:fs'
import { SKILL_PATH, SKILLS_PATH } from '@bridge/constants'
interface MemoryOptions<T> {
name: string
defaultMemory?: T
}
export class Memory<T = unknown> {
private readonly memoryPath: string
private readonly name: string
private readonly defaultMemory: T | undefined
private isFromAnotherSkill: boolean
constructor(options: MemoryOptions<T>) {
const { name, defaultMemory } = options
this.name = name
this.defaultMemory = defaultMemory
this.memoryPath = path.join(SKILL_PATH, 'memory', `${this.name}.json`)
this.isFromAnotherSkill = false
if (this.name.includes(':') && this.name.split(':').length === 3) {
this.isFromAnotherSkill = true
const [domainName, skillName, memoryName] = this.name.split(':')
this.memoryPath = path.join(
SKILLS_PATH,
domainName as string,
skillName as string,
'memory',
`${memoryName}.json`
)
}
}
/**
* Clear the memory and set it to the default memory value
* @example clear()
*/
public async clear(): Promise<void> {
if (!this.isFromAnotherSkill) {
await this.write(this.defaultMemory as T)
} else {
throw new Error(
`You cannot clear the memory "${this.name}" as it belongs to another skill`
)
}
}
/**
* Read the memory
* @example read()
*/
public async read(): Promise<T> {
if (this.isFromAnotherSkill && !fs.existsSync(this.memoryPath)) {
throw new Error(
`You cannot read the memory "${this.name}" as it belongs to another skill which haven't written to this memory yet`
)
}
try {
if (!fs.existsSync(this.memoryPath)) {
await this.clear()
}
return JSON.parse(await fs.promises.readFile(this.memoryPath, 'utf-8'))
} catch (e) {
console.error(`Error while reading memory for "${this.name}":`, e)
throw e
}
}
/**
* Write the memory
* @param memory The memory to write
* @example write({ foo: 'bar' }) // { foo: 'bar' }
*/
public async write(memory: T): Promise<T> {
if (!this.isFromAnotherSkill) {
try {
await fs.promises.writeFile(
this.memoryPath,
JSON.stringify(memory, null, 2)
)
return memory
} catch (e) {
console.error(`Error while writing memory for "${this.name}":`, e)
throw e
}
} else {
throw new Error(
`You cannot write into the memory "${this.name}" as it belongs to another skill`
)
}
}
}
+147
View File
@@ -0,0 +1,147 @@
import dns from 'node:dns'
import type { AxiosInstance } from 'axios'
import axios from 'axios'
import { LEON_VERSION, NODEJS_BRIDGE_VERSION } from '@bridge/constants'
interface NetworkOptions {
/** `baseURL` will be prepended to `url`. It can be convenient to set `baseURL` for an instance of `Network` to pass relative URLs. */
baseURL?: string
}
interface NetworkRequestOptions {
/** Server URL that will be used for the request. */
url: string
/** Request method to be used when making the request. */
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
/** Data to be sent as the request body. */
data?: Record<string, unknown>
/** Custom headers to be sent. */
headers?: Record<string, string>
}
interface NetworkResponse<ResponseData> {
/** Data provided by the server. */
data: ResponseData
/** HTTP status code from the server response. */
statusCode: number
/** Options that was provided for the request. */
options: NetworkRequestOptions & NetworkOptions
}
export class NetworkError<ResponseErrorData = unknown> extends Error {
public readonly response: NetworkResponse<ResponseErrorData>
public constructor(response: NetworkResponse<ResponseErrorData>) {
super(`[NetworkError]: ${response.statusCode} ${response.data}`)
this.response = response
Object.setPrototypeOf(this, NetworkError.prototype)
}
}
export class Network {
private readonly options: NetworkOptions
private axios: AxiosInstance
public constructor(options: NetworkOptions = {}) {
this.options = options
this.axios = axios.create({
baseURL: this.options.baseURL
})
}
/**
* Send HTTP request
* @param options Request options
* @example request({ url: '/send', method: 'POST', data: { message: 'Hi' } })
*/
public async request<ResponseData = unknown, ResponseErrorData = unknown>(
options: NetworkRequestOptions
): Promise<NetworkResponse<ResponseData>> {
try {
const response = await this.axios.request<string>({
url: options.url,
method: options.method.toLowerCase(),
data: options.data,
transformResponse: (data) => {
return data
},
headers: {
'User-Agent': `Leon Personal Assistant ${LEON_VERSION} - Node.js Bridge ${NODEJS_BRIDGE_VERSION}`,
...options.headers
}
})
let data = {} as ResponseData
try {
data = JSON.parse(response.data)
} catch {
data = response.data as ResponseData
}
return {
data,
statusCode: response.status,
options: {
...this.options,
...options
}
}
} catch (error) {
let statusCode = 500
let dataRawText = ''
if (axios.isAxiosError(error)) {
dataRawText = error?.response?.data ?? ''
statusCode = error?.response?.status ?? 500
}
let data: ResponseErrorData
try {
data = JSON.parse(dataRawText)
} catch {
data = dataRawText as ResponseErrorData
}
throw new NetworkError<ResponseErrorData>({
data,
statusCode,
options: {
...this.options,
...options
}
})
}
}
/**
* Check if error is a network error
* @param error Error to check
* @example isNetworkError(error) // false
*/
public isNetworkError<ResponseErrorData = unknown>(
error: unknown
): error is NetworkError<ResponseErrorData> {
return error instanceof NetworkError
}
/**
* Verify whether there is an Internet connectivity
* @example isNetworkAvailable() // true
*/
public async isNetworkAvailable(): Promise<boolean> {
try {
await dns.promises.resolve('getleon.ai')
return true
} catch {
return false
}
}
}
@@ -0,0 +1 @@
export { default } from 'lodash'
+125
View File
@@ -0,0 +1,125 @@
import path from 'node:path'
import fs from 'node:fs'
import { SKILL_PATH } from '@bridge/constants'
export class Settings<T extends Record<string, unknown>> {
private readonly settingsPath: string
private readonly settingsSamplePath: string
public constructor() {
this.settingsPath = path.join(SKILL_PATH, 'src', 'settings.json')
this.settingsSamplePath = path.join(
SKILL_PATH,
'src',
'settings.sample.json'
)
}
/**
* Check if a setting is already set
* @param key The key to verify whether its value is set
* @returns isSettingSet('apiKey') // true
*/
public async isSettingSet(key: string): Promise<boolean> {
const settingsSample = await this.getSettingsSample()
const settings = await this.get()
return (
!!settings[key] &&
JSON.stringify(settings[key]) !== JSON.stringify(settingsSample[key])
)
}
/**
* Clear the settings and set it to the default settings.sample.json file
* @example clear()
*/
public async clear(): Promise<void> {
const settingsSample = await this.getSettingsSample()
await this.set(settingsSample)
}
private async getSettingsSample(): Promise<T> {
try {
return JSON.parse(
await fs.promises.readFile(this.settingsSamplePath, 'utf8')
)
} catch (e) {
console.error(
`Error while reading settings sample at "${this.settingsSamplePath}":`,
e
)
throw e
}
}
/**
* Get the settings
* @param key The key of the setting to get
* @example get('API_KEY') // 'value'
* @example get() // { API_KEY: 'value' }
*/
public async get<Key extends keyof T>(key: Key): Promise<T[Key]>
public async get(): Promise<T>
public async get<Key extends keyof T>(key?: Key): Promise<T | T[Key]> {
try {
if (!fs.existsSync(this.settingsPath)) {
await this.clear()
}
const settings = JSON.parse(
await fs.promises.readFile(this.settingsPath, 'utf8')
)
if (key != null) {
return settings[key]
}
return settings
} catch (e) {
console.error(
`Error while reading settings at "${this.settingsPath}":`,
e
)
throw e
}
}
/**
* Set the settings
* @param key The key of the setting to set
* @param value The value of the setting to set
* @example set({ API_KEY: 'value' }) // { API_KEY: 'value' }
*/
public async set<Key extends keyof T>(key: Key, value: T[Key]): Promise<T>
public async set(settings: T): Promise<T>
public async set<Key extends keyof T>(
keyOrSettings: Key | T,
value?: T[Key]
): Promise<T> {
try {
const settings = await this.get()
const newSettings =
typeof keyOrSettings === 'object'
? keyOrSettings
: { ...settings, [keyOrSettings]: value }
await fs.promises.writeFile(
this.settingsPath,
JSON.stringify(newSettings, null, 2)
)
return newSettings
} catch (e) {
console.error(
`Error while writing settings at "${this.settingsPath}":`,
e
)
throw e
}
}
}
+37
View File
@@ -0,0 +1,37 @@
/**
* Action types
*/
import type {
ActionParams,
IntentObject,
SkillAnswerCoreData,
SkillAnswerOutput
} from '@/core/brain/types'
import type { SkillAnswerConfigSchema } from '@/schemas/skill-schemas'
export type { ActionParams, IntentObject }
export * from '@/core/nlp/types'
export type ActionFunction = (params: ActionParams) => Promise<void>
/**
* Answer types
*/
export interface Answer {
key?: string
widget?: unknown // TODO
data?: AnswerData
core?: SkillAnswerCoreData
}
export interface TextAnswer extends Answer {
key: string
}
export interface WidgetAnswer extends Answer {
widget: unknown
key?: string
}
export type AnswerData = Record<string, string | number> | null
export type AnswerInput = TextAnswer | WidgetAnswer
export type AnswerOutput = SkillAnswerOutput
export type AnswerConfig = SkillAnswerConfigSchema
+9
View File
@@ -0,0 +1,9 @@
export abstract class Widget<T> {
public readonly type: string
public readonly options: T
protected constructor(options: T) {
this.type = this.constructor.name
this.options = options
}
}
+1
View File
@@ -0,0 +1 @@
export const VERSION = '1.1.0'
+24
View File
@@ -0,0 +1,24 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist/bin",
"rootDir": "../../",
"baseUrl": ".",
"paths": {
"@@/*": ["../../*"],
"@/*": ["../../server/src/*"],
"@server/*": ["../../server/src/*"],
"@bridge/*": ["./src/*"],
"@sdk/*": ["./src/sdk/*"]
},
"exactOptionalPropertyTypes": false,
"declaration": true
},
"ts-node": {
"swc": true,
"require": ["tsconfig-paths/register"],
"files": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
-21
View File
@@ -1,21 +0,0 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[requires]
python_version = "3.9.10"
[packages]
requests = "==2.21.0"
pytube = "==9.5.0"
tinydb = "==4.7.0"
beautifulsoup4 = "==4.7.1"
spacy = "==3.4.0"
setuptools = "==60.9.3"
wheel = "==0.37.1"
torch = "==1.12.1"
python-dotenv = "==0.19.2"
geonamescache = "==1.3.0"
[dev-packages]
-592
View File
@@ -1,592 +0,0 @@
{
"_meta": {
"hash": {
"sha256": "2db39af98e7ccc96ec933a4b2cbe921addef26899daf69d7d4d8ddb01ef5f746"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.9.10"
},
"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"
},
"blis": {
"hashes": [
"sha256:0c3245e42c7c6ba0d68d7dff4171d11bb08174e639bc8edd52a1fd831de1d903",
"sha256:0f7bfdee74ac695c35360ace00f2630c1b47406dc0b99ba9211bfa8588bfbed9",
"sha256:159a1a9b32213d99d1415789ac66ed8d23442a696d9d376c66d7b791d3eae575",
"sha256:17df5ac7d9a9dbbf0415f8f8392fbdf1790fa394f89d695bae5e2e7e361c852b",
"sha256:1e970ba1eb12ca38fb5d57f379472125bc3f5106c8214dc847fe79b027212135",
"sha256:1f5fa330ab66d0e92a845b1db361ec8bf3dc4bc7e0dc0ded94f36b8e9f731650",
"sha256:2056b0d9722f5505cfa94904c6248021197c63ecf45804dcf117f8f1c6160ab6",
"sha256:25cdb9775699c1b926df514a5d4c28016c11722a66211f1024b2f21373f50de2",
"sha256:2778fe0ba0e25c157839fdd19ed66b9a340c92d4e92e707b7fa9aa21c51cb254",
"sha256:294421b720c2de904908de841464c667e1a5c5e9f3db6931dfa29cf369d3653a",
"sha256:2db369a4f95927be37e11790dd1ccbf99fd6201eaffbcf408546db847b7b5740",
"sha256:354cadff661a1452c886f541b84018770ddb4c134844c56e7c1a30aa4bcc473d",
"sha256:4e7b7b8bc8cf5e82958bbc393e0167318a930d394cbbf04c1ba18cfabaef5818",
"sha256:63735128c9cae44dc6cbf7557327385df0c4ed2dc2c45a00dabfde1e4d00802d",
"sha256:66b8ca1a2eb8f1e0563a592aae4b8682b66189ad560e3b8221d93eab0cb76582",
"sha256:90f17543e0aa3bc379d139867467df2c365ffaf5b61988de12dbba6dbbc9fab4",
"sha256:95d22d3007cb454d11a478331690629861f7d40b4668f9fccfd13b6507ed099b",
"sha256:96ff4c0c1ceab9f94c14b3281f3cef82f593c48c3b5f6169bd51cdcd315e0a6e",
"sha256:ae5b06fe3b94645ac5d93cbc7c0129639cc3e0d50b4efb361a20a9e160277a92",
"sha256:bf60f634481c3d0faf831ac4f2d1c75343e98f714dc88e3fb3c329758577e772",
"sha256:bfa56e7ef14ae607d8444eb344d22f252a2e0b0f9bfa4bdc9b0c48a9f96b5461",
"sha256:cac120e3c0517095d3c39278e8b6b1102b1add0e1f4e161a87f313d8ee7c12e1",
"sha256:f576ad64b772b6fd7df6ef94986235f321983dc870d0f76d78c931bafc41cfa4",
"sha256:f7d541bb06323aa350163ba4a3ad00e8effb3b53d4c58ee6228224f3928b6c57"
],
"version": "==0.7.8"
},
"catalogue": {
"hashes": [
"sha256:2d786e229d8d202b4f8a2a059858e45a2331201d831e39746732daa704b99f69",
"sha256:b325c77659208bfb6af1b0d93b1a1aa4112e1bb29a4c5ced816758a722f0e388"
],
"markers": "python_version >= '3.6'",
"version": "==2.0.8"
},
"certifi": {
"hashes": [
"sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d",
"sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"
],
"markers": "python_version >= '3.6'",
"version": "==2022.6.15"
},
"chardet": {
"hashes": [
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
],
"version": "==3.0.4"
},
"click": {
"hashes": [
"sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
"sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"
],
"markers": "python_version >= '3.7'",
"version": "==8.1.3"
},
"cymem": {
"hashes": [
"sha256:04676d696596b0db3f3c5a3936bab12fb6f24278921a6622bb185e61765b2b4d",
"sha256:169725b5816959d34de2545b33fee6a8021a6e08818794a426c5a4f981f17e5e",
"sha256:228bd261a85d92d870ed358f263ee028ac026302304f2186827377a3895c5819",
"sha256:2aa3fa467d906cd2c27fa0a2e2952dd7925f5fcc7973fab6d815ef6acb25aad8",
"sha256:38b51ac23f914d85b197dbd0fb2d3e2de9bf6112b9b30f16b45dbb6c9b4e509d",
"sha256:4749f220e4c06ec44eb10de13794ff0508cdc4f8eff656cf49cab2cdb3122c0c",
"sha256:492084aef23ac2ff3da3729e9d36340bc91a96c2dc8c3a82a1926e384ab52412",
"sha256:4f87fe087f2ae36c3e20e2b1a29d7f76a28c035372d0a97655f26223d975235a",
"sha256:5d631239bfb07293ee444b269656308da952b6b003b12332ccb1c624dbfcda4b",
"sha256:6b0d1a6b0a1296f31fa9e4b7ae5ea49394084ecc883b1ae6fec4844403c43468",
"sha256:700540b68e96a7056d0691d467df2bbaaf0934a3e6fe2383669998cbee19580a",
"sha256:971cf0a8437dfb4185c3049c086e463612fe849efadc0f5cc153fc81c501da7d",
"sha256:a261f51796a2705f3900ed22b8442519a0f230f50a816fb5bd89cb9b027dc5ac",
"sha256:a93fba62fe79dbf6fc4d5b6d804a6e114b44af3ff3d40a28833ee39f21bd336b",
"sha256:af3c01e6b20f9e6c07c7d7cdb7f710e49889d3906c9a3e039546ee6636a34b9a",
"sha256:b8e1c18bb00800425576710468299153caad20c64ddb6819d40a6a34e21ee21c",
"sha256:c59293b232b53ebb47427f16cf648e937022f489cff36c11d1d8a1f0075b6609",
"sha256:c59ca1072769cb6c3eade59de9e080ff2cecde0122f7e0ca0dc9ef2ed9240f0e",
"sha256:cd818356b635d8ae546e152a6f2b95f00e959d128a16155c275b0c202cd6312b",
"sha256:d4dc378fb9dda3b0529361fe32cfe1a6de0fc16bb40c710aaec8d217534928d2",
"sha256:d7a59cef8f2fa25d12e2c30138f8623acbd43ad2715e730a709e49c5eef8e1b0",
"sha256:dd52d8a81881804625df88453611175ab7e0099b34f52204da1f6940cf2e83c9",
"sha256:ea535f74ab6024e7416f93de564e5c81fb7c0964b96280de66f60aeb05f0cf53",
"sha256:ee73a48c5a7e0f2acf6830ddc958ffafd7a614cfb79d14017a459bc7a7145ecd"
],
"version": "==2.0.6"
},
"geonamescache": {
"hashes": [
"sha256:5a1fc774a3282d324952b87eb5c2c13684055e68e829526909c76c2fffb84f8f",
"sha256:efa1dd28a87632303c5d882cc52718f04cf28e85f1cc7d6afdf8a6ba7c5ab1dc"
],
"index": "pypi",
"version": "==1.3.0"
},
"idna": {
"hashes": [
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
],
"version": "==2.8"
},
"jinja2": {
"hashes": [
"sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852",
"sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"
],
"markers": "python_version >= '3.7'",
"version": "==3.1.2"
},
"langcodes": {
"hashes": [
"sha256:4d89fc9acb6e9c8fdef70bcdf376113a3db09b67285d9e1d534de6d8818e7e69",
"sha256:794d07d5a28781231ac335a1561b8442f8648ca07cd518310aeb45d6f0807ef6"
],
"markers": "python_version >= '3.6'",
"version": "==3.3.0"
},
"markupsafe": {
"hashes": [
"sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003",
"sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88",
"sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5",
"sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7",
"sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a",
"sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603",
"sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1",
"sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135",
"sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247",
"sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6",
"sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601",
"sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77",
"sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02",
"sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e",
"sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63",
"sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f",
"sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980",
"sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b",
"sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812",
"sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff",
"sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96",
"sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1",
"sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925",
"sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a",
"sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6",
"sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e",
"sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f",
"sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4",
"sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f",
"sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3",
"sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c",
"sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a",
"sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417",
"sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a",
"sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a",
"sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37",
"sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452",
"sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933",
"sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a",
"sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"
],
"markers": "python_version >= '3.7'",
"version": "==2.1.1"
},
"murmurhash": {
"hashes": [
"sha256:1b3d584705bf7be487c09a79f35a45a45f9b2a8a2120ccca47692d24bc6329ff",
"sha256:1fd2dac6ea401310d1245f68a758ff86bc58ba28fe3ec41c3fec42d4cea249a0",
"sha256:262abc461353bcd724daef11aa236fed95ce2c5642847fe18f835721ae0356d6",
"sha256:2d001688bd2106fbd84a99d4c0292339de7a0a96c8516596032a3e9389adba25",
"sha256:341a499cb30fae9f305479650728d832744a2e37f8e7fbdbfaedd8676b4e822d",
"sha256:37c8207377110fa791051e2998d6d8d84d0a066010be9e8e41d1af1c41a65f14",
"sha256:43d161ecdc1923ec401efb4e78d1da848c4aa957a49c08c29af276a7696c5336",
"sha256:469a5c8959988ce8c395be2c623a45df8112783d87445b6a230596807e7786d2",
"sha256:60637d74c73be1259d9c07d03726b75907ad9e8dd47f946b21244113cdc52843",
"sha256:66857bf301c676917d7ceba3fa42fb82aa34605d6b9788612c532bc6d69af9f9",
"sha256:67d48fc47edc40fef9eb19c6e9ee3d4321f864a3d6566217812615c79fa4ff16",
"sha256:79a3ef14cab2bdc2cf4814eb30d8237d28ddc9e6fd1859d3d61857162979a630",
"sha256:88c569636b0bad29a3854f1d324636e0561423da75ef6e5bc5b363f8d2143692",
"sha256:88eb9b866d2e6690249eb305cce509eeffbf2a59c42eb47e8aab6a3b46bd4a54",
"sha256:8bb03aad842837a64b0c1d2ed22b50eba85f9fa51476c8bc0a77c366a979f1f3",
"sha256:97231ac1f42d29b6e1a3e2e8d23ab32deb37ccd55b00554d74e4bd8f0e73b7d7",
"sha256:9fe289e88b18b388d6029a17839113a6090ead3b04c904cba0b64961f0db7d02",
"sha256:aaa8df50c83468a6be52e29a85d7d54b981b43cd1c9b501b3a2d80acbe87283e",
"sha256:ac0701b6823a8a88412c2a1410b1afbd25ee20666ea9d4ad1d3016c7d55ac433",
"sha256:b9bab3d46076ac65b38e9f2823ce3e45d7a2a798e3dd466eb594de1802732979",
"sha256:bafe99db2f05d8ecd9b39250cf37f561b4281d081b7c10bd283d6c1fd685bedf",
"sha256:bd4584443731a9d73b87970f9b08c86162d35acc48b63c78cf215bcebeb8b5b0",
"sha256:cbf5b97feaba000df8e5b16ce23e426ea9b52e0e442e6451b4687b6f7797804e",
"sha256:d3d64b6a24203da05964c708856f2ff46653dbd115d3bba326e0c6dc1d4ea511",
"sha256:d55e956cebe38ef96360949b130cbfb605c3ffc04e3b770c6e0299308c46c880"
],
"markers": "python_version >= '3.6'",
"version": "==1.0.8"
},
"numpy": {
"hashes": [
"sha256:17e5226674f6ea79e14e3b91bfbc153fdf3ac13f5cc54ee7bc8fdbe820a32da0",
"sha256:2bd879d3ca4b6f39b7770829f73278b7c5e248c91d538aab1e506c628353e47f",
"sha256:4f41f5bf20d9a521f8cab3a34557cd77b6f205ab2116651f12959714494268b0",
"sha256:5593f67e66dea4e237f5af998d31a43e447786b2154ba1ad833676c788f37cde",
"sha256:5e28cd64624dc2354a349152599e55308eb6ca95a13ce6a7d5679ebff2962913",
"sha256:633679a472934b1c20a12ed0c9a6c9eb167fbb4cb89031939bfd03dd9dbc62b8",
"sha256:806970e69106556d1dd200e26647e9bee5e2b3f1814f9da104a943e8d548ca38",
"sha256:806cc25d5c43e240db709875e947076b2826f47c2c340a5a2f36da5bb10c58d6",
"sha256:8247f01c4721479e482cc2f9f7d973f3f47810cbc8c65e38fd1bbd3141cc9842",
"sha256:8ebf7e194b89bc66b78475bd3624d92980fca4e5bb86dda08d677d786fefc414",
"sha256:8ecb818231afe5f0f568c81f12ce50f2b828ff2b27487520d85eb44c71313b9e",
"sha256:8f9d84a24889ebb4c641a9b99e54adb8cab50972f0166a3abc14c3b93163f074",
"sha256:909c56c4d4341ec8315291a105169d8aae732cfb4c250fbc375a1efb7a844f8f",
"sha256:9b83d48e464f393d46e8dd8171687394d39bc5abfe2978896b77dc2604e8635d",
"sha256:ac987b35df8c2a2eab495ee206658117e9ce867acf3ccb376a19e83070e69418",
"sha256:b78d00e48261fbbd04aa0d7427cf78d18401ee0abd89c7559bbf422e5b1c7d01",
"sha256:b8b97a8a87cadcd3f94659b4ef6ec056261fa1e1c3317f4193ac231d4df70215",
"sha256:bd5b7ccae24e3d8501ee5563e82febc1771e73bd268eef82a1e8d2b4d556ae66",
"sha256:bdc02c0235b261925102b1bd586579b7158e9d0d07ecb61148a1799214a4afd5",
"sha256:be6b350dfbc7f708d9d853663772a9310783ea58f6035eec649fb9c4371b5389",
"sha256:c403c81bb8ffb1c993d0165a11493fd4bf1353d258f6997b3ee288b0a48fce77",
"sha256:cf8c6aed12a935abf2e290860af8e77b26a042eb7f2582ff83dc7ed5f963340c",
"sha256:d98addfd3c8728ee8b2c49126f3c44c703e2b005d4a95998e2167af176a9e722",
"sha256:dc76bca1ca98f4b122114435f83f1fcf3c0fe48e4e6f660e07996abf2f53903c",
"sha256:dec198619b7dbd6db58603cd256e092bcadef22a796f778bf87f8592b468441d",
"sha256:df28dda02c9328e122661f399f7655cdcbcf22ea42daa3650a26bce08a187450",
"sha256:e603ca1fb47b913942f3e660a15e55a9ebca906857edfea476ae5f0fe9b457d5",
"sha256:ecfdd68d334a6b97472ed032b5b37a30d8217c097acfff15e8452c710e775524"
],
"markers": "python_version >= '3.8'",
"version": "==1.23.2"
},
"packaging": {
"hashes": [
"sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb",
"sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"
],
"markers": "python_version >= '3.6'",
"version": "==21.3"
},
"pathy": {
"hashes": [
"sha256:3178215bdadf3741107d987020be0fb5b59888f60f96de43cce5fe45d9d4b64a",
"sha256:a7aa9794fade161bb4c28a33c5bc2c6bf41f61ec5eee51cfa8914f0a433447e1"
],
"markers": "python_version >= '3.6'",
"version": "==0.6.2"
},
"preshed": {
"hashes": [
"sha256:0435d4647037fc534bf1bdcf87fdbf206a935abe5e68c9814277090c62e6b6ef",
"sha256:06be22a8a2757e61b2c3cc854e9c2d2361fb3b6528deb2af5b5079e6da670405",
"sha256:0feae8cfcf46fb97cd8118d150245ae31c68ca9c68e514ab33e1e33a90eee459",
"sha256:13140808a56ce67e30579a40e293d16dedeb85fd56c74cd024c44f7a9f966432",
"sha256:1573d42bdec168081242ec88d40288000f84a5afb66a60517e4220950fe62f17",
"sha256:1acc514a41142a086c2ebc19cd368534e27337511b3a2936c28455e0b42f3eb3",
"sha256:24935553ff18f39195b468984d784b2bb7825b6f43385a2d0d05b02e55090815",
"sha256:3741b459f50dde7a22b88d75d1fc4a7e6e36402db43c4f690df44e966ff1bd54",
"sha256:37900e1e923a35fc15f56cd02f4a899e5903790113256fedbf527a5b3f8e2214",
"sha256:39cd2a0ab1adb11452c617831ea0ccea7d1712f2812d1744738735987513113a",
"sha256:3b1d747ab1e233bc4bccdc4baee7531c5661459d7a8d67845833f7c857b371fb",
"sha256:3e7022fe473e677088cda6e0538669fe240943e3eb7ff88447d690a52c6d87ce",
"sha256:4a5825b80a450198cb582b3b4004c95e9d4eca268e89c126a9d71e8f26b69338",
"sha256:4a99d4f46a4e317245f2370eb13d0e3c6747f66752a8d88dbc9284f4fd25e05f",
"sha256:5eeafb832009a3e1ed92a412f19499c86e687308d6d56617772d42ee4de26ccf",
"sha256:6e1b61c9797443ee42cb314c91ab178791b80397c2e98410f5173806604458b1",
"sha256:6e518275d1b84bed779ddc69eabeb9283bf5f9f5482bcaf1b099d2877b050a0d",
"sha256:7cc3166ed48d603131912da40a7638b3655d6990032a770303346e2f5f4154d4",
"sha256:7f97c3d2dc9713139cc096af9e4455ced33f9e90ce9d29f739db5adff6ae6a06",
"sha256:8d57469e5e52d37342588804d3ce70128ab42f42e5babaeea0d29d3609ce7b30",
"sha256:9785e3de0dca8f4d6040eba89e50e72012ce94d269583502d14f958624daea73",
"sha256:9c700a0744f5ede86ff8754522bd54f92f5b75f58046bc3f17c60d1c25529f41",
"sha256:a9ed0dc685aa058a1a76111f476715ccfb4df12800c3681e401d6af7384f570d",
"sha256:ab4168fe1d31707e3473d1bb57d3c88dac9151b3cbe61d22f14bf691e04aaa1b",
"sha256:d2cc8d8df139d5935464530d45ff0e1209752e9748792cdf774b5d5fc230c07a"
],
"markers": "python_version >= '3.6'",
"version": "==3.0.7"
},
"pydantic": {
"hashes": [
"sha256:1061c6ee6204f4f5a27133126854948e3b3d51fcc16ead2e5d04378c199b2f44",
"sha256:19b5686387ea0d1ea52ecc4cffb71abb21702c5e5b2ac626fd4dbaa0834aa49d",
"sha256:2bd446bdb7755c3a94e56d7bdfd3ee92396070efa8ef3a34fab9579fe6aa1d84",
"sha256:328558c9f2eed77bd8fffad3cef39dbbe3edc7044517f4625a769d45d4cf7555",
"sha256:32e0b4fb13ad4db4058a7c3c80e2569adbd810c25e6ca3bbd8b2a9cc2cc871d7",
"sha256:3ee0d69b2a5b341fc7927e92cae7ddcfd95e624dfc4870b32a85568bd65e6131",
"sha256:4aafd4e55e8ad5bd1b19572ea2df546ccace7945853832bb99422a79c70ce9b8",
"sha256:4b3946f87e5cef3ba2e7bd3a4eb5a20385fe36521d6cc1ebf3c08a6697c6cfb3",
"sha256:4de71c718c9756d679420c69f216776c2e977459f77e8f679a4a961dc7304a56",
"sha256:5565a49effe38d51882cb7bac18bda013cdb34d80ac336428e8908f0b72499b0",
"sha256:5803ad846cdd1ed0d97eb00292b870c29c1f03732a010e66908ff48a762f20e4",
"sha256:5da164119602212a3fe7e3bc08911a89db4710ae51444b4224c2382fd09ad453",
"sha256:615661bfc37e82ac677543704437ff737418e4ea04bef9cf11c6d27346606044",
"sha256:78a4d6bdfd116a559aeec9a4cfe77dda62acc6233f8b56a716edad2651023e5e",
"sha256:7d0f183b305629765910eaad707800d2f47c6ac5bcfb8c6397abdc30b69eeb15",
"sha256:7ead3cd020d526f75b4188e0a8d71c0dbbe1b4b6b5dc0ea775a93aca16256aeb",
"sha256:84d76ecc908d917f4684b354a39fd885d69dd0491be175f3465fe4b59811c001",
"sha256:8cb0bc509bfb71305d7a59d00163d5f9fc4530f0881ea32c74ff4f74c85f3d3d",
"sha256:91089b2e281713f3893cd01d8e576771cd5bfdfbff5d0ed95969f47ef6d676c3",
"sha256:9c9e04a6cdb7a363d7cb3ccf0efea51e0abb48e180c0d31dca8d247967d85c6e",
"sha256:a8c5360a0297a713b4123608a7909e6869e1b56d0e96eb0d792c27585d40757f",
"sha256:afacf6d2a41ed91fc631bade88b1d319c51ab5418870802cedb590b709c5ae3c",
"sha256:b34ba24f3e2d0b39b43f0ca62008f7ba962cff51efa56e64ee25c4af6eed987b",
"sha256:bd67cb2c2d9602ad159389c29e4ca964b86fa2f35c2faef54c3eb28b4efd36c8",
"sha256:c0f5e142ef8217019e3eef6ae1b6b55f09a7a15972958d44fbd228214cede567",
"sha256:cdb4272678db803ddf94caa4f94f8672e9a46bae4a44f167095e4d06fec12979",
"sha256:d70916235d478404a3fa8c997b003b5f33aeac4686ac1baa767234a0f8ac2326",
"sha256:d8ce3fb0841763a89322ea0432f1f59a2d3feae07a63ea2c958b2315e1ae8adb",
"sha256:e0b214e57623a535936005797567231a12d0da0c29711eb3514bc2b3cd008d0f",
"sha256:e631c70c9280e3129f071635b81207cad85e6c08e253539467e4ead0e5b219aa",
"sha256:e78578f0c7481c850d1c969aca9a65405887003484d24f6110458fb02cca7747",
"sha256:f0ca86b525264daa5f6b192f216a0d1e860b7383e3da1c65a1908f9c02f42801",
"sha256:f1a68f4f65a9ee64b6ccccb5bf7e17db07caebd2730109cb8a95863cfa9c4e55",
"sha256:fafe841be1103f340a24977f61dee76172e4ae5f647ab9e7fd1e1fca51524f08",
"sha256:ff68fc85355532ea77559ede81f35fff79a6a5543477e168ab3a381887caea76"
],
"markers": "python_full_version >= '3.6.1'",
"version": "==1.9.2"
},
"pyparsing": {
"hashes": [
"sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb",
"sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"
],
"markers": "python_full_version >= '3.6.8'",
"version": "==3.0.9"
},
"python-dotenv": {
"hashes": [
"sha256:32b2bdc1873fd3a3c346da1c6db83d0053c3c62f28f1f38516070c4c8971b1d3",
"sha256:a5de49a31e953b45ff2d2fd434bbc2670e8db5273606c1e737cc6b93eff3655f"
],
"index": "pypi",
"version": "==0.19.2"
},
"pytube": {
"hashes": [
"sha256:2a32f3475f063d25e7b7a7434a93b51d59aadbbda7ed24af48f097b2876c0964",
"sha256:9190f5e13b05a4fc1586eedd46f7164c3a4318607d455a1f7c126699ddde724f"
],
"index": "pypi",
"version": "==9.5.0"
},
"requests": {
"hashes": [
"sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e",
"sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b"
],
"index": "pypi",
"version": "==2.21.0"
},
"setuptools": {
"hashes": [
"sha256:2347b2b432c891a863acadca2da9ac101eae6169b1d3dfee2ec605ecd50dbfe5",
"sha256:e4f30b9f84e5ab3decf945113119649fec09c1fc3507c6ebffec75646c56e62b"
],
"index": "pypi",
"version": "==60.9.3"
},
"smart-open": {
"hashes": [
"sha256:71d14489da58b60ce12fc3ecb823facc59a8b23cd1b58edb97175640350d3a62",
"sha256:75abf758717a92a8f53aa96953f0c245c8cedf8e1e4184903db3659b419d4c17"
],
"markers": "python_version >= '3.6' and python_version < '4.0'",
"version": "==5.2.1"
},
"soupsieve": {
"hashes": [
"sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759",
"sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"
],
"markers": "python_version >= '3.6'",
"version": "==2.3.2.post1"
},
"spacy": {
"hashes": [
"sha256:0720297328e32c1952a6c2eb9f5d9aa7b11b95588886c9117a7030c2dd1a0619",
"sha256:344f262344f1c078e6159543eecc09b32b70c138deb1f9fe01c49cd89002730f",
"sha256:3c99920830c1cbf3be169b7817863d88fa07c465540ebf0eed304ba106201cb4",
"sha256:3caaa36f8fc95776a558ec2a4625f5cd22c1fa7990b1d9ab650709851586cec4",
"sha256:3ccd1a9f56759e5f0f9efdf57119a06702ad59c045dde0b3830b5472593e09ef",
"sha256:4dc6ea142866f7042a710597ad2c3939bde3486c27d0eb11fcfb079245c72cb3",
"sha256:5b95eff2f9e012991c27e93c038ef8f3ca4132ec7e66e097833ef22f263a46da",
"sha256:6c45fe868973dd44afa4a200f72fd2d7288548ae6bc201fc5a6d5ffb0a4949b3",
"sha256:6d147595db91191a0a748e33629c99fb5e7849af5100237e058fd832b7254242",
"sha256:7039fe789caa9753fa0a66b9391f0f93d49e6cb1017336c6b0842220a04346a8",
"sha256:76ad38af7205dbc97e1a3dd0956f5d97b4d31542adbb039eb161bf5f08e386ec",
"sha256:9c9167631733f8618f8928745fc740f3fd680994993dce2db7a4dd2b85d8919e",
"sha256:9e631c07560457926860b1c64bf2a62e4e4c25359085024ea3847cc7e2fc39ee",
"sha256:9ff04736c88475a950726c92a8e87ea6f42ca49ae60e0dc9612b456333f25e9c",
"sha256:a10451847eb7983ba1fe05ab87a37367e00e2807fe633d17926626cb2dacd10f",
"sha256:a4fa15d13ef73089680506c91e27630005537b9b68d2d4e736cec26cb29a3f47",
"sha256:b350dc2321b4cbeac65419ec0cb0d0697f991c0a3b4ca4236438fbcce77e9421",
"sha256:b3b336aed79d7610ad33fac1557de8b96a1421aa8c4d41604700d1eb1c7e34fd",
"sha256:dbcf52b49a7221202f7a388993562c9dd610ed621697a4684583514aed63c06a",
"sha256:e0bec5befbb6bbc11d4d984e8f864dcbdf9e9274dbc5dbc349b931a2dd9ec84c",
"sha256:eb39f5551f4ef6475fa7f46fec347553680ab0e917d2a790384aa75d5797333d",
"sha256:eca827077f32965c1931ccb34375c29a7b9c321818e1773248004719b27b008f",
"sha256:f0b26babf0d7d9b07f8350c390b19445207a9f84cac7a81ac2b6d0cbcb47357a",
"sha256:ff0687a6f3e822655650a5ba45af6738b879962806f09ac3903768b0b67cf415"
],
"index": "pypi",
"version": "==3.4.0"
},
"spacy-legacy": {
"hashes": [
"sha256:16104595d8ab1b7267f817a449ad1f986eb1f2a2edf1050748f08739a479679a",
"sha256:8526a54d178dee9b7f218d43e5c21362c59056c5da23380b319b56043e9211f3"
],
"markers": "python_version >= '3.6'",
"version": "==3.0.10"
},
"spacy-loggers": {
"hashes": [
"sha256:00f6fd554db9fd1fde6501b23e1f0e72f6eef14bb1e7fc15456d11d1d2de92ca",
"sha256:f74386b390a023f9615dcb499b7b4ad63338236a8187f0ec4dfe265a9f665ee8"
],
"markers": "python_version >= '3.6'",
"version": "==1.0.3"
},
"srsly": {
"hashes": [
"sha256:1a90233d5ef978db5887d0d159fa5652bfecde353812c4b4e293791460db2211",
"sha256:1ce17dcf2acd26f3add82d94a29d264bd72364071a29dccdd335d4c1826e4e98",
"sha256:2702ab0858bb27cefe684cc01be5f28ca05d204dc60b52efd122434864a347bd",
"sha256:30eb733770b69593ac31ff84df41455e45bb2e48bf44c1382bc40f10be3e8936",
"sha256:372204bbb7089ecc99fa984f0ef6c06063dcf6ac1abf0d896605486a2cdf5779",
"sha256:47e6ce2aed95aa2f55b9a967f34f82cf170ff2c0e126d3422ede106dbfe4922c",
"sha256:4bb401bf8477b685d933670bcec6b430b8e8025cd68da1e6bacfd57f6d8191d5",
"sha256:4efa441fc54d3f2300c6ce48f9e44ed9850f2627c0ebeaa320b206b470679e63",
"sha256:5054c25a9b923d33f54e7bbab8c5be669db94b9bab87e348439bf85f3d644825",
"sha256:708623d4e4503fee4cd9c727d471ab6918b664e177fbe413b0ddd2debb45437a",
"sha256:74acd1e52235fa46a3ede5c34f33adf8bad4050bbf44ec04d76369c4aed9041e",
"sha256:8235975d943587b4d17fc10e860b11d9248f58c0b74e95f911bd70b24542c630",
"sha256:8abfca6b34c8a03608ca9c6e54e315c30d240cc3aae942a412c52742d15a089b",
"sha256:930164882db523020c7660b12a7f3b0d9266781012004fa2e8ad6150412493e1",
"sha256:964bdc3f8ff4a5e66ab2685e001b78f6ca2ce68fe4817842f4f342abad2fddbb",
"sha256:a6d03f65c079e98fcd635f19c65c0ddb7b06f1069332fb87c74e36d7c3ca883d",
"sha256:bd4f7e2b43187d4fc5095fb01fe7b7868a777eb12315ff1ac07e3243fd4493e8",
"sha256:c85962bf1d6f52b9d5d2e727a4e3c558a6b00cecadea29141f122f6c83147cca",
"sha256:c96963e1db238014525f924d5d5058ee9386e129c82f24cc63fead41902e1c06",
"sha256:cb65e2d67980419072379abef1e5b1d3b11931082bc038b0295d35a56376c3d5",
"sha256:d6733ddaf0b2db54f334a2e881f1112be0ff48f113c96bcd88d1aec1ff871ca8",
"sha256:e0c6510716e5cb2abf11abcbe06338283b01690955342e78a76fcb9953b7e3ba",
"sha256:e1866a1a5ea8c7bb213b0c3c7a7b97cd6d9a3ca26f2f59e441d47fa9720fb399",
"sha256:e8a06581627b6712f19c60241b7c14c2bb29ce86ef04f791379a79f1b249a128"
],
"markers": "python_version >= '3.6'",
"version": "==2.4.4"
},
"thinc": {
"hashes": [
"sha256:133f585941801382dd52201eb5b857426dfa1adca298b052875c9a07943c18b0",
"sha256:21ec24cdb3248617b41d4bdf13de557fdd994bca73b107c30530b7fcd590c9c2",
"sha256:2766914adae8768aaad0d18c3968779bebe3d366f94ebca3b42b3f8cc290c5e3",
"sha256:2c40cbc4c630e6201983af88ee9c4fd9f1d8c1d41545c78a861e9911fcb23b7b",
"sha256:478f32fcf2042ead1bfbba7a3c77e2fc574c1f65967efc137156130bfd02c056",
"sha256:5ab8dcf427184d5573494061d4cb7201ae4d7303433f81af359b6bd48b19515f",
"sha256:619776f6070a00a06713ef14f67e03af5bea16afda1897e7936ba8bbf0b3dba6",
"sha256:6934566d3bca7cd0d2912fbb8966882fd7b43b8ec0139b0c7797814e11555be0",
"sha256:6e293ea5141767817c26f085a26fcd3c451c15c1902c5f2a7bdb9a7fe57ebdef",
"sha256:74fa81f69e67363c4d3b4d60a0608adddadb0f2e2f4cc8c1f2dc2b083747fd69",
"sha256:77c7f6984dcaa007bcba8ff67e2e3c7a71a237b63193e5c14fe832493e53976a",
"sha256:7a261b55d72c266d467423966aa48ebf73326736155307c5265a1c99f163f2d7",
"sha256:7dc9a3a108f1730f6cd65a68ae67ea2eb10bd314cffe8dca1afe693c50e84b9b",
"sha256:7ded7df0174040ccd8be60780f43fd3d18bf675ac1170d82d09985d214896521",
"sha256:9096bea0f7aa29e52a3a23759cd6cabee98366a41a2c880db949fcf00f936aa4",
"sha256:9097836ba9a9f631736ab86bb622dcc6155476c7ea0f55486dc2d9b22c07f5d6",
"sha256:b33b2b71ccf6689968a8452e0c1beadf385511df9b55e36d83e688a2832f6b0a",
"sha256:bb45c8aabb3d4e646a25939096cc751cb4e0e4ff9d3bfdcce9fa64ff0622d348",
"sha256:bf9e0ac84a8f473ad723059ac561c307682015a083a8b9b7ff26808780715666",
"sha256:c01ca2b364ef7b02c2ffbed0b423597c9999131f83a1878548d36666ca2a27ed",
"sha256:d6738b13d0f7ddaf02f43ce71353fe079d461bf9bec76f48406071de4a89a1dd",
"sha256:e22998c2d914bee02dc58aa791bc7df6f9733554b244e94b33ff4a491322c142",
"sha256:eaaea91dc56c041516a829c460423a8aef5357001610c8d6395bce95d8254a0b",
"sha256:f8b673775f120d7f54b5f3230742239e21fc5c4e3138372dad87b82617677509"
],
"markers": "python_version >= '3.6'",
"version": "==8.1.0"
},
"tinydb": {
"hashes": [
"sha256:357eb7383dee6915f17b00596ec6dd2a890f3117bf52be28a4c516aeee581100",
"sha256:e2cdf6e2dad49813e9b5fceb3c7943387309a8738125fbff0b58d248a033f7a9"
],
"index": "pypi",
"version": "==4.7.0"
},
"torch": {
"hashes": [
"sha256:03e31c37711db2cd201e02de5826de875529e45a55631d317aadce2f1ed45aa8",
"sha256:0b44601ec56f7dd44ad8afc00846051162ef9c26a8579dda0a02194327f2d55e",
"sha256:42e115dab26f60c29e298559dbec88444175528b729ae994ec4c65d56fe267dd",
"sha256:42f639501928caabb9d1d55ddd17f07cd694de146686c24489ab8c615c2871f2",
"sha256:4e1b9c14cf13fd2ab8d769529050629a0e68a6fc5cb8e84b4a3cc1dd8c4fe541",
"sha256:68104e4715a55c4bb29a85c6a8d57d820e0757da363be1ba680fa8cc5be17b52",
"sha256:69fe2cae7c39ccadd65a123793d30e0db881f1c1927945519c5c17323131437e",
"sha256:6cf6f54b43c0c30335428195589bd00e764a6d27f3b9ba637aaa8c11aaf93073",
"sha256:743784ccea0dc8f2a3fe6a536bec8c4763bd82c1352f314937cb4008d4805de1",
"sha256:8a34a2fbbaa07c921e1b203f59d3d6e00ed379f2b384445773bd14e328a5b6c8",
"sha256:976c3f997cea38ee91a0dd3c3a42322785414748d1761ef926b789dfa97c6134",
"sha256:9b356aea223772cd754edb4d9ecf2a025909b8615a7668ac7d5130f86e7ec421",
"sha256:9c038662db894a23e49e385df13d47b2a777ffd56d9bcd5b832593fab0a7e286",
"sha256:a8320ba9ad87e80ca5a6a016e46ada4d1ba0c54626e135d99b2129a4541c509d",
"sha256:b5dbcca369800ce99ba7ae6dee3466607a66958afca3b740690d88168752abcf",
"sha256:bfec2843daa654f04fda23ba823af03e7b6f7650a873cdb726752d0e3718dada",
"sha256:cd26d8c5640c3a28c526d41ccdca14cf1cbca0d0f2e14e8263a7ac17194ab1d2",
"sha256:e9c8f4a311ac29fc7e8e955cfb7733deb5dbe1bdaabf5d4af2765695824b7e0d",
"sha256:f00c721f489089dc6364a01fd84906348fe02243d0af737f944fddb36003400d",
"sha256:f3b52a634e62821e747e872084ab32fbcb01b7fa7dbb7471b6218279f02a178a"
],
"index": "pypi",
"version": "==1.12.1"
},
"tqdm": {
"hashes": [
"sha256:40be55d30e200777a307a7585aee69e4eabb46b4ec6a4b4a5f2d9f11e7d5408d",
"sha256:74a2cdefe14d11442cedf3ba4e21a3b84ff9a2dbdc6cfae2c34addb2a14a5ea6"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==4.64.0"
},
"typer": {
"hashes": [
"sha256:023bae00d1baf358a6cc7cea45851639360bb716de687b42b0a4641cd99173f1",
"sha256:b8261c6c0152dd73478b5ba96ba677e5d6948c715c310f7c91079f311f62ec03"
],
"markers": "python_version >= '3.6'",
"version": "==0.4.2"
},
"typing-extensions": {
"hashes": [
"sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02",
"sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"
],
"markers": "python_version >= '3.7'",
"version": "==4.3.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.0'",
"version": "==1.24.3"
},
"wasabi": {
"hashes": [
"sha256:c8e372781be19272942382b14d99314d175518d7822057cb7a97010c4259d249",
"sha256:fe862cc24034fbc9f04717cd312ab884f71f51a8ecabebc3449b751c2a649d83"
],
"version": "==0.10.1"
},
"wheel": {
"hashes": [
"sha256:4bdcd7d840138086126cd09254dc6195fb4fc6f01c050a1d7236f2630db1d22a",
"sha256:e9a504e793efbca1b8e0e9cb979a249cf4a0a7b5b8c9e8b65a5e39d49529c1c4"
],
"index": "pypi",
"version": "==0.37.1"
}
},
"develop": {}
}
-37
View File
@@ -1,37 +0,0 @@
#!/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()
+14
View File
@@ -0,0 +1,14 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[requires]
python_version = "3.9.10"
[packages]
setuptools = "*"
wheel = "*"
cx-freeze = "==6.11.1"
requests = "==2.28.1"
beautifulsoup4 = "==4.7.1"
+30
View File
@@ -0,0 +1,30 @@
import sys
import json
import os
import version
INTENT_OBJ_FILE_PATH = sys.argv[1]
with open(INTENT_OBJ_FILE_PATH, 'r') as f:
INTENT_OBJECT = json.load(f)
SKILLS_ROOT_PATH = os.path.join(
os.getcwd(),
'skills'
)
SKILL_PATH = os.path.join(
SKILLS_ROOT_PATH,
INTENT_OBJECT['domain'],
INTENT_OBJECT['skill']
)
SKILLS_PATH = SKILLS_ROOT_PATH
with open(os.path.join(SKILL_PATH, 'config', INTENT_OBJECT['extra_context_data']['lang'] + '.json'), 'r') as f:
SKILL_CONFIG = json.load(f)
LEON_VERSION = os.getenv('npm_package_version')
PYTHON_BRIDGE_VERSION = version.__version__
+44
View File
@@ -0,0 +1,44 @@
import sys
from traceback import print_exc
from importlib import import_module
from constants import INTENT_OBJECT
def main():
params = {
'lang': INTENT_OBJECT['lang'],
'utterance': INTENT_OBJECT['utterance'],
'current_entities': INTENT_OBJECT['current_entities'],
'entities': INTENT_OBJECT['entities'],
'current_resolvers': INTENT_OBJECT['current_resolvers'],
'resolvers': INTENT_OBJECT['resolvers'],
'slots': INTENT_OBJECT['slots'],
'extra_context_data': INTENT_OBJECT['extra_context_data']
}
try:
sys.path.append('.')
skill_action_module = import_module(
'skills.'
+ INTENT_OBJECT['domain']
+ '.'
+ INTENT_OBJECT['skill']
+ '.src.actions.'
+ INTENT_OBJECT['action']
)
getattr(skill_action_module, 'run')(params)
except Exception as e:
print(f"Error while running {INTENT_OBJECT['skill']} skill {INTENT_OBJECT['action']} action: {e}")
print_exc()
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()
+9
View File
@@ -0,0 +1,9 @@
from ..widget import Widget
# TODO: contains the button API. rendering engine <-> SDK
class Button(Widget):
def __init__(self, options):
super().__init__(options)
+92
View File
@@ -0,0 +1,92 @@
import random
import sys
from typing import Union
from time import sleep
import json
from .types import AnswerInput, AnswerData, AnswerConfig
from ..constants import SKILL_CONFIG, INTENT_OBJECT
class Leon:
instance: 'Leon' = None
def __init__(self) -> None:
if not Leon.instance:
Leon.instance = self
@staticmethod
def set_answer_data(answer_key: str, data: Union[AnswerData, None] = None) -> Union[str, AnswerConfig]:
"""
Apply data to the answer
:param answer_key: The answer key
:param data: The data to apply
"""
try:
# In case the answer key is a raw answer
if SKILL_CONFIG.get('answers') is None or SKILL_CONFIG['answers'].get(answer_key) is None:
return answer_key
answers = SKILL_CONFIG['answers'].get(answer_key, '')
if isinstance(answers, list):
answer = answers[random.randrange(len(answers))]
else:
answer = answers
if data:
for key, value in data.items():
# In case the answer needs speech and text differentiation
if not isinstance(answer, str) and answer.get('text'):
answer['text'] = answer['text'].replace('%{}%'.format(key), str(value))
answer['speech'] = answer['speech'].replace('%{}%'.format(key), str(value))
else:
answer = answer.replace('%{}%'.format(key), str(value))
if SKILL_CONFIG.get('variables'):
for key, value in SKILL_CONFIG['variables'].items():
# In case the answer needs speech and text differentiation
if not isinstance(answer, str) and answer.get('text'):
answer['text'] = answer['text'].replace('%{}%'.format(key), str(value))
answer['speech'] = answer['speech'].replace('%{}%'.format(key), str(value))
else:
answer = answer.replace('%{}%'.format(key), str(value))
return answer
except Exception as e:
print('Error while setting answer data:', e)
raise e
def answer(self, answer_input: AnswerInput) -> None:
"""
Send an answer to the core
:param answer_input: The answer input
"""
try:
key = answer_input.get('key')
output = {
'output': {
'codes': 'widget' if answer_input.get('widget') and not answer_input.get('key') else answer_input.get('key'),
'answer': self.set_answer_data(key, answer_input.get('data')) if key is not None else '',
'core': answer_input.get('core')
}
}
if answer_input.get('widget'):
output['output']['widget'] = answer_input['widget'].__dict__
answer_object = {
**INTENT_OBJECT,
**output
}
# "Temporize" for the data buffer output on the core
sleep(0.1)
sys.stdout.write(json.dumps(answer_object))
sys.stdout.flush()
except Exception as e:
print('Error while creating answer:', e)
leon = Leon()
+76
View File
@@ -0,0 +1,76 @@
import json
import os
from typing import TypedDict, Any
from ..constants import SKILL_PATH, SKILLS_PATH
class MemoryOptions(TypedDict, total=False):
name: str
default_memory: Any
class Memory:
def __init__(self, options: MemoryOptions):
self.name = options['name']
self.default_memory = options['default_memory'] if 'default_memory' in options else None
self.memory_path = self.memory_path = os.path.join(
SKILL_PATH,
'memory',
f'{self.name}.json'
)
self.__is_from_another_skill = False
if ':' in self.name and self.name.count(':') == 2:
self.__is_from_another_skill = True
domain_name, skill_name, memory_name = self.name.split(':')
self.memory_path = os.path.join(
SKILLS_PATH,
domain_name,
skill_name,
'memory',
memory_name + '.json'
)
def clear(self) -> None:
"""
Clear the memory and set it to the default memory value
"""
if not self.__is_from_another_skill:
self.write(self.default_memory)
else:
raise ValueError(f'You cannot clear the memory "{self.name}" as it belongs to another skill')
def read(self):
"""
Read the memory
"""
if self.__is_from_another_skill and not os.path.exists(self.memory_path):
raise ValueError(f'You cannot read the memory "{self.name}" as it belongs to another skill which hasn\'t written to this memory yet')
try:
if not os.path.exists(self.memory_path):
self.clear()
with open(self.memory_path, 'r') as f:
return json.load(f)
except Exception as e:
print(f'Error while reading memory for "{self.name}": {e}')
raise e
def write(self, memory):
"""
Write the memory
:param memory: The memory to write
"""
if not self.__is_from_another_skill:
try:
with open(self.memory_path, 'w') as f:
json.dump(memory, f, indent=2)
return memory
except Exception as e:
print(f'Error while writing memory for "{self.name}": {e}')
raise e
else:
raise ValueError(f'You cannot write into the memory "{self.name}" as it belongs to another skill')
+92
View File
@@ -0,0 +1,92 @@
import requests
import socket
from typing import Any, Dict, TypedDict, Union, Literal, Optional
from ..constants import LEON_VERSION, PYTHON_BRIDGE_VERSION
class NetworkOptions(TypedDict, total=False):
base_url: Optional[str]
class NetworkResponse(TypedDict):
data: Any
status_code: int
options: Dict[str, Any]
class NetworkError(Exception):
def __init__(self, response: NetworkResponse) -> None:
self.response = response
super().__init__(f"[NetworkError]: {response['status_code']} {response['data']}")
class NetworkRequestOptions(TypedDict, total=False):
url: str
method: Union[Literal['GET'], Literal['POST'], Literal['PUT'], Literal['PATCH'], Literal['DELETE']]
data: Dict[str, Any]
headers: Dict[str, str]
class Network:
def __init__(self, options: NetworkOptions = {'base_url': None}) -> None:
self.options = options
def request(self, options: NetworkRequestOptions) -> NetworkResponse:
try:
url = options['url']
if self.options['base_url'] is not None:
url = self.options['base_url'] + url
method = options['method']
data = options.get('data', {})
headers = options.get('headers', {})
response = requests.request(
method,
url,
json=data,
headers={
'User-Agent': f"Leon Personal Assistant {LEON_VERSION} - Python Bridge {PYTHON_BRIDGE_VERSION}",
**headers
}
)
data = {}
try:
data = response.json()
except Exception:
data = response.text
network_response: NetworkResponse = {
'data': data,
'status_code': response.status_code,
'options': {**self.options, **options}
}
if response.ok:
return network_response
else:
raise NetworkError(network_response)
except requests.exceptions.RequestException as error:
data = {}
try:
data = error.response.json()
except Exception:
data = error.response.text
raise NetworkError({
'data': data,
'status_code': error.response.status_code,
'options': {**self.options, **options}
}) from error
def is_network_error(self, error: Exception) -> bool:
return isinstance(error, NetworkError)
def is_network_available(self) -> bool:
try:
socket.gethostbyname('getleon.ai')
return True
except socket.error:
return False
+91
View File
@@ -0,0 +1,91 @@
import json
import os
from os import path
from typing import Union, Any, overload
from ..constants import SKILL_PATH
class Settings:
def __init__(self):
self.settings_path = path.join(SKILL_PATH, 'src', 'settings.json')
self.settings_sample_path = path.join(SKILL_PATH, 'src', 'settings.sample.json')
def is_setting_set(self, key: str) -> bool:
"""
Check if a setting is already set
:param key: The key to verify whether its value is set
"""
settings_sample = self.get_settings_sample()
settings = self.get()
return key in settings and json.dumps(settings[key]) != json.dumps(settings_sample[key])
def clear(self) -> None:
"""
Clear the settings and set it to the default settings.sample.json file
"""
settings_sample = self.get_settings_sample()
self.set(settings_sample)
def get_settings_sample(self) -> dict[str, Any]:
try:
with open(self.settings_sample_path, 'r') as file:
return json.load(file)
except Exception as e:
print(f"Error while reading settings sample at '{self.settings_sample_path}': {e}")
raise e
@overload
def get(self, key: str) -> Any: ...
@overload
def get(self, key: None = None) -> dict[str, Any]: ...
def get(self, key: Union[str, None] = None) -> Union[dict[str, Any], Any]:
"""
Get the settings
:param key: The key to get from the settings
"""
try:
if not os.path.exists(self.settings_path):
self.clear()
with open(self.settings_path, 'r') as file:
settings = json.load(file)
if key is not None:
return settings[key]
return settings
except Exception as e:
print(f"Error while reading settings at '{self.settings_path}': {e}")
raise e
@overload
def set(self, key_or_settings: dict[str, Any]) -> dict[str, Any]: ...
@overload
def set(self, key_or_settings: str, value: Any) -> dict[str, Any]: ...
def set(self, key_or_settings: Union[str, dict[str, Any]], value: Any = None) -> dict[str, Any]:
"""
Set the settings
:param key_or_settings: The key to set or the settings to set
:param value: The value to set
"""
try:
settings = self.get()
if isinstance(key_or_settings, dict):
new_settings = key_or_settings
else:
new_settings = {**settings, key_or_settings: value}
with open(self.settings_path, 'w') as file:
json.dump(new_settings, file, indent=2)
return new_settings
except Exception as e:
print(f"Error while writing settings at '{self.settings_path}': {e}")
raise e
+49
View File
@@ -0,0 +1,49 @@
from typing import Dict, Any, Optional, Union, Literal, TypedDict
class NLUResultSentiment(TypedDict):
vote: Optional[Union[Literal['positive'], Literal['neutral'], Literal['negative']]]
score: Optional[float]
class ExtraContextData(TypedDict):
lang: str
sentiment: str
date: str
time: str
timestamp: int
date_time: str
week_day: str
class ActionParams(TypedDict):
lang: str
utterance: str
current_entities: list[Any]
entities: list[Any]
current_resolvers: list[Any]
resolvers: list[Any]
slots: Dict[str, Any]
extra_context_data: ExtraContextData
AnswerData = Optional[Union[Dict[str, Union[str, int]], None]]
class Answer(TypedDict):
key: Optional[str]
widget: Optional[Any]
data: Optional[AnswerData]
core: Optional[Dict[str, Any]]
class AnswerInput(TypedDict, total=False):
key: Optional[str]
widget: Any
data: Optional[AnswerData]
core: Dict[str, Any]
class AnswerConfig(TypedDict):
text: str
speech: str
+4
View File
@@ -0,0 +1,4 @@
class Widget:
def __init__(self, options):
self.type = type(self).__name__
self.options = options
+30
View File
@@ -0,0 +1,30 @@
from cx_Freeze import setup, Executable
import requests.certs
from version import __version__
options = {
'build_exe': {
# Add common dependencies for skills
'includes': [
'bs4',
'requests',
'timeit'
],
'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
)
+1
View File
@@ -0,0 +1 @@
__version__ = '1.2.0'
@@ -1,60 +0,0 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
import json
import lib.nlp as nlp
class TCPServer:
def __init__(self, host, port):
self.host = host
self.port = port
self.tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.conn = None
self.addr = None
def init(self):
# Make sure to establish TCP connection by reusing the address so it does not conflict with port already in use
self.tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.tcp_socket.bind((self.host, int(self.port)))
self.tcp_socket.listen()
while True:
print('Waiting for connection...')
# Our TCP server only needs to support one connection
self.conn, self.addr = self.tcp_socket.accept()
try:
print(f'Client connected: {self.addr}')
while True:
socket_data = self.conn.recv(1024)
if not socket_data:
break
data_dict = json.loads(socket_data)
# Verify the received topic can execute the method
method = data_dict['topic'].lower().replace('-', '_')
if hasattr(self.__class__, method) and callable(getattr(self.__class__, method)):
data = data_dict['data']
method = getattr(self, method)
res = method(data)
self.conn.sendall(json.dumps(res).encode('utf-8'))
finally:
print(f'Client disconnected: {self.addr}')
self.conn.close()
def get_spacy_entities(self, utterance):
entities = nlp.extract_spacy_entities(utterance)
return {
'topic': 'spacy-entities-received',
'data': {
'spacyEntities': entities
}
}
-88
View File
@@ -1,88 +0,0 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from sys import argv
import spacy
import geonamescache
lang = argv[1] or 'en'
spacy_nlp = None
spacy_model_mapping = {
'en': {
'model': 'en_core_web_trf',
'exclude': ['tagger', 'parser', 'attribute_ruler', 'lemmatizer'],
'entity_mapping': {
'PERSON': 'person',
'GPE': 'location',
'ORG': 'organization'
}
},
'fr': {
'model': 'fr_core_news_md',
'exclude': ['tok2vec', 'morphologizer', 'parser', 'senter', 'attribute_ruler', 'lemmatizer'],
'entity_mapping': {
'PER': 'person',
'LOC': 'location',
'ORG': 'organization'
}
}
}
gc = geonamescache.GeonamesCache()
countries = gc.get_countries()
cities = gc.get_cities()
def gen_dict_extract(var, key):
if isinstance(var, dict):
for k, v in var.items():
if k == key:
yield v
if isinstance(v, (dict, list)):
yield from gen_dict_extract(v, key)
elif isinstance(var, list):
for d in var:
yield from gen_dict_extract(d, key)
countries = [*gen_dict_extract(countries, 'name')]
cities = [*gen_dict_extract(cities, 'name')]
"""
Functions called from TCPServer class
"""
def load_spacy_model():
global spacy_nlp
model = spacy_model_mapping[lang]['model']
exclude = spacy_model_mapping[lang]['exclude']
print(f'Loading {model} spaCy model...')
spacy_nlp = spacy.load(model, exclude=exclude)
print('spaCy model loaded')
def extract_spacy_entities(utterance):
doc = spacy_nlp(utterance)
entities = []
for ent in doc.ents:
if ent.label_ in spacy_model_mapping[lang]['entity_mapping']:
entity = spacy_model_mapping[lang]['entity_mapping'][ent.label_]
if entity == 'location':
if ent.text.casefold() in (country.casefold() for country in countries):
entity += ':country'
elif ent.text.casefold() in (city.casefold() for city in cities):
entity += ':city'
entities.append({
'start': ent.start_char,
'end': ent.end_char,
'len': len(ent.text),
'sourceText': ent.text,
'utteranceText': ent.text,
'entity': entity,
'resolution': {
'value': ent.text
}
})
return entities
-147
View File
@@ -1,147 +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, table, operations
from time import sleep
import sqlite3
import requests
import re
dirname = path.dirname(path.realpath(__file__))
intent_object_path = 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(path.join(dirname, '../../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'):
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(path.join(dirname, '../../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 = path.dirname(path.realpath(__file__)) + '/../../downloads/'
skill_dl_dir = 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 environ.get('LEON_NODE_ENV') != 'testing' else '.spec.json'
db = TinyDB(path.join(dirname, '../../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 environ.get('LEON_NODE_ENV') != 'testing' else '.spec.json'
db = TinyDB(path.join(dirname, '../../skills', domain, skill, 'memory/db' + ext))
return db.table(table)
-11
View File
@@ -1,11 +0,0 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from os import path
from json import loads
packagejsonfile = open(path.dirname(path.realpath(__file__)) + '/../../package.json', 'r', encoding = 'utf8')
packagejson = loads(packagejsonfile.read())
packagejsonfile.close()
useragent = 'Leon-Personal-Assistant/' + packagejson['version']
+1
View File
@@ -1,4 +1,5 @@
{
"$schema": "../../../schemas/voice-config-schemas/amazon.json",
"credentials": {
"accessKeyId": "",
"secretAccessKey": ""
+7 -6
View File
@@ -1,12 +1,13 @@
{
"type": "",
"$schema": "../../../schemas/voice-config-schemas/google-cloud.json",
"type": "service_account",
"project_id": "",
"private_key_id": "",
"private_key": "",
"client_email": "",
"client_email": "example@iam.gserviceaccount.com",
"client_id": "",
"auth_uri": "",
"token_uri": "",
"auth_provider_x509_cert_url": "",
"client_x509_cert_url": ""
"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/"
}
+2 -1
View File
@@ -1,4 +1,5 @@
{
"$schema": "../../../schemas/voice-config-schemas/watson-stt.json",
"apikey": "",
"url": ""
"url": "https://stream.watsonplatform.net/speech-to-text/api"
}
+2 -1
View File
@@ -1,4 +1,5 @@
{
"$schema": "../../../schemas/voice-config-schemas/watson-tts.json",
"apikey": "",
"url": ""
"url": "https://stream.watsonplatform.net/text-to-speech/api"
}
+32 -40
View File
@@ -1,45 +1,37 @@
{
"answers": {
"success": {
},
"errors": {
"not_found": "Sorry, it seems I cannot find that",
"nlu": "It might come from my natural language understanding, the error returned is: \"%error%\""
},
"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"
"$schema": "../../../schemas/global-data/global-answers.json",
"answers": {
"success": {},
"errors": {
"not_found": "Sorry, it seems I cannot find that"
},
"random_errors": [
"Sorry, there is a problem with my system",
"Sorry, I don't work correctly",
"Sorry, you need to fix me",
"Sorry, I cannot do that because I'm broken"
],
"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",
"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_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"
@@ -63,5 +55,5 @@
"Aah, you want to change the subject, sure",
"Mmmh, as you wish, let's switch conversation"
]
}
}
}
+1
View File
@@ -1,4 +1,5 @@
{
"$schema": "../../../../schemas/global-data/global-entity.json",
"options": {
"red": {
"synonyms": ["red"],
+1
View File
@@ -1,4 +1,5 @@
{
"$schema": "../../../../schemas/global-data/global-entity.json",
"options": {
"LOW": {
"synonyms": ["low"]
@@ -1,4 +1,5 @@
{
"$schema": "../../../../schemas/global-data/global-entity.json",
"options": {
"Alexa": {
"synonyms": ["Alexa"],
@@ -1,4 +1,5 @@
{
"$schema": "../../../../schemas/global-data/global-resolver.json",
"name": "affirmation_denial",
"intents": {
"affirmation": {
@@ -22,7 +23,14 @@
"That works",
"Go ahead",
"Why not",
"Please"
"Please",
"Absolutely",
"Precisely",
"Spot on",
"Undoubtedly",
"Certainly",
"Without a doubt",
"Definitely"
],
"value": true
},
@@ -36,7 +44,10 @@
"No thanks",
"No I'm fine",
"Hell no",
"Please do not"
"Please do not",
"I disagree",
"Negative",
"Not at all"
],
"value": false
}
+33 -40
View File
@@ -1,45 +1,38 @@
{
"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"
"$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%\""
},
"random_errors": [
"Désolé, il y a un problème avec mon système",
"Désolé, je ne fonctionne pas correctement",
"Désolé, vous devez me réparer",
"Désolé, je ne peux aboutir à votre demande parce que je suis cassé"
],
"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",
"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_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"
@@ -58,5 +51,5 @@
"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"
]
}
}
}
+3 -6
View File
@@ -1,19 +1,16 @@
{
"$schema": "../../../../schemas/global-data/global-entity.json",
"options": {
"rouge": {
"synonyms": ["rouge"],
"data": {
"usage": [
"..."
]
"usage": ["..."]
}
},
"bleu": {
"synonyms": ["bleu"],
"data": {
"usage": [
"..."
]
"usage": ["..."]
}
}
}
+4 -9
View File
@@ -1,27 +1,22 @@
{
"$schema": "../../../../schemas/global-data/global-entity.json",
"options": {
"bas": {
"synonyms": ["bas", "basse"],
"data": {
"value": [
"LOW"
]
"value": ["LOW"]
}
},
"moyen": {
"synonyms": ["moyen"],
"data": {
"value": [
"MEDIUM"
]
"value": ["MEDIUM"]
}
},
"haut": {
"synonyms": ["haut", "haute"],
"data": {
"value": [
"HIGH"
]
"value": ["HIGH"]
}
}
}
@@ -1,4 +1,5 @@
{
"$schema": "../../../../schemas/global-data/global-entity.json",
"options": {
"Alexa": {
"synonyms": ["Alexa"],
@@ -1,4 +1,5 @@
{
"$schema": "../../../../schemas/global-data/global-resolver.json",
"name": "affirmation_denial",
"intents": {
"affirmation": {
+3 -4
View File
@@ -1,10 +1,9 @@
{
"langs": {
"langs": {
"en-US": {
"short": "en",
"min_confidence": 0.5,
"fallbacks": [
]
"fallbacks": []
},
"fr-FR": {
"short": "fr",
@@ -18,5 +17,5 @@
}
]
}
}
}
}
+104 -96
View File
@@ -1,11 +1,77 @@
{
"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": "POST",
"route": "/api/action/games/akinator/choose_thematic",
"params": [
"thematic"
],
"params": ["thematic"],
"entitiesType": "trim"
},
{
@@ -46,9 +112,7 @@
{
"method": "POST",
"route": "/api/action/games/rochambeau/play",
"params": [
"handsign"
],
"params": ["handsign"],
"entitiesType": "trim"
},
{
@@ -56,6 +120,11 @@
"route": "/api/action/games/rochambeau/rematch",
"params": []
},
{
"method": "GET",
"route": "/api/action/leon/age/run",
"params": []
},
{
"method": "GET",
"route": "/api/action/leon/color/favorite_color",
@@ -81,6 +150,11 @@
"route": "/api/action/leon/greeting/run",
"params": []
},
{
"method": "GET",
"route": "/api/action/leon/help/help",
"params": []
},
{
"method": "GET",
"route": "/api/action/leon/introduction/introduce_leon",
@@ -121,93 +195,34 @@
"route": "/api/action/leon/welcome/run",
"params": []
},
{
"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",
"route": "/api/action/utilities/date_time/current_date_time",
"params": []
},
{
"method": "GET",
"route": "/api/action/social_communication/mbti/quiz",
"route": "/api/action/utilities/date_time/current_date",
"params": []
},
{
"method": "GET",
"route": "/api/action/utilities/date_time/current_time",
"params": []
},
{
"method": "GET",
"route": "/api/action/utilities/date_time/current_week_number",
"params": []
},
{
"method": "GET",
"route": "/api/action/utilities/date_time/days_countdown",
"params": []
},
{
"method": "GET",
"route": "/api/action/utilities/date_time/current_date_time_with_time_zone",
"params": []
},
{
@@ -218,20 +233,13 @@
{
"method": "POST",
"route": "/api/action/utilities/is_it_down/run",
"params": [
"url"
],
"params": ["url"],
"entitiesType": "builtIn"
},
{
"method": "GET",
"route": "/api/action/utilities/speed_test/run",
"params": []
},
{
"method": "GET",
"route": "/api/action/utilities/youtube_downloader/run",
"params": []
}
]
}
}
+2 -2
View File
@@ -12,6 +12,6 @@ services:
tty: true
command: 'npm run dev:server && npm run dev:app'
volumes:
- './:/app'
- '/app/node_modules'
- './:/home/docker/leon'
- '/home/docker/leon/node_modules'
network_mode: 'host'
+1
View File
@@ -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
+58 -60
View File
@@ -3,9 +3,7 @@
* 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('@bugsounet/snowboy')
const { io } = require('socket.io-client')
@@ -23,63 +21,63 @@ socket.on('connect', () => {
console.log('Connected to the server')
console.log('Waiting for hotword...')
})
;(async () => {
try {
await axios.get(`${url}/api/v1/info`)
request.get(`${url}/api/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-${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)
console.error(e)
}
})
}
})()
+321 -1128
View File
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -13,10 +13,10 @@
},
"license": "MIT",
"dependencies": {
"node-record-lpcm16": "^0.3.0",
"@mapbox/node-pre-gyp": "^1.0.8",
"@bugsounet/snowboy": "^2.2.3",
"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"
}
}
+7
View File
@@ -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"
}
-35751
View File
File diff suppressed because it is too large Load Diff
+110 -70
View File
@@ -1,6 +1,6 @@
{
"name": "leon",
"version": "1.0.0-beta.7",
"version": "1.0.0-beta.10+dev",
"description": "Server, skills and web app of the Leon personal assistant",
"author": {
"name": "Louis Grenard",
@@ -21,92 +21,132 @@
"npm": ">=8.0.0"
},
"scripts": {
"lint": "babel-node scripts/lint.js",
"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/Pipfile LEON_NODE_ENV=testing jest --forceExit --silent --projects test/unit/unit.jest.json && npm run train",
"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 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",
"test:e2e:nlp-modules": "npm run train 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",
"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:over-http": "npm run generate:skills-endpoints && npm run train && cross-env PIPENV_PIPFILE=bridges/python/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": "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 && npm run generate:skills-endpoints && 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",
"clean:python-deps": "shx rm -rf ./bridges/python/src/.venv && npm run postinstall",
"prepare": "husky install",
"generate:skills-endpoints": "babel-node scripts/generate/run-generate-skills-endpoints.js",
"generate:http-api-key": "babel-node scripts/generate/run-generate-http-api-key.js",
"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 babel-node scripts/app/run-build-app.js",
"build:server": "npm run delete-dist:server && npm run train && npm run generate:skills-endpoints && babel ./server/src -d ./server/dist --copy-files && shx mkdir -p server/dist/tmp",
"start:tcp-server": "cross-env PIPENV_PIPFILE=bridges/python/Pipfile pipenv run python bridges/python/tcp_server/main.py",
"start": "cross-env LEON_NODE_ENV=production node ./server/dist/index.js",
"train": "babel-node scripts/train/run-train.js",
"prepare-release": "babel-node scripts/release/prepare-release.js",
"check": "babel-node scripts/run-check.js",
"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",
"skill-package": "ts-node scripts/skill-package.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.18.0",
"@ffmpeg-installer/ffmpeg": "^1.1.0",
"@ffprobe-installer/ffprobe": "^1.3.0",
"@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",
"archiver": "^5.3.0",
"async": "^3.2.0",
"cross-env": "^7.0.3",
"dotenv": "^10.0.0",
"execa": "^5.0.0",
"fastify": "^3.25.2",
"fastify-static": "^4.5.0",
"fluent-ffmpeg": "^2.1.2",
"googleapis": "^67.1.1",
"ibm-watson": "^6.1.1",
"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.4.0",
"socket.io-client": "^4.4.0",
"stt": "^1.1.0",
"superagent": "^6.1.0",
"tree-kill": "^1.2.2"
"os-name": "4.0.1",
"pretty-bytes": "5.6.0",
"pretty-ms": "7.0.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"socket.io": "4.5.2",
"socket.io-client": "4.5.2",
"stt": "1.4.0",
"tree-kill": "1.2.2"
},
"devDependencies": {
"@babel/cli": "^7.16.0",
"@babel/core": "^7.16.0",
"@babel/node": "^7.16.0",
"@babel/preset-env": "^7.16.0",
"@nlpjs/utils": "^4.24.1",
"babel-plugin-module-resolver": "^4.1.0",
"cli-spinner": "^0.2.10",
"eslint": "^7.28.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-import-resolver-babel-module": "^5.3.1",
"eslint-plugin-import": "^2.23.2",
"eslint-plugin-jest": "^24.3.6",
"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",
"nodemon": "^2.0.7",
"semver": "^7.3.5",
"shx": "^0.3.3",
"vite": "^2.7.7"
"@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",
"@types/react": "18.2.6",
"@types/react-dom": "18.2.4",
"@typescript-eslint/eslint-plugin": "5.55.0",
"@typescript-eslint/parser": "5.55.0",
"@vercel/ncc": "0.36.1",
"@vitejs/plugin-react": "4.0.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": "4.3.5"
}
}
+10 -6
View File
@@ -1,13 +1,17 @@
import { command } from 'execa'
import log from '@/helpers/log'
import { LogHelper } from '@/helpers/log-helper'
/**
* Build web app
*/
export default () => new Promise(async (resolve) => {
await command('vite --config app/vite.config.js build', { shell: true, stdout: 'inherit' })
export default () =>
new Promise(async (resolve) => {
await command('vite --config app/vite.config.js build', {
shell: true,
stdout: 'inherit'
})
log.success('Web app built')
resolve()
})
LogHelper.success('Web app built')
resolve()
})
+3 -3
View File
@@ -1,14 +1,14 @@
import log from '@/helpers/log'
import { LogHelper } from '@/helpers/log-helper'
import buildApp from './build-app'
/**
* Execute the building app script
*/
(async () => {
;(async () => {
try {
await buildApp()
} catch (e) {
log.error(`Failed to build: ${e}`)
LogHelper.error(`Failed to build: ${e}`)
}
})()
+1 -1
View File
@@ -2,4 +2,4 @@
<% _.forEach(sections, (section) => { if(section.commitsCount > 0) { %>### <%= section.title %>
<% _.forEach(section.commits, (commit) => { %> - <%= printCommit(commit, true) %><% }) %>
<% _.forEach(section.components.sort((a, b) => a !== b ? a < b ? -1 : 0 : 1), (component) => { %> - **<%= component.name %>:**
<% _.forEach(component.commits, (commit) => { %> <%= (component.commits.length > 1) ? ' -' : '' %> <%= printCommit(commit, true) %><% }) %><% }) %><% } %><% }) %>
<% _.forEach(component.commits, (commit) => { %> <%= (component.commits.length > 1) ? ' -' : '' %> <%= printCommit(commit, true) %><% }) %><% }) %><% } %><% }) %>
-1
View File
@@ -1 +0,0 @@
{"lang":"en","domain":"leon","skill":"random_number","action":"run","utterance":"Give me a random number","slots":{},"entities":[],"current_entities":[],"resolvers":[],"current_resolvers":[]}
@@ -0,0 +1,12 @@
{
"lang": "en",
"domain": "leon",
"skill": "age",
"action": "run",
"utterance": "How old are you?",
"slots": {},
"entities": [],
"current_entities": [],
"resolvers": [],
"current_resolvers": []
}

Some files were not shown because too many files have changed in this diff Show More