xiaogpt 2.41__tar.gz → 2.50__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {xiaogpt-2.41 → xiaogpt-2.50}/PKG-INFO +116 -33
- {xiaogpt-2.41 → xiaogpt-2.50}/README.md +15 -27
- xiaogpt-2.50/pyproject.toml +165 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/config.py +10 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/tts/__init__.py +2 -1
- xiaogpt-2.50/xiaogpt/tts/volc.py +130 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/xiaogpt.py +6 -3
- xiaogpt-2.41/pyproject.toml +0 -65
- {xiaogpt-2.41 → xiaogpt-2.50}/LICENSE +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/__init__.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/__main__.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/bot/__init__.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/bot/base_bot.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/bot/chatgptapi_bot.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/bot/gemini_bot.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/bot/glm_bot.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/bot/langchain_bot.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/bot/newbing_bot.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/bot/qwen_bot.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/cli.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/langchain/callbacks.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/langchain/chain.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/langchain/examples/email/mail_box.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/langchain/examples/email/mail_summary_tools.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/tts/azure.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/tts/base.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/tts/edge.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/tts/mi.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/tts/openai.py +0 -0
- {xiaogpt-2.41 → xiaogpt-2.50}/xiaogpt/utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: xiaogpt
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.50
|
4
4
|
Summary: Play ChatGPT or other LLM with xiaomi AI speaker
|
5
5
|
Author-Email: yihong0618 <zouzou0208@gmail.com>
|
6
6
|
License: MIT
|
@@ -13,8 +13,8 @@ Requires-Dist: miservice_fork
|
|
13
13
|
Requires-Dist: openai>=1
|
14
14
|
Requires-Dist: aiohttp
|
15
15
|
Requires-Dist: rich
|
16
|
-
Requires-Dist: zhipuai
|
17
|
-
Requires-Dist: httpx
|
16
|
+
Requires-Dist: zhipuai>=2.0.1
|
17
|
+
Requires-Dist: httpx[socks]
|
18
18
|
Requires-Dist: edge-tts>=6.1.3
|
19
19
|
Requires-Dist: EdgeGPT==0.1.26
|
20
20
|
Requires-Dist: langchain>=0.0.343
|
@@ -22,10 +22,105 @@ Requires-Dist: beautifulsoup4>=4.12.0
|
|
22
22
|
Requires-Dist: google-search-results>=2.4.2
|
23
23
|
Requires-Dist: google-generativeai
|
24
24
|
Requires-Dist: numexpr>=2.8.6
|
25
|
-
Requires-Dist: dashscope
|
26
|
-
Requires-Dist: httpcore==0.15.0
|
27
|
-
Requires-Dist: idna==3.7
|
25
|
+
Requires-Dist: dashscope>=1.10.0
|
28
26
|
Requires-Dist: azure-cognitiveservices-speech>=1.37.0
|
27
|
+
Requires-Dist: multidict>=6.0.5
|
28
|
+
Requires-Dist: volcengine>=1.0.136
|
29
|
+
Requires-Dist: aiohttp==3.9.4; extra == "locked"
|
30
|
+
Requires-Dist: aiosignal==1.3.1; extra == "locked"
|
31
|
+
Requires-Dist: annotated-types==0.6.0; extra == "locked"
|
32
|
+
Requires-Dist: anyio==3.7.1; extra == "locked"
|
33
|
+
Requires-Dist: async-timeout==4.0.3; python_version < "3.11" and extra == "locked"
|
34
|
+
Requires-Dist: attrs==23.2.0; extra == "locked"
|
35
|
+
Requires-Dist: azure-cognitiveservices-speech==1.37.0; extra == "locked"
|
36
|
+
Requires-Dist: beautifulsoup4==4.12.3; extra == "locked"
|
37
|
+
Requires-Dist: bingimagecreator==0.5.0; extra == "locked"
|
38
|
+
Requires-Dist: cachetools==5.3.2; extra == "locked"
|
39
|
+
Requires-Dist: certifi==2024.2.2; extra == "locked"
|
40
|
+
Requires-Dist: charset-normalizer==3.3.2; extra == "locked"
|
41
|
+
Requires-Dist: colorama==0.4.6; platform_system == "Windows" and extra == "locked"
|
42
|
+
Requires-Dist: dashscope==1.10.0; extra == "locked"
|
43
|
+
Requires-Dist: dataclasses-json==0.6.3; extra == "locked"
|
44
|
+
Requires-Dist: decorator==5.1.1; extra == "locked"
|
45
|
+
Requires-Dist: distro==1.9.0; extra == "locked"
|
46
|
+
Requires-Dist: edge-tts==6.1.10; extra == "locked"
|
47
|
+
Requires-Dist: edgegpt==0.1.26; extra == "locked"
|
48
|
+
Requires-Dist: exceptiongroup==1.2.0; python_version < "3.11" and extra == "locked"
|
49
|
+
Requires-Dist: frozenlist==1.4.1; extra == "locked"
|
50
|
+
Requires-Dist: google==3.0.0; extra == "locked"
|
51
|
+
Requires-Dist: google-ai-generativelanguage==0.6.1; extra == "locked"
|
52
|
+
Requires-Dist: google-api-core==2.15.0; extra == "locked"
|
53
|
+
Requires-Dist: google-api-core[grpc]==2.15.0; extra == "locked"
|
54
|
+
Requires-Dist: google-api-python-client==2.125.0; extra == "locked"
|
55
|
+
Requires-Dist: google-auth==2.26.1; extra == "locked"
|
56
|
+
Requires-Dist: google-auth-httplib2==0.2.0; extra == "locked"
|
57
|
+
Requires-Dist: google-generativeai==0.5.0; extra == "locked"
|
58
|
+
Requires-Dist: google-search-results==2.4.2; extra == "locked"
|
59
|
+
Requires-Dist: googleapis-common-protos==1.62.0; extra == "locked"
|
60
|
+
Requires-Dist: greenlet==3.0.3; (platform_machine == "win32" or platform_machine == "WIN32" or platform_machine == "AMD64" or platform_machine == "amd64" or platform_machine == "x86_64" or platform_machine == "ppc64le" or platform_machine == "aarch64") and extra == "locked"
|
61
|
+
Requires-Dist: grpcio==1.60.0; extra == "locked"
|
62
|
+
Requires-Dist: grpcio-status==1.60.0; extra == "locked"
|
63
|
+
Requires-Dist: h11==0.14.0; extra == "locked"
|
64
|
+
Requires-Dist: httpcore==1.0.5; extra == "locked"
|
65
|
+
Requires-Dist: httplib2==0.22.0; extra == "locked"
|
66
|
+
Requires-Dist: httpx==0.27.0; extra == "locked"
|
67
|
+
Requires-Dist: httpx[socks]==0.27.0; extra == "locked"
|
68
|
+
Requires-Dist: idna==3.7; extra == "locked"
|
69
|
+
Requires-Dist: jsonpatch==1.33; extra == "locked"
|
70
|
+
Requires-Dist: jsonpointer==2.4; extra == "locked"
|
71
|
+
Requires-Dist: langchain==0.1.16; extra == "locked"
|
72
|
+
Requires-Dist: langchain-community==0.0.32; extra == "locked"
|
73
|
+
Requires-Dist: langchain-core==0.1.42; extra == "locked"
|
74
|
+
Requires-Dist: langchain-text-splitters==0.0.1; extra == "locked"
|
75
|
+
Requires-Dist: langsmith==0.1.45; extra == "locked"
|
76
|
+
Requires-Dist: markdown-it-py==3.0.0; extra == "locked"
|
77
|
+
Requires-Dist: marshmallow==3.20.1; extra == "locked"
|
78
|
+
Requires-Dist: mdurl==0.1.2; extra == "locked"
|
79
|
+
Requires-Dist: miservice-fork==2.4.3; extra == "locked"
|
80
|
+
Requires-Dist: multidict==6.0.5; extra == "locked"
|
81
|
+
Requires-Dist: mutagen==1.47.0; extra == "locked"
|
82
|
+
Requires-Dist: mypy-extensions==1.0.0; extra == "locked"
|
83
|
+
Requires-Dist: numexpr==2.10.0; extra == "locked"
|
84
|
+
Requires-Dist: numpy==1.26.3; extra == "locked"
|
85
|
+
Requires-Dist: openai==1.17.1; extra == "locked"
|
86
|
+
Requires-Dist: orjson==3.10.0; extra == "locked"
|
87
|
+
Requires-Dist: packaging==23.2; extra == "locked"
|
88
|
+
Requires-Dist: prompt-toolkit==3.0.43; extra == "locked"
|
89
|
+
Requires-Dist: proto-plus==1.23.0; extra == "locked"
|
90
|
+
Requires-Dist: protobuf==4.25.1; extra == "locked"
|
91
|
+
Requires-Dist: py==1.11.0; extra == "locked"
|
92
|
+
Requires-Dist: pyasn1==0.5.1; extra == "locked"
|
93
|
+
Requires-Dist: pyasn1-modules==0.3.0; extra == "locked"
|
94
|
+
Requires-Dist: pycryptodome==3.9.9; extra == "locked"
|
95
|
+
Requires-Dist: pydantic==2.5.3; extra == "locked"
|
96
|
+
Requires-Dist: pydantic-core==2.14.6; extra == "locked"
|
97
|
+
Requires-Dist: pygments==2.17.2; extra == "locked"
|
98
|
+
Requires-Dist: pyjwt==2.8.0; extra == "locked"
|
99
|
+
Requires-Dist: pyparsing==3.1.2; python_version > "3.0" and extra == "locked"
|
100
|
+
Requires-Dist: pytz==2020.5; extra == "locked"
|
101
|
+
Requires-Dist: pyyaml==6.0.1; extra == "locked"
|
102
|
+
Requires-Dist: regex==2023.12.25; extra == "locked"
|
103
|
+
Requires-Dist: requests==2.31.0; extra == "locked"
|
104
|
+
Requires-Dist: retry==0.9.2; extra == "locked"
|
105
|
+
Requires-Dist: rich==13.7.1; extra == "locked"
|
106
|
+
Requires-Dist: rsa==4.9; extra == "locked"
|
107
|
+
Requires-Dist: six==1.16.0; extra == "locked"
|
108
|
+
Requires-Dist: sniffio==1.3.0; extra == "locked"
|
109
|
+
Requires-Dist: socksio==1.0.0; extra == "locked"
|
110
|
+
Requires-Dist: soupsieve==2.5; extra == "locked"
|
111
|
+
Requires-Dist: sqlalchemy==2.0.25; extra == "locked"
|
112
|
+
Requires-Dist: tenacity==8.2.3; extra == "locked"
|
113
|
+
Requires-Dist: tqdm==4.66.1; extra == "locked"
|
114
|
+
Requires-Dist: typing-extensions==4.9.0; extra == "locked"
|
115
|
+
Requires-Dist: typing-inspect==0.9.0; extra == "locked"
|
116
|
+
Requires-Dist: uritemplate==4.1.1; extra == "locked"
|
117
|
+
Requires-Dist: urllib3==2.1.0; extra == "locked"
|
118
|
+
Requires-Dist: volcengine==1.0.136; extra == "locked"
|
119
|
+
Requires-Dist: wcwidth==0.2.13; extra == "locked"
|
120
|
+
Requires-Dist: websockets==12.0; extra == "locked"
|
121
|
+
Requires-Dist: yarl==1.9.4; extra == "locked"
|
122
|
+
Requires-Dist: zhipuai==2.0.1; extra == "locked"
|
123
|
+
Provides-Extra: locked
|
29
124
|
Description-Content-Type: text/markdown
|
30
125
|
|
31
126
|
# xiaogpt
|
@@ -49,32 +144,15 @@ Play ChatGPT and other LLM with Xiaomi AI Speaker
|
|
49
144
|
- [通义千问](https://help.aliyun.com/zh/dashscope/developer-reference/api-details)
|
50
145
|
|
51
146
|
## 获取小米音响DID
|
52
|
-
|
53
|
-
|
54
|
-
pip install miservice_fork
|
55
|
-
set MI_USER=
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
147
|
+
系统和Shell|Linux *sh|Windows CMD用户|Windows PowerShell用户
|
148
|
+
-|-|-|-
|
149
|
+
1、安装包|`pip install miservice_fork`|`pip install miservice_fork`|`pip install miservice_fork`
|
150
|
+
2、设置变量|`export MI_USER=xxx` <br> `export MI_PASS=xxx`|`set MI_USER=xxx`<br>`set MI_PASS=xxx`|`$env:MI_USER="xxx"` <br> `$env:MI_PASS="xxx"`
|
151
|
+
3、取得MI_DID|`micli list` |`micli list` |`micli list`
|
152
|
+
4、设置MI_DID|`export MI_DID=xxx`| `set MI_DID=xxx`| `$env:MI_DID="xxx"`
|
153
|
+
|
154
|
+
- 注意不同shell 对环境变量的处理是不同的,尤其是powershell赋值时,可能需要双引号来包括值。
|
61
155
|
- 如果获取did报错时,请更换一下无线网络,有很大概率解决问题。
|
62
|
-
|
63
|
-
### Linux(使用 export 设置环境变量)
|
64
|
-
```sh
|
65
|
-
# 1、安装模块
|
66
|
-
pip install miservice_fork
|
67
|
-
|
68
|
-
# 2、设置环境用户参数
|
69
|
-
export MI_USER=xxxx
|
70
|
-
export MI_PASS=xxx
|
71
|
-
|
72
|
-
# 3、使用micli list 得到did
|
73
|
-
micli list
|
74
|
-
|
75
|
-
# 4、根据did设置环境DID参数
|
76
|
-
export MI_DID=xxxx
|
77
|
-
```
|
78
156
|
|
79
157
|
## 一点原理
|
80
158
|
|
@@ -89,7 +167,7 @@ export MI_DID=xxxx
|
|
89
167
|
|
90
168
|
## 使用
|
91
169
|
|
92
|
-
- `pip install -U --force-reinstall xiaogpt`
|
170
|
+
- `pip install -U --force-reinstall xiaogpt[locked]`
|
93
171
|
- 参考我 fork 的 [MiService](https://github.com/yihong0618/MiService) 项目 README 并在本地 terminal 跑 `micli list` 拿到你音响的 DID 成功 **别忘了设置 export MI_DID=xxx** 这个 MI_DID 用
|
94
172
|
- run `xiaogpt --hardware ${your_hardware} --use_chatgpt_api` hardware 你看小爱屁股上有型号,输入进来,如果在屁股上找不到或者型号不对,可以用 `micli mina` 找到型号
|
95
173
|
- 跑起来之后就可以问小爱同学问题了,“帮我"开头的问题,会发送一份给 ChatGPT 然后小爱同学用 tts 回答
|
@@ -209,7 +287,7 @@ ChatGLM [文档](http://open.bigmodel.cn/doc/api#chatglm_130b)
|
|
209
287
|
| mute_xiaoai | 快速停掉小爱自己的回答 | `true` | |
|
210
288
|
| verbose | 是否打印详细日志 | `false` | |
|
211
289
|
| bot | 使用的 bot 类型,目前支持 chatgptapi,newbing, qwen, gemini | `chatgptapi` | |
|
212
|
-
| tts | 使用的 TTS 类型 | `mi` | `edge`、 `openai`、`azure` |
|
290
|
+
| tts | 使用的 TTS 类型 | `mi` | `edge`、 `openai`、`azure`、`volc` |
|
213
291
|
| tts_voice | TTS 的嗓音 | `zh-CN-XiaoxiaoNeural`(edge), `alloy`(openai), `zh-CN-XiaoxiaoMultilingualNeural`(azure) | |
|
214
292
|
| prompt | 自定义prompt | `请用100字以内回答` | |
|
215
293
|
| keyword | 自定义请求词列表 | `["请"]` | |
|
@@ -225,6 +303,11 @@ ChatGLM [文档](http://open.bigmodel.cn/doc/api#chatglm_130b)
|
|
225
303
|
| api_base | 如果需要替换默认的api,或者使用Azure OpenAI 服务 | 例如:`https://abc-def.openai.azure.com/` | |
|
226
304
|
| azure_tts_speech_key | Azure TTS key | null | |
|
227
305
|
| azure_tts_service_region | Azure TTS 服务地区 | `eastasia` | [Regions - Speech service - Azure AI services](https://learn.microsoft.com/en-us/azure/ai-services/speech-service/regions) |
|
306
|
+
| volc_accesskey | 火山引擎accesskey [参考](https://console.volcengine.com/iam/keymanage/) | | |
|
307
|
+
| volc_secretkey | 火山引擎secretkey [参考](https://console.volcengine.com/iam/keymanage/) | | |
|
308
|
+
| volc_tts_app | 火山引擎 TTS app 服务 [参考]( https://console.volcengine.com/sami/) | | |
|
309
|
+
| volc_tts_speaker | 火山引擎 TTS speaker [参考]( https://www.volcengine.com/docs/6489/93478) | `zh_female_qingxin` | |
|
310
|
+
|
228
311
|
|
229
312
|
[这里]: https://github.com/acheong08/EdgeGPT#getting-authentication-required
|
230
313
|
|
@@ -19,32 +19,15 @@ Play ChatGPT and other LLM with Xiaomi AI Speaker
|
|
19
19
|
- [通义千问](https://help.aliyun.com/zh/dashscope/developer-reference/api-details)
|
20
20
|
|
21
21
|
## 获取小米音响DID
|
22
|
-
|
23
|
-
|
24
|
-
pip install miservice_fork
|
25
|
-
set MI_USER=
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
22
|
+
系统和Shell|Linux *sh|Windows CMD用户|Windows PowerShell用户
|
23
|
+
-|-|-|-
|
24
|
+
1、安装包|`pip install miservice_fork`|`pip install miservice_fork`|`pip install miservice_fork`
|
25
|
+
2、设置变量|`export MI_USER=xxx` <br> `export MI_PASS=xxx`|`set MI_USER=xxx`<br>`set MI_PASS=xxx`|`$env:MI_USER="xxx"` <br> `$env:MI_PASS="xxx"`
|
26
|
+
3、取得MI_DID|`micli list` |`micli list` |`micli list`
|
27
|
+
4、设置MI_DID|`export MI_DID=xxx`| `set MI_DID=xxx`| `$env:MI_DID="xxx"`
|
28
|
+
|
29
|
+
- 注意不同shell 对环境变量的处理是不同的,尤其是powershell赋值时,可能需要双引号来包括值。
|
31
30
|
- 如果获取did报错时,请更换一下无线网络,有很大概率解决问题。
|
32
|
-
|
33
|
-
### Linux(使用 export 设置环境变量)
|
34
|
-
```sh
|
35
|
-
# 1、安装模块
|
36
|
-
pip install miservice_fork
|
37
|
-
|
38
|
-
# 2、设置环境用户参数
|
39
|
-
export MI_USER=xxxx
|
40
|
-
export MI_PASS=xxx
|
41
|
-
|
42
|
-
# 3、使用micli list 得到did
|
43
|
-
micli list
|
44
|
-
|
45
|
-
# 4、根据did设置环境DID参数
|
46
|
-
export MI_DID=xxxx
|
47
|
-
```
|
48
31
|
|
49
32
|
## 一点原理
|
50
33
|
|
@@ -59,7 +42,7 @@ export MI_DID=xxxx
|
|
59
42
|
|
60
43
|
## 使用
|
61
44
|
|
62
|
-
- `pip install -U --force-reinstall xiaogpt`
|
45
|
+
- `pip install -U --force-reinstall xiaogpt[locked]`
|
63
46
|
- 参考我 fork 的 [MiService](https://github.com/yihong0618/MiService) 项目 README 并在本地 terminal 跑 `micli list` 拿到你音响的 DID 成功 **别忘了设置 export MI_DID=xxx** 这个 MI_DID 用
|
64
47
|
- run `xiaogpt --hardware ${your_hardware} --use_chatgpt_api` hardware 你看小爱屁股上有型号,输入进来,如果在屁股上找不到或者型号不对,可以用 `micli mina` 找到型号
|
65
48
|
- 跑起来之后就可以问小爱同学问题了,“帮我"开头的问题,会发送一份给 ChatGPT 然后小爱同学用 tts 回答
|
@@ -179,7 +162,7 @@ ChatGLM [文档](http://open.bigmodel.cn/doc/api#chatglm_130b)
|
|
179
162
|
| mute_xiaoai | 快速停掉小爱自己的回答 | `true` | |
|
180
163
|
| verbose | 是否打印详细日志 | `false` | |
|
181
164
|
| bot | 使用的 bot 类型,目前支持 chatgptapi,newbing, qwen, gemini | `chatgptapi` | |
|
182
|
-
| tts | 使用的 TTS 类型 | `mi` | `edge`、 `openai`、`azure` |
|
165
|
+
| tts | 使用的 TTS 类型 | `mi` | `edge`、 `openai`、`azure`、`volc` |
|
183
166
|
| tts_voice | TTS 的嗓音 | `zh-CN-XiaoxiaoNeural`(edge), `alloy`(openai), `zh-CN-XiaoxiaoMultilingualNeural`(azure) | |
|
184
167
|
| prompt | 自定义prompt | `请用100字以内回答` | |
|
185
168
|
| keyword | 自定义请求词列表 | `["请"]` | |
|
@@ -195,6 +178,11 @@ ChatGLM [文档](http://open.bigmodel.cn/doc/api#chatglm_130b)
|
|
195
178
|
| api_base | 如果需要替换默认的api,或者使用Azure OpenAI 服务 | 例如:`https://abc-def.openai.azure.com/` | |
|
196
179
|
| azure_tts_speech_key | Azure TTS key | null | |
|
197
180
|
| azure_tts_service_region | Azure TTS 服务地区 | `eastasia` | [Regions - Speech service - Azure AI services](https://learn.microsoft.com/en-us/azure/ai-services/speech-service/regions) |
|
181
|
+
| volc_accesskey | 火山引擎accesskey [参考](https://console.volcengine.com/iam/keymanage/) | | |
|
182
|
+
| volc_secretkey | 火山引擎secretkey [参考](https://console.volcengine.com/iam/keymanage/) | | |
|
183
|
+
| volc_tts_app | 火山引擎 TTS app 服务 [参考]( https://console.volcengine.com/sami/) | | |
|
184
|
+
| volc_tts_speaker | 火山引擎 TTS speaker [参考]( https://www.volcengine.com/docs/6489/93478) | `zh_female_qingxin` | |
|
185
|
+
|
198
186
|
|
199
187
|
[这里]: https://github.com/acheong08/EdgeGPT#getting-authentication-required
|
200
188
|
|
@@ -0,0 +1,165 @@
|
|
1
|
+
[project]
|
2
|
+
name = "xiaogpt"
|
3
|
+
description = "Play ChatGPT or other LLM with xiaomi AI speaker"
|
4
|
+
readme = "README.md"
|
5
|
+
authors = [
|
6
|
+
{ name = "yihong0618", email = "zouzou0208@gmail.com" },
|
7
|
+
]
|
8
|
+
classifiers = [
|
9
|
+
"License :: OSI Approved :: MIT License",
|
10
|
+
"Operating System :: OS Independent",
|
11
|
+
"Programming Language :: Python :: 3",
|
12
|
+
]
|
13
|
+
requires-python = ">=3.9"
|
14
|
+
dependencies = [
|
15
|
+
"miservice_fork",
|
16
|
+
"openai>=1",
|
17
|
+
"aiohttp",
|
18
|
+
"rich",
|
19
|
+
"zhipuai>=2.0.1",
|
20
|
+
"httpx[socks]",
|
21
|
+
"edge-tts>=6.1.3",
|
22
|
+
"EdgeGPT==0.1.26",
|
23
|
+
"langchain>=0.0.343",
|
24
|
+
"beautifulsoup4>=4.12.0",
|
25
|
+
"google-search-results>=2.4.2",
|
26
|
+
"google-generativeai",
|
27
|
+
"numexpr>=2.8.6",
|
28
|
+
"dashscope>=1.10.0",
|
29
|
+
"azure-cognitiveservices-speech>=1.37.0",
|
30
|
+
"multidict>=6.0.5",
|
31
|
+
"volcengine>=1.0.136",
|
32
|
+
]
|
33
|
+
dynamic = []
|
34
|
+
version = "2.50"
|
35
|
+
|
36
|
+
[project.license]
|
37
|
+
text = "MIT"
|
38
|
+
|
39
|
+
[project.urls]
|
40
|
+
Homepage = "https://github.com/yihong0618/xiaogpt"
|
41
|
+
|
42
|
+
[project.scripts]
|
43
|
+
xiaogpt = "xiaogpt.cli:main"
|
44
|
+
|
45
|
+
[project.optional-dependencies]
|
46
|
+
locked = [
|
47
|
+
"aiohttp==3.9.4",
|
48
|
+
"aiosignal==1.3.1",
|
49
|
+
"annotated-types==0.6.0",
|
50
|
+
"anyio==3.7.1",
|
51
|
+
"async-timeout==4.0.3 ; python_version < \"3.11\"",
|
52
|
+
"attrs==23.2.0",
|
53
|
+
"azure-cognitiveservices-speech==1.37.0",
|
54
|
+
"beautifulsoup4==4.12.3",
|
55
|
+
"bingimagecreator==0.5.0",
|
56
|
+
"cachetools==5.3.2",
|
57
|
+
"certifi==2024.2.2",
|
58
|
+
"charset-normalizer==3.3.2",
|
59
|
+
"colorama==0.4.6 ; platform_system == \"Windows\"",
|
60
|
+
"dashscope==1.10.0",
|
61
|
+
"dataclasses-json==0.6.3",
|
62
|
+
"decorator==5.1.1",
|
63
|
+
"distro==1.9.0",
|
64
|
+
"edge-tts==6.1.10",
|
65
|
+
"edgegpt==0.1.26",
|
66
|
+
"exceptiongroup==1.2.0 ; python_version < \"3.11\"",
|
67
|
+
"frozenlist==1.4.1",
|
68
|
+
"google==3.0.0",
|
69
|
+
"google-ai-generativelanguage==0.6.1",
|
70
|
+
"google-api-core==2.15.0",
|
71
|
+
"google-api-core[grpc]==2.15.0",
|
72
|
+
"google-api-python-client==2.125.0",
|
73
|
+
"google-auth==2.26.1",
|
74
|
+
"google-auth-httplib2==0.2.0",
|
75
|
+
"google-generativeai==0.5.0",
|
76
|
+
"google-search-results==2.4.2",
|
77
|
+
"googleapis-common-protos==1.62.0",
|
78
|
+
"greenlet==3.0.3 ; platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\"",
|
79
|
+
"grpcio==1.60.0",
|
80
|
+
"grpcio-status==1.60.0",
|
81
|
+
"h11==0.14.0",
|
82
|
+
"httpcore==1.0.5",
|
83
|
+
"httplib2==0.22.0",
|
84
|
+
"httpx==0.27.0",
|
85
|
+
"httpx[socks]==0.27.0",
|
86
|
+
"idna==3.7",
|
87
|
+
"jsonpatch==1.33",
|
88
|
+
"jsonpointer==2.4",
|
89
|
+
"langchain==0.1.16",
|
90
|
+
"langchain-community==0.0.32",
|
91
|
+
"langchain-core==0.1.42",
|
92
|
+
"langchain-text-splitters==0.0.1",
|
93
|
+
"langsmith==0.1.45",
|
94
|
+
"markdown-it-py==3.0.0",
|
95
|
+
"marshmallow==3.20.1",
|
96
|
+
"mdurl==0.1.2",
|
97
|
+
"miservice-fork==2.4.3",
|
98
|
+
"multidict==6.0.5",
|
99
|
+
"mutagen==1.47.0",
|
100
|
+
"mypy-extensions==1.0.0",
|
101
|
+
"numexpr==2.10.0",
|
102
|
+
"numpy==1.26.3",
|
103
|
+
"openai==1.17.1",
|
104
|
+
"orjson==3.10.0",
|
105
|
+
"packaging==23.2",
|
106
|
+
"prompt-toolkit==3.0.43",
|
107
|
+
"proto-plus==1.23.0",
|
108
|
+
"protobuf==4.25.1",
|
109
|
+
"py==1.11.0",
|
110
|
+
"pyasn1==0.5.1",
|
111
|
+
"pyasn1-modules==0.3.0",
|
112
|
+
"pycryptodome==3.9.9",
|
113
|
+
"pydantic==2.5.3",
|
114
|
+
"pydantic-core==2.14.6",
|
115
|
+
"pygments==2.17.2",
|
116
|
+
"pyjwt==2.8.0",
|
117
|
+
"pyparsing==3.1.2 ; python_version > \"3.0\"",
|
118
|
+
"pytz==2020.5",
|
119
|
+
"pyyaml==6.0.1",
|
120
|
+
"regex==2023.12.25",
|
121
|
+
"requests==2.31.0",
|
122
|
+
"retry==0.9.2",
|
123
|
+
"rich==13.7.1",
|
124
|
+
"rsa==4.9",
|
125
|
+
"six==1.16.0",
|
126
|
+
"sniffio==1.3.0",
|
127
|
+
"socksio==1.0.0",
|
128
|
+
"soupsieve==2.5",
|
129
|
+
"sqlalchemy==2.0.25",
|
130
|
+
"tenacity==8.2.3",
|
131
|
+
"tqdm==4.66.1",
|
132
|
+
"typing-extensions==4.9.0",
|
133
|
+
"typing-inspect==0.9.0",
|
134
|
+
"uritemplate==4.1.1",
|
135
|
+
"urllib3==2.1.0",
|
136
|
+
"volcengine==1.0.136",
|
137
|
+
"wcwidth==0.2.13",
|
138
|
+
"websockets==12.0",
|
139
|
+
"yarl==1.9.4",
|
140
|
+
"zhipuai==2.0.1",
|
141
|
+
]
|
142
|
+
|
143
|
+
[tool.pdm]
|
144
|
+
plugins = [
|
145
|
+
"pdm-autoexport",
|
146
|
+
]
|
147
|
+
autoexport = [
|
148
|
+
{ filename = "requirements.txt", without-hashes = true },
|
149
|
+
]
|
150
|
+
|
151
|
+
[tool.pdm.version]
|
152
|
+
source = "scm"
|
153
|
+
|
154
|
+
[tool.pdm.build]
|
155
|
+
includes = [
|
156
|
+
"xiaogpt/",
|
157
|
+
]
|
158
|
+
locked = true
|
159
|
+
|
160
|
+
[build-system]
|
161
|
+
requires = [
|
162
|
+
"pdm-backend>=2.0.0",
|
163
|
+
"pdm-build-locked",
|
164
|
+
]
|
165
|
+
build-backend = "pdm.backend"
|
@@ -87,6 +87,16 @@ class Config:
|
|
87
87
|
bing_cookies: dict | None = None
|
88
88
|
azure_tts_speech_key: str | None = None
|
89
89
|
azure_tts_service_region: str = "eastasia"
|
90
|
+
volc_accesskey: str = os.getenv(
|
91
|
+
"VOLC_ACCESSKEY", ""
|
92
|
+
) # https://console.volcengine.com/iam/keymanage/
|
93
|
+
volc_secretkey: str = os.getenv("VOLC_SECRETKEY", "")
|
94
|
+
volc_tts_app: str = os.getenv(
|
95
|
+
"VOLC_TTS_APP", ""
|
96
|
+
) # https://console.volcengine.com/sami
|
97
|
+
volc_tts_speaker: str = os.getenv(
|
98
|
+
"VOLC_TTS_SPEAPER", "zh_female_qingxin"
|
99
|
+
) # https://www.volcengine.com/docs/6489/93478
|
90
100
|
|
91
101
|
def __post_init__(self) -> None:
|
92
102
|
if self.proxy:
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from xiaogpt.tts.base import TTS as TTS
|
2
2
|
from xiaogpt.tts.edge import EdgeTTS as EdgeTTS
|
3
3
|
from xiaogpt.tts.mi import MiTTS as MiTTS
|
4
|
+
from xiaogpt.tts.volc import VolcTTS as VolcTTS
|
4
5
|
from xiaogpt.tts.azure import AzureTTS
|
5
6
|
|
6
|
-
__all__ = ["TTS", "EdgeTTS", "MiTTS", "AzureTTS"]
|
7
|
+
__all__ = ["TTS", "EdgeTTS", "MiTTS", "AzureTTS", "VolcTTS"]
|
@@ -0,0 +1,130 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import logging
|
4
|
+
import tempfile
|
5
|
+
from pathlib import Path
|
6
|
+
from typing import Optional
|
7
|
+
import json
|
8
|
+
import os
|
9
|
+
import time
|
10
|
+
import base64
|
11
|
+
import threading
|
12
|
+
import httpx
|
13
|
+
|
14
|
+
from volcengine.ApiInfo import ApiInfo
|
15
|
+
from volcengine.Credentials import Credentials
|
16
|
+
from volcengine.ServiceInfo import ServiceInfo
|
17
|
+
from volcengine.base.Service import Service
|
18
|
+
|
19
|
+
|
20
|
+
from xiaogpt.tts.base import AudioFileTTS
|
21
|
+
from xiaogpt.utils import calculate_tts_elapse
|
22
|
+
|
23
|
+
logger = logging.getLogger(__name__)
|
24
|
+
|
25
|
+
|
26
|
+
class VolcTTS(AudioFileTTS):
|
27
|
+
def __init__(self, mina_service, device_id, config):
|
28
|
+
super().__init__(mina_service, device_id, config)
|
29
|
+
self.token = get_token(config)
|
30
|
+
self.client = httpx.Client()
|
31
|
+
logger.info("Initializing VolcTTS {self.token}")
|
32
|
+
|
33
|
+
async def make_audio_file(self, query: str, text: str) -> tuple[Path, float]:
|
34
|
+
tts_payload = json.dumps(
|
35
|
+
{
|
36
|
+
"text": text,
|
37
|
+
"speaker": self.config.volc_tts_speaker,
|
38
|
+
"audio_config": {
|
39
|
+
"format": "mp3",
|
40
|
+
"sample_rate": 24000,
|
41
|
+
"speech_rate": 0,
|
42
|
+
},
|
43
|
+
}
|
44
|
+
)
|
45
|
+
|
46
|
+
req = {
|
47
|
+
"appkey": self.config.volc_tts_app,
|
48
|
+
"token": self.token,
|
49
|
+
"namespace": "TTS",
|
50
|
+
"payload": tts_payload,
|
51
|
+
}
|
52
|
+
|
53
|
+
resp = self.client.post("https://sami.bytedance.com/api/v1/invoke", json=req)
|
54
|
+
try:
|
55
|
+
sami_resp = resp.json()
|
56
|
+
logger.info(f"volc sami_resp {resp.status_code}")
|
57
|
+
if resp.status_code != 200:
|
58
|
+
print(sami_resp)
|
59
|
+
except:
|
60
|
+
logger.error(f"Failed to get tts from volcengine with voice=zh {text}")
|
61
|
+
|
62
|
+
if sami_resp["status_code"] == 20000000 and len(sami_resp["data"]) > 0:
|
63
|
+
audio_data = base64.b64decode(sami_resp["data"])
|
64
|
+
with tempfile.NamedTemporaryFile(
|
65
|
+
suffix=".mp3", mode="wb", delete=False, dir=self.dirname.name
|
66
|
+
) as f:
|
67
|
+
f.write(audio_data)
|
68
|
+
|
69
|
+
return Path(f.name), calculate_tts_elapse(text)
|
70
|
+
|
71
|
+
|
72
|
+
## fetch token and save it to file
|
73
|
+
## it's aimed to reduce the request to volcengine
|
74
|
+
## it'll throw error if token is requested too frequently (more than 1 times per minute)
|
75
|
+
def get_token(config):
|
76
|
+
token_file = Path.home() / ".volc.token"
|
77
|
+
if not Path.exists(token_file):
|
78
|
+
token = request_token_data(config)
|
79
|
+
else:
|
80
|
+
with open(token_file, "r") as f:
|
81
|
+
token = json.load(f)
|
82
|
+
if token["expires_at"] < time.time():
|
83
|
+
token = request_token_data(config)
|
84
|
+
|
85
|
+
if not Path.exists(token_file):
|
86
|
+
with open(token_file, "w") as f:
|
87
|
+
json.dump(token, f)
|
88
|
+
return token["token"]
|
89
|
+
|
90
|
+
|
91
|
+
def request_token_data(config):
|
92
|
+
sami_service = SAMIService()
|
93
|
+
sami_service.set_ak(config.volc_accesskey)
|
94
|
+
sami_service.set_sk(config.volc_secretkey)
|
95
|
+
|
96
|
+
req = {
|
97
|
+
"appkey": config.volc_tts_app,
|
98
|
+
"token_version": "volc-auth-v1",
|
99
|
+
"expiration": 24 * 3600,
|
100
|
+
}
|
101
|
+
token = sami_service.common_json_handler("GetToken", req)
|
102
|
+
logger.info(f"Got token from volcengine {token}")
|
103
|
+
return token
|
104
|
+
|
105
|
+
|
106
|
+
class SAMIService(Service):
|
107
|
+
def __init__(self):
|
108
|
+
self.service_info = ServiceInfo(
|
109
|
+
"open.volcengineapi.com",
|
110
|
+
{},
|
111
|
+
Credentials("", "", "sami", "cn-north-1"),
|
112
|
+
10,
|
113
|
+
10,
|
114
|
+
)
|
115
|
+
self.api_info = {
|
116
|
+
"GetToken": ApiInfo(
|
117
|
+
"POST", "/", {"Action": "GetToken", "Version": "2021-07-27"}, {}, {}
|
118
|
+
),
|
119
|
+
}
|
120
|
+
super(SAMIService, self).__init__(self.service_info, self.api_info)
|
121
|
+
|
122
|
+
def common_json_handler(self, api, body):
|
123
|
+
params = dict()
|
124
|
+
try:
|
125
|
+
body = json.dumps(body)
|
126
|
+
res = self.json(api, params, body)
|
127
|
+
res_json = json.loads(res)
|
128
|
+
return res_json
|
129
|
+
except Exception as e:
|
130
|
+
raise Exception(str(e))
|
@@ -23,7 +23,7 @@ from xiaogpt.config import (
|
|
23
23
|
WAKEUP_KEYWORD,
|
24
24
|
Config,
|
25
25
|
)
|
26
|
-
from xiaogpt.tts import TTS, EdgeTTS, MiTTS, AzureTTS
|
26
|
+
from xiaogpt.tts import TTS, EdgeTTS, MiTTS, AzureTTS, VolcTTS
|
27
27
|
from xiaogpt.tts.openai import OpenAITTS
|
28
28
|
from xiaogpt.utils import (
|
29
29
|
parse_cookie_string,
|
@@ -62,7 +62,9 @@ class MiGPT:
|
|
62
62
|
)
|
63
63
|
new_record = await self.get_latest_ask_from_xiaoai(session)
|
64
64
|
start = time.perf_counter()
|
65
|
-
self.log.debug(
|
65
|
+
self.log.debug(
|
66
|
+
"Polling_event, timestamp: %s %s", self.last_timestamp, new_record
|
67
|
+
)
|
66
68
|
await self.polling_event.wait()
|
67
69
|
if (
|
68
70
|
self.config.mute_xiaoai
|
@@ -262,6 +264,8 @@ class MiGPT:
|
|
262
264
|
return AzureTTS(self.mina_service, self.device_id, self.config)
|
263
265
|
elif self.config.tts == "openai":
|
264
266
|
return OpenAITTS(self.mina_service, self.device_id, self.config)
|
267
|
+
elif self.config.tts == "volc":
|
268
|
+
return VolcTTS(self.mina_service, self.device_id, self.config)
|
265
269
|
else:
|
266
270
|
return MiTTS(self.mina_service, self.device_id, self.config)
|
267
271
|
|
@@ -355,7 +359,6 @@ class MiGPT:
|
|
355
359
|
new_record = await self.last_record.get()
|
356
360
|
self.polling_event.clear() # stop polling when processing the question
|
357
361
|
query = new_record.get("query", "").strip()
|
358
|
-
|
359
362
|
if query == self.config.start_conversation:
|
360
363
|
if not self.in_conversation:
|
361
364
|
print("开始对话")
|
xiaogpt-2.41/pyproject.toml
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
[project]
|
2
|
-
name = "xiaogpt"
|
3
|
-
description = "Play ChatGPT or other LLM with xiaomi AI speaker"
|
4
|
-
readme = "README.md"
|
5
|
-
authors = [
|
6
|
-
{ name = "yihong0618", email = "zouzou0208@gmail.com" },
|
7
|
-
]
|
8
|
-
classifiers = [
|
9
|
-
"License :: OSI Approved :: MIT License",
|
10
|
-
"Operating System :: OS Independent",
|
11
|
-
"Programming Language :: Python :: 3",
|
12
|
-
]
|
13
|
-
requires-python = ">=3.9"
|
14
|
-
dependencies = [
|
15
|
-
"miservice_fork",
|
16
|
-
"openai>=1",
|
17
|
-
"aiohttp",
|
18
|
-
"rich",
|
19
|
-
"zhipuai==2.0.1",
|
20
|
-
"httpx==0.24.1",
|
21
|
-
"edge-tts>=6.1.3",
|
22
|
-
"EdgeGPT==0.1.26",
|
23
|
-
"langchain>=0.0.343",
|
24
|
-
"beautifulsoup4>=4.12.0",
|
25
|
-
"google-search-results>=2.4.2",
|
26
|
-
"google-generativeai",
|
27
|
-
"numexpr>=2.8.6",
|
28
|
-
"dashscope==1.10.0",
|
29
|
-
"httpcore==0.15.0",
|
30
|
-
"idna==3.7",
|
31
|
-
"azure-cognitiveservices-speech>=1.37.0",
|
32
|
-
]
|
33
|
-
dynamic = []
|
34
|
-
version = "2.41"
|
35
|
-
|
36
|
-
[project.license]
|
37
|
-
text = "MIT"
|
38
|
-
|
39
|
-
[project.urls]
|
40
|
-
Homepage = "https://github.com/yihong0618/xiaogpt"
|
41
|
-
|
42
|
-
[project.scripts]
|
43
|
-
xiaogpt = "xiaogpt.cli:main"
|
44
|
-
|
45
|
-
[tool.pdm]
|
46
|
-
plugins = [
|
47
|
-
"pdm-autoexport",
|
48
|
-
]
|
49
|
-
autoexport = [
|
50
|
-
{ filename = "requirements.txt", without-hashes = true },
|
51
|
-
]
|
52
|
-
|
53
|
-
[tool.pdm.version]
|
54
|
-
source = "scm"
|
55
|
-
|
56
|
-
[tool.pdm.build]
|
57
|
-
includes = [
|
58
|
-
"xiaogpt/",
|
59
|
-
]
|
60
|
-
|
61
|
-
[build-system]
|
62
|
-
requires = [
|
63
|
-
"pdm-backend>=2.0.0",
|
64
|
-
]
|
65
|
-
build-backend = "pdm.backend"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|