mirror of
https://github.com/leon-ai/leon.git
synced 2024-11-27 16:16:48 +03:00
Merge branch 'develop' into over-http
This commit is contained in:
commit
5c88c134f4
@ -17,7 +17,7 @@ LEON_AFTER_SPEECH=false
|
||||
# Enable/disable Leon's speech-to-text
|
||||
LEON_STT=false
|
||||
# Speech-to-text provider
|
||||
LEON_STT_PROVIDER=deepspeech
|
||||
LEON_STT_PROVIDER=coqui-stt
|
||||
|
||||
# Enable/disable Leon's text-to-speech
|
||||
LEON_TTS=false
|
||||
|
2
.github/ISSUE_TEMPLATE/BUG.md
vendored
2
.github/ISSUE_TEMPLATE/BUG.md
vendored
@ -14,7 +14,7 @@ Please check if there is no similar issue before creating this one.
|
||||
- Leon version:
|
||||
- OS (or browser) version:
|
||||
- Node.js version:
|
||||
- Complete "npm run check" output:
|
||||
- Complete "leon check" (or "npm run check") output:
|
||||
- (if using Docker) Complete "npm run docker:check" output:
|
||||
- (optional) Leon package version:
|
||||
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -9,7 +9,7 @@ bridges/python/.venv/*
|
||||
downloads/*
|
||||
logs/*
|
||||
server/src/config/**/*.json
|
||||
bin/deepspeech/*
|
||||
bin/coqui/*
|
||||
bin/flite/*
|
||||
|
||||
*.pyc
|
||||
|
40
README.md
40
README.md
@ -29,10 +29,6 @@
|
||||
<a href="https://blog.getleon.ai/the-story-behind-leon/">Story</a>
|
||||
</p>
|
||||
|
||||
<svg width="4438" height="1000" viewBox="0 0 4438 1000" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2223.75 250C2051.25 250 1926.87 362.5 1926.87 531.25C1926.87 700 2066.72 812.5 2239.38 812.5C2343.59 812.5 2435.47 771.25 2492.34 701.719L2372.81 632.656C2341.25 667.188 2293.28 687.344 2239.38 687.344C2164.53 687.344 2100.94 648.281 2077.34 585.781H2515.16C2518.59 568.281 2520.63 550.156 2520.63 531.094C2520.63 362.5 2396.41 250 2223.75 250ZM2076.09 476.562C2095.62 414.219 2149.06 375 2223.75 375C2298.59 375 2352.03 414.219 2371.41 476.562H2076.09ZM2040.78 78.125L1607.81 828.125L1174.69 78.125H1337.03L1607.66 546.875L1878.28 78.125H2040.78ZM577.344 0L1154.69 1000H0L577.344 0ZM3148.75 531.25C3148.75 625 3210 687.5 3305 687.5C3369.38 687.5 3417.66 658.281 3442.5 610.625L3562.5 679.844C3512.81 762.656 3419.69 812.5 3305 812.5C3132.34 812.5 3008.13 700 3008.13 531.25C3008.13 362.5 3132.5 250 3305 250C3419.69 250 3512.66 299.844 3562.5 382.656L3442.5 451.875C3417.66 404.219 3369.38 375 3305 375C3210.16 375 3148.75 437.5 3148.75 531.25ZM4437.5 78.125V796.875H4296.88V78.125H4437.5ZM3906.25 250C3733.75 250 3609.38 362.5 3609.38 531.25C3609.38 700 3749.38 812.5 3921.88 812.5C4026.09 812.5 4117.97 771.25 4174.84 701.719L4055.31 632.656C4023.75 667.188 3975.78 687.344 3921.88 687.344C3847.03 687.344 3783.44 648.281 3759.84 585.781H4197.66C4201.09 568.281 4203.12 550.156 4203.12 531.094C4203.12 362.5 4078.91 250 3906.25 250ZM3758.59 476.562C3778.13 414.219 3831.41 375 3906.25 375C3981.09 375 4034.53 414.219 4053.91 476.562H3758.59ZM2961.25 265.625V417.031C2945.63 412.5 2929.06 409.375 2911.25 409.375C2820.47 409.375 2755 471.875 2755 565.625V796.875H2614.38V265.625H2755V409.375C2755 330 2847.34 265.625 2961.25 265.625Z" fill="black"/>
|
||||
</svg>
|
||||
|
||||
---
|
||||
|
||||
## 👋 Introduction
|
||||
@ -83,8 +79,6 @@ Gitpod will automatically setup an environment and run an instance for you.
|
||||
|
||||
- [Node.js](https://nodejs.org/) >= 16
|
||||
- [npm](https://npmjs.com/) >= 8
|
||||
- [Python](https://www.python.org/downloads/) >= 3
|
||||
- [Pipenv](https://docs.pipenv.org) >= 2020.11.15
|
||||
- Supported OSes: Linux, macOS and Windows
|
||||
|
||||
To install these prerequisites, you can follow the [How To section](https://docs.getleon.ai/how-to/) of the documentation.
|
||||
@ -92,28 +86,22 @@ To install these prerequisites, you can follow the [How To section](https://docs
|
||||
### Installation
|
||||
|
||||
```sh
|
||||
# Clone the repository (stable branch)
|
||||
git clone -b master https://github.com/leon-ai/leon.git leon
|
||||
# OR download the latest release at: https://github.com/leon-ai/leon/releases/latest
|
||||
# Install the Leon CLI
|
||||
npm install --global @leon-ai/cli
|
||||
|
||||
# Go to the project root
|
||||
cd leon
|
||||
|
||||
# Install
|
||||
npm install
|
||||
# Install Leon (stable branch)
|
||||
leon create birth
|
||||
# OR install from the develop branch: leon create birth --develop
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```sh
|
||||
# Check the setup went well
|
||||
npm run check
|
||||
|
||||
# Build
|
||||
npm run build
|
||||
leon check
|
||||
|
||||
# Run
|
||||
npm start
|
||||
leon start
|
||||
|
||||
# Go to http://localhost:1337
|
||||
# Hooray! Leon is running
|
||||
@ -122,11 +110,11 @@ npm start
|
||||
### Docker Installation
|
||||
|
||||
```sh
|
||||
# Build
|
||||
npm run docker:build
|
||||
# Install Leon
|
||||
leon create birth --docker
|
||||
|
||||
# Run
|
||||
npm run docker:run
|
||||
leon start
|
||||
|
||||
# Go to http://localhost:1337
|
||||
# Hooray! Leon is running
|
||||
@ -184,7 +172,7 @@ You'll find a write-up on this [blog post](https://blog.getleon.ai/the-story-beh
|
||||
<img src="https://github.com/GregoireAMATO.png?size=128" />
|
||||
GrAMATO
|
||||
</a><br>
|
||||
<sub><sup>30 USD / month</sup></sub>
|
||||
<sub><sup>17 USD / month</sup></sub>
|
||||
</td>
|
||||
<td align="center" valign="middle" width="128">
|
||||
<a href="https://github.com/phareal">
|
||||
@ -194,9 +182,9 @@ You'll find a write-up on this [blog post](https://blog.getleon.ai/the-story-beh
|
||||
<sub><sup>17 USD / month</sup></sub>
|
||||
</td>
|
||||
<td align="center" valign="middle" width="128">
|
||||
<a href="https://github.com/marvinpoo">
|
||||
<img src="https://github.com/marvinpoo.png?size=128" />
|
||||
marvinpoo
|
||||
<a href="https://github.com/Divlo">
|
||||
<img src="https://github.com/Divlo.png?size=128" />
|
||||
Divlo
|
||||
</a><br>
|
||||
<sub><sup>10 USD / month</sup></sub>
|
||||
</td>
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
const request = require('superagent')
|
||||
const record = require('node-record-lpcm16')
|
||||
const { Detector, Models } = require('snowboy')
|
||||
const { Detector, Models } = require('@bugsounet/snowboy')
|
||||
const { io } = require('socket.io-client')
|
||||
|
||||
process.env.LEON_HOST = process.env.LEON_HOST || 'http://localhost'
|
||||
@ -39,7 +39,7 @@ request.get(`${url}/api/v1/info`)
|
||||
})
|
||||
|
||||
const detector = new Detector({
|
||||
resource: `${__dirname}/node_modules/snowboy/resources/common.res`,
|
||||
resource: `${__dirname}/node_modules/@bugsounet/snowboy/resources/common.res`,
|
||||
models,
|
||||
audioGain: 2.0,
|
||||
applyFrontend: true
|
||||
|
2064
hotword/package-lock.json
generated
2064
hotword/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -14,7 +14,8 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"node-record-lpcm16": "^0.3.0",
|
||||
"snowboy": "git+https://github.com/leon-ai/snowboy.git",
|
||||
"@mapbox/node-pre-gyp": "^1.0.8",
|
||||
"@bugsounet/snowboy": "^2.2.3",
|
||||
"socket.io-client": "^4.0.0",
|
||||
"superagent": "^3.5.2"
|
||||
}
|
||||
|
200
package-lock.json
generated
200
package-lock.json
generated
@ -23,7 +23,6 @@
|
||||
"archiver": "^5.3.0",
|
||||
"async": "^3.2.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"deepspeech": "^0.9.3",
|
||||
"dotenv": "^10.0.0",
|
||||
"execa": "^5.0.0",
|
||||
"fastify": "^3.25.2",
|
||||
@ -35,6 +34,7 @@
|
||||
"node-wav": "0.0.2",
|
||||
"socket.io": "^4.4.0",
|
||||
"socket.io-client": "^4.4.0",
|
||||
"stt": "^1.1.0",
|
||||
"superagent": "^6.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -7988,21 +7988,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/deepspeech": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/deepspeech/-/deepspeech-0.9.3.tgz",
|
||||
"integrity": "sha512-80yqUWEWgzclY9pjukpq0TdkQEbJ6NzqZ899vsLZfa4YcK35uOWIf+ILK55zQ+Ii/TEJ6Eo62Vc2saedQ/AK6w==",
|
||||
"dependencies": {
|
||||
"argparse": "1.0.x",
|
||||
"memory-stream": "1.0.x",
|
||||
"node-pre-gyp": "0.15.x",
|
||||
"node-wav": "0.0.2",
|
||||
"sox-stream": "2.0.x"
|
||||
},
|
||||
"bin": {
|
||||
"deepspeech": "client.js"
|
||||
}
|
||||
},
|
||||
"node_modules/defaults": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
|
||||
@ -8245,9 +8230,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/engine.io": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.0.tgz",
|
||||
"integrity": "sha512-ErhZOVu2xweCjEfYcTdkCnEYUiZgkAcBBAhW4jbIvNG8SLU3orAqoJCiytZjYF7eTpVmmCrLDjLIEaPlUAs1uw==",
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.2.tgz",
|
||||
"integrity": "sha512-v/7eGHxPvO2AWsksyx2PUsQvBafuvqs0jJJQ0FdmJG1b9qIvgSbqDRGwNhfk2XHaTTbTXiC4quRE8Q9nRjsrQQ==",
|
||||
"dependencies": {
|
||||
"@types/cookie": "^0.4.1",
|
||||
"@types/cors": "^2.8.12",
|
||||
@ -10226,9 +10211,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
|
||||
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==",
|
||||
"version": "1.14.7",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
|
||||
"integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@ -10675,11 +10660,11 @@
|
||||
"integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
|
||||
},
|
||||
"node_modules/google-p12-pem": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz",
|
||||
"integrity": "sha512-wS0ek4ZtFx/ACKYF3JhyGe5kzH7pgiQ7J5otlumqR9psmWMYc+U9cErKlCYVYHoUaidXHdZ2xbo34kB+S+24hA==",
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.3.tgz",
|
||||
"integrity": "sha512-MC0jISvzymxePDVembypNefkAQp+DRP7dBE+zNUPaIjEspIlYg0++OrsNr248V9tPbz6iqtZ7rX1hxWA5B8qBQ==",
|
||||
"dependencies": {
|
||||
"node-forge": "^0.10.0"
|
||||
"node-forge": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"gp12-pem": "build/src/bin/gp12-pem.js"
|
||||
@ -16866,9 +16851,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.1.30",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz",
|
||||
"integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==",
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
|
||||
"integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
@ -16932,19 +16917,49 @@
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
|
||||
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch/node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
|
||||
},
|
||||
"node_modules/node-fetch/node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
|
||||
},
|
||||
"node_modules/node-fetch/node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-forge": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
|
||||
"integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.2.1.tgz",
|
||||
"integrity": "sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w==",
|
||||
"engines": {
|
||||
"node": ">= 6.0.0"
|
||||
"node": ">= 6.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-gyp-build": {
|
||||
@ -18690,9 +18705,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/shelljs": {
|
||||
"version": "0.8.4",
|
||||
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz",
|
||||
"integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==",
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz",
|
||||
"integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"glob": "^7.0.0",
|
||||
@ -19178,6 +19193,21 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/stt": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/stt/-/stt-1.1.0.tgz",
|
||||
"integrity": "sha512-HAhK+1/dKAL9qfjVL+p69Xgb/UsjCh+xUVoMqtOPvw6ZmQXVl2HJN8Q91CQQMo78tgIcK83u4mdunTkS8aPehA==",
|
||||
"dependencies": {
|
||||
"argparse": "1.0.x",
|
||||
"memory-stream": "1.0.x",
|
||||
"node-pre-gyp": "0.15.x",
|
||||
"node-wav": "0.0.2",
|
||||
"sox-stream": "2.0.x"
|
||||
},
|
||||
"bin": {
|
||||
"stt": "client.js"
|
||||
}
|
||||
},
|
||||
"node_modules/stubs": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz",
|
||||
@ -26744,18 +26774,6 @@
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
|
||||
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
|
||||
},
|
||||
"deepspeech": {
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/deepspeech/-/deepspeech-0.9.3.tgz",
|
||||
"integrity": "sha512-80yqUWEWgzclY9pjukpq0TdkQEbJ6NzqZ899vsLZfa4YcK35uOWIf+ILK55zQ+Ii/TEJ6Eo62Vc2saedQ/AK6w==",
|
||||
"requires": {
|
||||
"argparse": "1.0.x",
|
||||
"memory-stream": "1.0.x",
|
||||
"node-pre-gyp": "0.15.x",
|
||||
"node-wav": "0.0.2",
|
||||
"sox-stream": "2.0.x"
|
||||
}
|
||||
},
|
||||
"defaults": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
|
||||
@ -26948,9 +26966,9 @@
|
||||
}
|
||||
},
|
||||
"engine.io": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.0.tgz",
|
||||
"integrity": "sha512-ErhZOVu2xweCjEfYcTdkCnEYUiZgkAcBBAhW4jbIvNG8SLU3orAqoJCiytZjYF7eTpVmmCrLDjLIEaPlUAs1uw==",
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.2.tgz",
|
||||
"integrity": "sha512-v/7eGHxPvO2AWsksyx2PUsQvBafuvqs0jJJQ0FdmJG1b9qIvgSbqDRGwNhfk2XHaTTbTXiC4quRE8Q9nRjsrQQ==",
|
||||
"requires": {
|
||||
"@types/cookie": "^0.4.1",
|
||||
"@types/cors": "^2.8.12",
|
||||
@ -28414,9 +28432,9 @@
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
|
||||
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg=="
|
||||
"version": "1.14.7",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
|
||||
"integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ=="
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.3.3",
|
||||
@ -28752,11 +28770,11 @@
|
||||
}
|
||||
},
|
||||
"google-p12-pem": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz",
|
||||
"integrity": "sha512-wS0ek4ZtFx/ACKYF3JhyGe5kzH7pgiQ7J5otlumqR9psmWMYc+U9cErKlCYVYHoUaidXHdZ2xbo34kB+S+24hA==",
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.3.tgz",
|
||||
"integrity": "sha512-MC0jISvzymxePDVembypNefkAQp+DRP7dBE+zNUPaIjEspIlYg0++OrsNr248V9tPbz6iqtZ7rX1hxWA5B8qBQ==",
|
||||
"requires": {
|
||||
"node-forge": "^0.10.0"
|
||||
"node-forge": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"googleapis": {
|
||||
@ -33465,9 +33483,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.1.30",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz",
|
||||
"integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==",
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
|
||||
"integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
|
||||
"dev": true
|
||||
},
|
||||
"natural-compare": {
|
||||
@ -33515,14 +33533,38 @@
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
|
||||
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"requires": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
|
||||
},
|
||||
"whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
||||
"requires": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-forge": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
|
||||
"integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA=="
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.2.1.tgz",
|
||||
"integrity": "sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w=="
|
||||
},
|
||||
"node-gyp-build": {
|
||||
"version": "4.2.3",
|
||||
@ -34856,9 +34898,9 @@
|
||||
}
|
||||
},
|
||||
"shelljs": {
|
||||
"version": "0.8.4",
|
||||
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz",
|
||||
"integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==",
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz",
|
||||
"integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.0.0",
|
||||
@ -35241,6 +35283,18 @@
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
|
||||
},
|
||||
"stt": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/stt/-/stt-1.1.0.tgz",
|
||||
"integrity": "sha512-HAhK+1/dKAL9qfjVL+p69Xgb/UsjCh+xUVoMqtOPvw6ZmQXVl2HJN8Q91CQQMo78tgIcK83u4mdunTkS8aPehA==",
|
||||
"requires": {
|
||||
"argparse": "1.0.x",
|
||||
"memory-stream": "1.0.x",
|
||||
"node-pre-gyp": "0.15.x",
|
||||
"node-wav": "0.0.2",
|
||||
"sox-stream": "2.0.x"
|
||||
}
|
||||
},
|
||||
"stubs": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz",
|
||||
|
@ -68,7 +68,6 @@
|
||||
"archiver": "^5.3.0",
|
||||
"async": "^3.2.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"deepspeech": "^0.9.3",
|
||||
"dotenv": "^10.0.0",
|
||||
"execa": "^5.0.0",
|
||||
"fastify": "^3.25.2",
|
||||
@ -80,6 +79,7 @@
|
||||
"node-wav": "0.0.2",
|
||||
"socket.io": "^4.4.0",
|
||||
"socket.io-client": "^4.4.0",
|
||||
"stt": "^1.1.0",
|
||||
"superagent": "^6.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -17,7 +17,7 @@ export default () => new Promise(async (resolve, reject) => {
|
||||
const npmMinRequiredVersion = '5'
|
||||
const pythonMinRequiredVersion = '3'
|
||||
const flitePath = 'bin/flite/flite'
|
||||
const deepSpeechPath = 'bin/deepspeech/lm.binary'
|
||||
const coquiLanguageModelPath = 'bin/coqui/huge-vocabulary.scorer'
|
||||
const amazonPath = 'server/src/config/voice/amazon.json'
|
||||
const googleCloudPath = 'server/src/config/voice/google-cloud.json'
|
||||
const watsonSttPath = 'server/src/config/voice/watson-stt.json'
|
||||
@ -173,11 +173,11 @@ export default () => new Promise(async (resolve, reject) => {
|
||||
}
|
||||
|
||||
log.info('Offline STT')
|
||||
if (!fs.existsSync(deepSpeechPath)) {
|
||||
if (!fs.existsSync(coquiLanguageModelPath)) {
|
||||
report.can_offline_stt.v = false
|
||||
log.warning(`Cannot find ${deepSpeechPath}. You can setup the offline STT by running: "npm run setup:offline-stt"`)
|
||||
log.warning(`Cannot find ${coquiLanguageModelPath}. You can setup the offline STT by running: "npm run setup:offline-stt"`)
|
||||
} else {
|
||||
log.success(`Found DeepSpeech language model at ${deepSpeechPath}`)
|
||||
log.success(`Found Coqui language model at ${coquiLanguageModelPath}`)
|
||||
}
|
||||
|
||||
// Report
|
||||
|
@ -36,6 +36,8 @@ export default () => new Promise(async (resolve, reject) => {
|
||||
log.info('Installing hotword dependencies...')
|
||||
await command('cd hotword && npm install', { shell: true })
|
||||
log.success('Offline hotword detection installed')
|
||||
await command('cd hotword/node_modules/@bugsounet/snowboy && CXXFLAGS="--std=c++17" ../../../node_modules/@mapbox/node-pre-gyp/bin/node-pre-gyp clean configure build', { shell: true })
|
||||
log.success('Snowboy bindings compiled')
|
||||
|
||||
resolve()
|
||||
} catch (e) {
|
||||
|
@ -10,23 +10,24 @@ import os from '@/helpers/os'
|
||||
export default () => new Promise(async (resolve, reject) => {
|
||||
log.info('Setting up offline speech-to-text...')
|
||||
|
||||
const destDeepSpeechFolder = 'bin/deepspeech'
|
||||
const destCoquiFolder = 'bin/coqui'
|
||||
const tmpDir = 'scripts/tmp'
|
||||
const deepSpeechVersion = '0.9.3'
|
||||
// check this repo for updates: https://github.com/coqui-ai/STT-models/tree/main/english/coqui
|
||||
const coquiModelVersion = '1.0.0'
|
||||
let downloader = 'wget'
|
||||
if (os.get().type === 'macos') {
|
||||
downloader = 'curl -L -O'
|
||||
}
|
||||
|
||||
if (!fs.existsSync(`${destDeepSpeechFolder}/deepspeech.scorer`)) {
|
||||
if (!fs.existsSync(`${destCoquiFolder}/model.tflite`)) {
|
||||
try {
|
||||
log.info('Downloading pre-trained model...')
|
||||
await command(`cd ${tmpDir} && ${downloader} https://github.com/mozilla/DeepSpeech/releases/download/v${deepSpeechVersion}/deepspeech-${deepSpeechVersion}-models.pbmm`, { shell: true })
|
||||
await command(`cd ${tmpDir} && ${downloader} https://github.com/mozilla/DeepSpeech/releases/download/v${deepSpeechVersion}/deepspeech-${deepSpeechVersion}-models.scorer`, { shell: true })
|
||||
await command(`cd ${tmpDir} && ${downloader} https://github.com/coqui-ai/STT-models/releases/download/english/coqui/v${coquiModelVersion}-huge-vocab/model.tflite`, { shell: true })
|
||||
await command(`cd ${tmpDir} && ${downloader} https://github.com/coqui-ai/STT-models/releases/download/english/coqui/v${coquiModelVersion}-huge-vocab/huge-vocabulary.scorer`, { shell: true })
|
||||
log.success('Pre-trained model download done')
|
||||
log.info('Moving...')
|
||||
await command(`mv -f ${tmpDir}/deepspeech-${deepSpeechVersion}-models.pbmm ${destDeepSpeechFolder}/deepspeech.pbmm`, { shell: true })
|
||||
await command(`mv -f ${tmpDir}/deepspeech-${deepSpeechVersion}-models.scorer ${destDeepSpeechFolder}/deepspeech.scorer`, { shell: true })
|
||||
await command(`mv -f ${tmpDir}/model.tflite ${destCoquiFolder}/model.tflite`, { shell: true })
|
||||
await command(`mv -f ${tmpDir}/huge-vocabulary.scorer ${destCoquiFolder}/huge-vocabulary.scorer`, { shell: true })
|
||||
log.success('Move done')
|
||||
log.success('Offline speech-to-text installed')
|
||||
|
||||
|
@ -1,32 +1 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
|
||||
/**
|
||||
* Trigger preinstall hook to remove DeepSpeech on Windows
|
||||
*/
|
||||
|
||||
console.info('\x1b[36m➡ %s\x1b[0m', 'Running Leon\'s installation...')
|
||||
|
||||
if (os.type().indexOf('Windows') !== -1) {
|
||||
const packageJsonPath = path.join(__dirname, '../../package.json')
|
||||
const packageJson = require(packageJsonPath) // eslint-disable-line global-require
|
||||
|
||||
console.warn('\x1b[33m❗ %s\x1b[0m', 'The Leon\'s voice offline mode is not available on Windows')
|
||||
console.info('\x1b[36m➡ %s\x1b[0m', 'Backing up package.json...')
|
||||
fs.copyFileSync('package.json', 'package.json.backup')
|
||||
console.log('\x1b[32m✔ %s\x1b[0m', 'package.json has been backed up')
|
||||
|
||||
try {
|
||||
if (packageJson?.dependencies.deepspeech) {
|
||||
console.info('\x1b[36m➡ %s\x1b[0m', 'Removing DeepSpeech dependency...')
|
||||
|
||||
delete packageJson.dependencies.deepspeech
|
||||
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))
|
||||
|
||||
console.log('\x1b[32m✔ %s\x1b[0m', 'DeepSpeech dependency has been removed.')
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('\x1b[31m✖ %s\x1b[0m', 'Failed to remove DeepSpeech dependency')
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,5 @@
|
||||
import fs from 'fs'
|
||||
|
||||
import loader from '@/helpers/loader'
|
||||
import log from '@/helpers/log'
|
||||
import os from '@/helpers/os'
|
||||
|
||||
import train from '../train'
|
||||
import generateHttpApiKey from '../generate/generate-http-api-key'
|
||||
@ -18,8 +15,6 @@ import setupPythonPackages from './setup-python-packages'
|
||||
*/
|
||||
(async () => {
|
||||
try {
|
||||
const info = os.get()
|
||||
|
||||
// Required env vars to setup
|
||||
process.env.LEON_LANG = 'en-US'
|
||||
process.env.PIPENV_PIPFILE = 'bridges/python/Pipfile'
|
||||
@ -36,12 +31,6 @@ import setupPythonPackages from './setup-python-packages'
|
||||
await generateHttpApiKey()
|
||||
loader.start()
|
||||
await train()
|
||||
if (info.type === 'windows') {
|
||||
log.info('Windows detected, reinjecting DeepSpeech into package.json...')
|
||||
fs.unlinkSync('package.json')
|
||||
fs.renameSync('package.json.backup', 'package.json')
|
||||
log.success('DeepSpeech has been reinjected into package.json')
|
||||
}
|
||||
|
||||
log.default('')
|
||||
log.success('Hooray! Leon is installed and ready to go!')
|
||||
|
@ -1,30 +1,12 @@
|
||||
import wav from 'node-wav'
|
||||
import fs from 'fs'
|
||||
import { Model } from 'stt'
|
||||
|
||||
import log from '@/helpers/log'
|
||||
|
||||
log.title('DeepSpeech Parser')
|
||||
log.title('Coqui STT Parser')
|
||||
|
||||
const parser = { }
|
||||
let DeepSpeech = { }
|
||||
|
||||
/* istanbul ignore next */
|
||||
try {
|
||||
DeepSpeech = require('deepspeech-gpu') // eslint-disable-line global-require, import/no-unresolved
|
||||
|
||||
log.success('GPU version found')
|
||||
} catch (eGpu) {
|
||||
log.info('GPU version not found, trying to get the CPU version...')
|
||||
|
||||
try {
|
||||
DeepSpeech = require('deepspeech') // eslint-disable-line global-require, import/no-unresolved
|
||||
|
||||
log.success('CPU version found')
|
||||
} catch (eCpu) {
|
||||
log.error(`No DeepSpeech library found:\nGPU: ${eGpu}\nCPU: ${eCpu}`)
|
||||
}
|
||||
}
|
||||
|
||||
let model = { }
|
||||
let desiredSampleRate = 16000
|
||||
|
||||
@ -32,19 +14,14 @@ let desiredSampleRate = 16000
|
||||
* Model and language model paths
|
||||
*/
|
||||
parser.conf = {
|
||||
model: 'bin/deepspeech/deepspeech.pbmm',
|
||||
scorer: 'bin/deepspeech/deepspeech.scorer'
|
||||
model: 'bin/coqui/model.tflite',
|
||||
scorer: 'bin/coqui/huge-vocabulary.scorer'
|
||||
}
|
||||
|
||||
/**
|
||||
* Load models
|
||||
*/
|
||||
parser.init = (args) => {
|
||||
/* istanbul ignore if */
|
||||
if (process.env.LEON_LANG !== 'en-US') {
|
||||
log.warning('The DeepSpeech parser only accepts the "en-US" language for the moment')
|
||||
}
|
||||
|
||||
log.info(`Loading model from file ${args.model}...`)
|
||||
|
||||
if (!fs.existsSync(args.model)) {
|
||||
@ -61,10 +38,18 @@ parser.init = (args) => {
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (process.env.LEON_NODE_ENV !== 'testing') {
|
||||
model = new DeepSpeech.Model(args.model)
|
||||
try {
|
||||
model = new Model(args.model)
|
||||
} catch (error) {
|
||||
throw Error(`model.stt: ${error}`)
|
||||
}
|
||||
desiredSampleRate = model.sampleRate()
|
||||
|
||||
model.enableExternalScorer(args.scorer)
|
||||
try {
|
||||
model.enableExternalScorer(args.scorer)
|
||||
} catch (error) {
|
||||
throw Error(`model.enableExternalScorer: ${error}`)
|
||||
}
|
||||
}
|
||||
|
||||
log.success('Model loaded')
|
@ -8,9 +8,9 @@ class Stt {
|
||||
this.socket = socket
|
||||
this.provider = provider
|
||||
this.providers = [
|
||||
'deepspeech',
|
||||
'google-cloud-stt',
|
||||
'watson-stt'
|
||||
'watson-stt',
|
||||
'coqui-stt'
|
||||
]
|
||||
this.parser = { }
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
import fs from 'fs'
|
||||
|
||||
import parser from '@/stt/deepspeech/parser'
|
||||
import parser from '@/stt/coqui-stt/parser'
|
||||
|
||||
describe('DeepSpeech STT parser', () => {
|
||||
describe('Coqui STT parser', () => {
|
||||
// Only run these tests if the models exist
|
||||
if (fs.existsSync(`${global.paths.root}/bin/deepspeech/deepspeech.pbmm`)
|
||||
&& fs.existsSync(`${global.paths.root}/bin/deepspeech/deepspeech.scorer`)) {
|
||||
if (fs.existsSync(`${global.paths.root}/bin/coqui/model.tflite`)
|
||||
&& fs.existsSync(`${global.paths.root}/bin/coqui/huge-vocabulary.scorer`)) {
|
||||
describe('init()', () => {
|
||||
test('returns error cannot find model', () => {
|
||||
expect(parser.init({
|
||||
@ -15,15 +15,15 @@ describe('DeepSpeech STT parser', () => {
|
||||
|
||||
test('returns error cannot find scorer', () => {
|
||||
expect(parser.init({
|
||||
model: `${global.paths.root}/bin/deepspeech/deepspeech.pbmm`,
|
||||
model: `${global.paths.root}/bin/coqui/model.tflite`,
|
||||
scorer: 'fake-scorer-path'
|
||||
})).toBeFalsy()
|
||||
})
|
||||
|
||||
test('returns true because all of the paths are good', () => {
|
||||
expect(parser.init({
|
||||
model: `${global.paths.root}/bin/deepspeech/deepspeech.pbmm`,
|
||||
scorer: `${global.paths.root}/bin/deepspeech/deepspeech.scorer`
|
||||
model: `${global.paths.root}/bin/coqui/model.tflite`,
|
||||
scorer: `${global.paths.root}/bin/coqui/huge-vocabulary.scorer`
|
||||
})).toBeTruthy()
|
||||
})
|
||||
})
|
@ -3,7 +3,7 @@ import Stt from '@/stt/stt'
|
||||
describe('STT', () => {
|
||||
describe('constructor()', () => {
|
||||
test('creates a new instance of Stt', () => {
|
||||
const stt = new Stt({ }, 'deepspeech')
|
||||
const stt = new Stt({ }, 'coqui-stt')
|
||||
|
||||
expect(stt).toBeInstanceOf(Stt)
|
||||
})
|
||||
@ -17,7 +17,7 @@ describe('STT', () => {
|
||||
})
|
||||
|
||||
test('initializes the STT parser', () => {
|
||||
const stt = new Stt({ }, 'deepspeech')
|
||||
const stt = new Stt({ }, 'coqui-stt')
|
||||
|
||||
expect(stt.init()).toBeTruthy()
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user