xiaogpt 2.70__tar.gz → 2.71__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.70 → xiaogpt-2.71}/PKG-INFO +60 -75
- {xiaogpt-2.70 → xiaogpt-2.71}/README.md +51 -60
- {xiaogpt-2.70 → xiaogpt-2.71}/pyproject.toml +9 -15
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/bot/__init__.py +2 -5
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/bot/chatgptapi_bot.py +1 -1
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/cli.py +0 -8
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/config.py +6 -9
- xiaogpt-2.70/xiaogpt/bot/newbing_bot.py +0 -81
- {xiaogpt-2.70 → xiaogpt-2.71}/LICENSE +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/__init__.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/__main__.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/bot/base_bot.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/bot/doubao_bot.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/bot/gemini_bot.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/bot/glm_bot.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/bot/langchain_bot.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/bot/llama_bot.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/bot/moonshot_bot.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/bot/qwen_bot.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/bot/yi_bot.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/langchain/callbacks.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/langchain/chain.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/langchain/examples/email/mail_box.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/langchain/examples/email/mail_summary_tools.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/tts/__init__.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/tts/base.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/tts/mi.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/tts/tetos.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/utils.py +0 -0
- {xiaogpt-2.70 → xiaogpt-2.71}/xiaogpt/xiaogpt.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: xiaogpt
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.71
|
4
4
|
Summary: Play ChatGPT or other LLM with xiaomi AI speaker
|
5
5
|
Author-Email: yihong0618 <zouzou0208@gmail.com>
|
6
6
|
License: MIT
|
@@ -15,7 +15,6 @@ Requires-Dist: aiohttp
|
|
15
15
|
Requires-Dist: rich
|
16
16
|
Requires-Dist: zhipuai>=2.0.1
|
17
17
|
Requires-Dist: httpx[socks]
|
18
|
-
Requires-Dist: EdgeGPT==0.1.26
|
19
18
|
Requires-Dist: langchain>=0.0.343
|
20
19
|
Requires-Dist: beautifulsoup4>=4.12.0
|
21
20
|
Requires-Dist: google-search-results>=2.4.2
|
@@ -24,6 +23,7 @@ Requires-Dist: numexpr>=2.8.6
|
|
24
23
|
Requires-Dist: dashscope>=1.10.0
|
25
24
|
Requires-Dist: tetos>=0.2.1
|
26
25
|
Requires-Dist: groq>=0.5.0
|
26
|
+
Requires-Dist: pyyaml>=6.0.1
|
27
27
|
Requires-Dist: aiohttp==3.9.5; extra == "locked"
|
28
28
|
Requires-Dist: aiosignal==1.3.1; extra == "locked"
|
29
29
|
Requires-Dist: annotated-types==0.6.0; extra == "locked"
|
@@ -32,27 +32,25 @@ Requires-Dist: async-timeout==4.0.3; python_version < "3.11" and extra == "locke
|
|
32
32
|
Requires-Dist: attrs==23.2.0; extra == "locked"
|
33
33
|
Requires-Dist: azure-cognitiveservices-speech==1.37.0; extra == "locked"
|
34
34
|
Requires-Dist: beautifulsoup4==4.12.3; extra == "locked"
|
35
|
-
Requires-Dist: bingimagecreator==0.5.0; extra == "locked"
|
36
35
|
Requires-Dist: cachetools==5.3.2; extra == "locked"
|
37
36
|
Requires-Dist: certifi==2024.2.2; extra == "locked"
|
38
37
|
Requires-Dist: charset-normalizer==3.3.2; extra == "locked"
|
39
38
|
Requires-Dist: click==8.1.7; extra == "locked"
|
40
39
|
Requires-Dist: colorama==0.4.6; platform_system == "Windows" and extra == "locked"
|
41
|
-
Requires-Dist: dashscope==1.
|
40
|
+
Requires-Dist: dashscope==1.19.0; extra == "locked"
|
42
41
|
Requires-Dist: dataclasses-json==0.6.3; extra == "locked"
|
43
42
|
Requires-Dist: distro==1.9.0; extra == "locked"
|
44
43
|
Requires-Dist: edge-tts==6.1.10; extra == "locked"
|
45
|
-
Requires-Dist: edgegpt==0.1.26; extra == "locked"
|
46
44
|
Requires-Dist: exceptiongroup==1.2.0; python_version < "3.11" and extra == "locked"
|
47
45
|
Requires-Dist: frozenlist==1.4.1; extra == "locked"
|
48
|
-
Requires-Dist: google-ai-generativelanguage==0.6.
|
46
|
+
Requires-Dist: google-ai-generativelanguage==0.6.3; extra == "locked"
|
49
47
|
Requires-Dist: google-api-core==2.15.0; extra == "locked"
|
50
48
|
Requires-Dist: google-api-core[grpc]==2.15.0; extra == "locked"
|
51
49
|
Requires-Dist: google-api-python-client==2.125.0; extra == "locked"
|
52
50
|
Requires-Dist: google-auth==2.26.1; extra == "locked"
|
53
51
|
Requires-Dist: google-auth-httplib2==0.2.0; extra == "locked"
|
54
52
|
Requires-Dist: google-cloud-texttospeech==2.16.3; extra == "locked"
|
55
|
-
Requires-Dist: google-generativeai==0.5.
|
53
|
+
Requires-Dist: google-generativeai==0.5.3; extra == "locked"
|
56
54
|
Requires-Dist: google-search-results==2.4.2; extra == "locked"
|
57
55
|
Requires-Dist: googleapis-common-protos==1.62.0; extra == "locked"
|
58
56
|
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"
|
@@ -67,9 +65,9 @@ Requires-Dist: httpx[socks]==0.27.0; extra == "locked"
|
|
67
65
|
Requires-Dist: idna==3.7; extra == "locked"
|
68
66
|
Requires-Dist: jsonpatch==1.33; extra == "locked"
|
69
67
|
Requires-Dist: jsonpointer==2.4; extra == "locked"
|
70
|
-
Requires-Dist: langchain==0.1.
|
71
|
-
Requires-Dist: langchain-community==0.0.
|
72
|
-
Requires-Dist: langchain-core==0.1.
|
68
|
+
Requires-Dist: langchain==0.1.20; extra == "locked"
|
69
|
+
Requires-Dist: langchain-community==0.0.38; extra == "locked"
|
70
|
+
Requires-Dist: langchain-core==0.1.52; extra == "locked"
|
73
71
|
Requires-Dist: langchain-text-splitters==0.0.1; extra == "locked"
|
74
72
|
Requires-Dist: langsmith==0.1.45; extra == "locked"
|
75
73
|
Requires-Dist: markdown-it-py==3.0.0; extra == "locked"
|
@@ -81,10 +79,9 @@ Requires-Dist: mutagen==1.47.0; extra == "locked"
|
|
81
79
|
Requires-Dist: mypy-extensions==1.0.0; extra == "locked"
|
82
80
|
Requires-Dist: numexpr==2.10.0; extra == "locked"
|
83
81
|
Requires-Dist: numpy==1.26.3; extra == "locked"
|
84
|
-
Requires-Dist: openai==1.
|
82
|
+
Requires-Dist: openai==1.29.0; extra == "locked"
|
85
83
|
Requires-Dist: orjson==3.10.0; extra == "locked"
|
86
84
|
Requires-Dist: packaging==23.2; extra == "locked"
|
87
|
-
Requires-Dist: prompt-toolkit==3.0.43; extra == "locked"
|
88
85
|
Requires-Dist: proto-plus==1.23.0; extra == "locked"
|
89
86
|
Requires-Dist: protobuf==4.25.1; extra == "locked"
|
90
87
|
Requires-Dist: pyasn1==0.5.1; extra == "locked"
|
@@ -95,7 +92,6 @@ Requires-Dist: pygments==2.17.2; extra == "locked"
|
|
95
92
|
Requires-Dist: pyjwt==2.8.0; extra == "locked"
|
96
93
|
Requires-Dist: pyparsing==3.1.2; python_version > "3.0" and extra == "locked"
|
97
94
|
Requires-Dist: pyyaml==6.0.1; extra == "locked"
|
98
|
-
Requires-Dist: regex==2023.12.25; extra == "locked"
|
99
95
|
Requires-Dist: requests==2.31.0; extra == "locked"
|
100
96
|
Requires-Dist: rich==13.7.1; extra == "locked"
|
101
97
|
Requires-Dist: rsa==4.9; extra == "locked"
|
@@ -110,8 +106,6 @@ Requires-Dist: typing-extensions==4.9.0; extra == "locked"
|
|
110
106
|
Requires-Dist: typing-inspect==0.9.0; extra == "locked"
|
111
107
|
Requires-Dist: uritemplate==4.1.1; extra == "locked"
|
112
108
|
Requires-Dist: urllib3==2.1.0; extra == "locked"
|
113
|
-
Requires-Dist: wcwidth==0.2.13; extra == "locked"
|
114
|
-
Requires-Dist: websockets==12.0; extra == "locked"
|
115
109
|
Requires-Dist: yarl==1.9.4; extra == "locked"
|
116
110
|
Requires-Dist: zhipuai==2.0.1.20240423.1; extra == "locked"
|
117
111
|
Provides-Extra: locked
|
@@ -143,8 +137,8 @@ Play ChatGPT and other LLM with Xiaomi AI Speaker
|
|
143
137
|
|
144
138
|
## 获取小米音响DID
|
145
139
|
|
146
|
-
| 系统和Shell
|
147
|
-
|
140
|
+
| 系统和Shell | Linux *sh | Windows CMD用户 | Windows PowerShell用户 |
|
141
|
+
| ------------- | ---------------------------------------------- | -------------------------------------- | ---------------------------------------------- |
|
148
142
|
| 1、安装包 | `pip install miservice_fork` | `pip install miservice_fork` | `pip install miservice_fork` |
|
149
143
|
| 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"` |
|
150
144
|
| 3、取得MI_DID | `micli list` | `micli list` | `micli list` |
|
@@ -254,36 +248,32 @@ export SERPAPI_API_KEY=${your_serpapi_key}
|
|
254
248
|
python3 xiaogpt.py --hardware Lx06 --use_langchain --mute_xiaoai --stream --openai_key ${your_api_key} --serpapi_api_key ${your_serpapi_key}
|
255
249
|
```
|
256
250
|
|
257
|
-
## config.
|
251
|
+
## config.yaml
|
258
252
|
|
259
|
-
如果想通过单一配置文件启动也是可以的, 可以通过 `--config` 参数指定配置文件, config 文件必须是合法的 JSON 格式
|
253
|
+
如果想通过单一配置文件启动也是可以的, 可以通过 `--config` 参数指定配置文件, config 文件必须是合法的 Yaml 或 JSON 格式
|
260
254
|
参数优先级
|
261
255
|
|
262
256
|
- cli args > default > config
|
263
257
|
|
264
258
|
```shell
|
265
|
-
python3 xiaogpt.py --config xiao_config.
|
259
|
+
python3 xiaogpt.py --config xiao_config.yaml
|
266
260
|
# or
|
267
|
-
xiaogpt --config xiao_config.
|
261
|
+
xiaogpt --config xiao_config.yaml
|
268
262
|
```
|
269
263
|
|
270
264
|
或者
|
271
265
|
|
272
266
|
```shell
|
273
|
-
cp xiao_config.
|
267
|
+
cp xiao_config.yaml.example xiao_config.yaml
|
274
268
|
python3 xiaogpt.py
|
275
269
|
```
|
276
270
|
|
277
|
-
若要指定 OpenAI 的模型参数,如 model, temporature, top_p, 请在config.
|
271
|
+
若要指定 OpenAI 的模型参数,如 model, temporature, top_p, 请在 config.yaml 中指定:
|
278
272
|
|
279
|
-
```
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
"temperature": 0.9,
|
284
|
-
"top_p": 0.9,
|
285
|
-
}
|
286
|
-
}
|
273
|
+
```yaml
|
274
|
+
gpt_options:
|
275
|
+
temperature: 0.9
|
276
|
+
top_p: 0.9
|
287
277
|
```
|
288
278
|
|
289
279
|
具体参数作用请参考 [Open AI API 文档](https://platform.openai.com/docs/api-reference/chat/create)。
|
@@ -291,43 +281,40 @@ ChatGLM [文档](http://open.bigmodel.cn/doc/api#chatglm_130b)
|
|
291
281
|
|
292
282
|
## 配置项说明
|
293
283
|
|
294
|
-
| 参数
|
295
|
-
|
296
|
-
| hardware
|
297
|
-
| account
|
298
|
-
| password
|
299
|
-
| openai_key
|
300
|
-
| moonshot_api_key
|
301
|
-
| yi_api_key
|
302
|
-
| llama_api_key
|
303
|
-
| serpapi_api_key
|
304
|
-
| glm_key
|
305
|
-
| gemini_key
|
306
|
-
| gemini_api_domain | gemini 的自定义域名 [参考](https://github.com/antergone/palm-netlify-proxy)
|
307
|
-
| qwen_key | qwen 的 apikey [参考](https://help.aliyun.com/zh/dashscope/developer-reference/api-details)
|
308
|
-
| cookie | 小爱账户cookie (如果用上面密码登录可以不填)
|
309
|
-
| mi_did | 设备did
|
310
|
-
| use_command | 使用 MI command 与小爱交互
|
311
|
-
| mute_xiaoai | 快速停掉小爱自己的回答
|
312
|
-
| verbose | 是否打印详细日志
|
313
|
-
| bot | 使用的 bot 类型,目前支持 chatgptapi,newbing, qwen, gemini
|
314
|
-
| tts | 使用的 TTS 类型
|
315
|
-
| tts_options | TTS 参数字典,参考 [tetos](https://github.com/frostming/tetos) 获取可用参数
|
316
|
-
| prompt | 自定义prompt
|
317
|
-
| keyword | 自定义请求词列表
|
318
|
-
| change_prompt_keyword | 更改提示词触发列表
|
319
|
-
| start_conversation | 开始持续对话关键词
|
320
|
-
| end_conversation | 结束持续对话关键词
|
321
|
-
| stream | 使用流式响应,获得更快的响应
|
322
|
-
| proxy | 支持 HTTP 代理,传入 http proxy URL
|
323
|
-
| gpt_options | OpenAI API 的参数字典
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
| volc_access_key | 火山引擎的 access key 请在[这里](https://console.volcengine.com/iam/keymanage/)获取 | | |
|
329
|
-
| volc_secret_key | 火山引擎的 secret key 请在[这里](https://console.volcengine.com/iam/keymanage/)获取 | | |
|
330
|
-
[这里]: <https://github.com/acheong08/EdgeGPT#getting-authentication-required>
|
284
|
+
| 参数 | 说明 | 默认值 | 可选值 |
|
285
|
+
| --------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
|
286
|
+
| hardware | 设备型号 | | |
|
287
|
+
| account | 小爱账户 | | |
|
288
|
+
| password | 小爱账户密码 | | |
|
289
|
+
| openai_key | openai的apikey | | |
|
290
|
+
| moonshot_api_key | moonshot kimi 的 [apikey](https://platform.moonshot.cn/docs/api/chat#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B) | | |
|
291
|
+
| yi_api_key | 01 wanwu 的 [apikey](https://platform.lingyiwanwu.com/apikeys) | | |
|
292
|
+
| llama_api_key | groq 的 llama3 [apikey](https://console.groq.com/docs/quickstart) | | |
|
293
|
+
| serpapi_api_key | serpapi的key 参考 [SerpAPI](https://serpapi.com/) | | |
|
294
|
+
| glm_key | chatglm 的 apikey | | |
|
295
|
+
| gemini_key | gemini 的 apikey [参考](https://makersuite.google.com/app/apikey) | | |
|
296
|
+
| gemini_api_domain | gemini 的自定义域名 [参考](https://github.com/antergone/palm-netlify-proxy) | |
|
297
|
+
| qwen_key | qwen 的 apikey [参考](https://help.aliyun.com/zh/dashscope/developer-reference/api-details) | | |
|
298
|
+
| cookie | 小爱账户cookie (如果用上面密码登录可以不填) | | |
|
299
|
+
| mi_did | 设备did | | |
|
300
|
+
| use_command | 使用 MI command 与小爱交互 | `false` | |
|
301
|
+
| mute_xiaoai | 快速停掉小爱自己的回答 | `true` | |
|
302
|
+
| verbose | 是否打印详细日志 | `false` | |
|
303
|
+
| bot | 使用的 bot 类型,目前支持 chatgptapi,newbing, qwen, gemini | `chatgptapi` | |
|
304
|
+
| tts | 使用的 TTS 类型 | `mi` | `edge`、 `openai`、`azure`、`volc`、`baidu`、`google`、`minimax` |
|
305
|
+
| tts_options | TTS 参数字典,参考 [tetos](https://github.com/frostming/tetos) 获取可用参数 | | |
|
306
|
+
| prompt | 自定义prompt | `请用100字以内回答` | |
|
307
|
+
| keyword | 自定义请求词列表 | `["请"]` | |
|
308
|
+
| change_prompt_keyword | 更改提示词触发列表 | `["更改提示词"]` | |
|
309
|
+
| start_conversation | 开始持续对话关键词 | `开始持续对话` | |
|
310
|
+
| end_conversation | 结束持续对话关键词 | `结束持续对话` | |
|
311
|
+
| stream | 使用流式响应,获得更快的响应 | `true` | |
|
312
|
+
| proxy | 支持 HTTP 代理,传入 http proxy URL | "" | |
|
313
|
+
| gpt_options | OpenAI API 的参数字典 | `{}` | |
|
314
|
+
| deployment_id | Azure OpenAI 服务的 deployment ID | 参考这个[如何找到deployment_id](https://github.com/yihong0618/xiaogpt/issues/347#issuecomment-1784410784) | |
|
315
|
+
| api_base | 如果需要替换默认的api,或者使用Azure OpenAI 服务 | 例如:`https://abc-def.openai.azure.com/` |
|
316
|
+
| volc_access_key | 火山引擎的 access key 请在[这里](https://console.volcengine.com/iam/keymanage/)获取 | | |
|
317
|
+
| volc_secret_key | 火山引擎的 secret key 请在[这里](https://console.volcengine.com/iam/keymanage/)获取 | |
|
331
318
|
|
332
319
|
## 注意
|
333
320
|
|
@@ -373,13 +360,13 @@ docker run -e OPENAI_API_KEY=<your-openapi-key> yihong0618/xiaogpt --account=<yo
|
|
373
360
|
xiaogpt的配置文件可通过指定volume /config,以及指定参数--config来处理,如
|
374
361
|
|
375
362
|
```shell
|
376
|
-
docker run -v <your-config-dir>:/config yihong0618/xiaogpt --config=/config/config.
|
363
|
+
docker run -v <your-config-dir>:/config yihong0618/xiaogpt --config=/config/config.yaml
|
377
364
|
```
|
378
365
|
|
379
366
|
### 网络使用 host 模型
|
380
367
|
|
381
368
|
```shell
|
382
|
-
docker run -v <your-config-dir>:/config --network=host yihong0618/xiaogpt --config=/config/config.
|
369
|
+
docker run -v <your-config-dir>:/config --network=host yihong0618/xiaogpt --config=/config/config.yaml
|
383
370
|
```
|
384
371
|
|
385
372
|
### 本地编译Docker Image
|
@@ -412,10 +399,8 @@ docker build --build-arg PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple
|
|
412
399
|
|
413
400
|
你可以通过参数 `tts`, 来启用它
|
414
401
|
|
415
|
-
```
|
416
|
-
|
417
|
-
"tts": "edge",
|
418
|
-
}
|
402
|
+
```yaml
|
403
|
+
tts: edge
|
419
404
|
```
|
420
405
|
|
421
406
|
For edge 查看更多语言支持, 从中选择一个
|
@@ -429,7 +414,7 @@ edge-tts --list-voices
|
|
429
414
|
由于 Edge TTS 启动了一个本地的 HTTP 服务,所以需要将容器的端口映射到宿主机上,并且指定本地机器的 hostname:
|
430
415
|
|
431
416
|
```shell
|
432
|
-
docker run -v <your-config-dir>:/config -p 9527:9527 -e XIAOGPT_HOSTNAME=<your ip> yihong0618/xiaogpt --config=/config/config.
|
417
|
+
docker run -v <your-config-dir>:/config -p 9527:9527 -e XIAOGPT_HOSTNAME=<your ip> yihong0618/xiaogpt --config=/config/config.yaml
|
433
418
|
```
|
434
419
|
|
435
420
|
注意端口必须映射为与容器内一致,XIAOGPT_HOSTNAME 需要设置为宿主机的 IP 地址,否则小爱无法正常播放语音。
|
@@ -24,8 +24,8 @@ Play ChatGPT and other LLM with Xiaomi AI Speaker
|
|
24
24
|
|
25
25
|
## 获取小米音响DID
|
26
26
|
|
27
|
-
| 系统和Shell
|
28
|
-
|
27
|
+
| 系统和Shell | Linux *sh | Windows CMD用户 | Windows PowerShell用户 |
|
28
|
+
| ------------- | ---------------------------------------------- | -------------------------------------- | ---------------------------------------------- |
|
29
29
|
| 1、安装包 | `pip install miservice_fork` | `pip install miservice_fork` | `pip install miservice_fork` |
|
30
30
|
| 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"` |
|
31
31
|
| 3、取得MI_DID | `micli list` | `micli list` | `micli list` |
|
@@ -135,36 +135,32 @@ export SERPAPI_API_KEY=${your_serpapi_key}
|
|
135
135
|
python3 xiaogpt.py --hardware Lx06 --use_langchain --mute_xiaoai --stream --openai_key ${your_api_key} --serpapi_api_key ${your_serpapi_key}
|
136
136
|
```
|
137
137
|
|
138
|
-
## config.
|
138
|
+
## config.yaml
|
139
139
|
|
140
|
-
如果想通过单一配置文件启动也是可以的, 可以通过 `--config` 参数指定配置文件, config 文件必须是合法的 JSON 格式
|
140
|
+
如果想通过单一配置文件启动也是可以的, 可以通过 `--config` 参数指定配置文件, config 文件必须是合法的 Yaml 或 JSON 格式
|
141
141
|
参数优先级
|
142
142
|
|
143
143
|
- cli args > default > config
|
144
144
|
|
145
145
|
```shell
|
146
|
-
python3 xiaogpt.py --config xiao_config.
|
146
|
+
python3 xiaogpt.py --config xiao_config.yaml
|
147
147
|
# or
|
148
|
-
xiaogpt --config xiao_config.
|
148
|
+
xiaogpt --config xiao_config.yaml
|
149
149
|
```
|
150
150
|
|
151
151
|
或者
|
152
152
|
|
153
153
|
```shell
|
154
|
-
cp xiao_config.
|
154
|
+
cp xiao_config.yaml.example xiao_config.yaml
|
155
155
|
python3 xiaogpt.py
|
156
156
|
```
|
157
157
|
|
158
|
-
若要指定 OpenAI 的模型参数,如 model, temporature, top_p, 请在config.
|
158
|
+
若要指定 OpenAI 的模型参数,如 model, temporature, top_p, 请在 config.yaml 中指定:
|
159
159
|
|
160
|
-
```
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
"temperature": 0.9,
|
165
|
-
"top_p": 0.9,
|
166
|
-
}
|
167
|
-
}
|
160
|
+
```yaml
|
161
|
+
gpt_options:
|
162
|
+
temperature: 0.9
|
163
|
+
top_p: 0.9
|
168
164
|
```
|
169
165
|
|
170
166
|
具体参数作用请参考 [Open AI API 文档](https://platform.openai.com/docs/api-reference/chat/create)。
|
@@ -172,43 +168,40 @@ ChatGLM [文档](http://open.bigmodel.cn/doc/api#chatglm_130b)
|
|
172
168
|
|
173
169
|
## 配置项说明
|
174
170
|
|
175
|
-
| 参数
|
176
|
-
|
177
|
-
| hardware
|
178
|
-
| account
|
179
|
-
| password
|
180
|
-
| openai_key
|
181
|
-
| moonshot_api_key
|
182
|
-
| yi_api_key
|
183
|
-
| llama_api_key
|
184
|
-
| serpapi_api_key
|
185
|
-
| glm_key
|
186
|
-
| gemini_key
|
187
|
-
| gemini_api_domain | gemini 的自定义域名 [参考](https://github.com/antergone/palm-netlify-proxy)
|
188
|
-
| qwen_key | qwen 的 apikey [参考](https://help.aliyun.com/zh/dashscope/developer-reference/api-details)
|
189
|
-
| cookie | 小爱账户cookie (如果用上面密码登录可以不填)
|
190
|
-
| mi_did | 设备did
|
191
|
-
| use_command | 使用 MI command 与小爱交互
|
192
|
-
| mute_xiaoai | 快速停掉小爱自己的回答
|
193
|
-
| verbose | 是否打印详细日志
|
194
|
-
| bot | 使用的 bot 类型,目前支持 chatgptapi,newbing, qwen, gemini
|
195
|
-
| tts | 使用的 TTS 类型
|
196
|
-
| tts_options | TTS 参数字典,参考 [tetos](https://github.com/frostming/tetos) 获取可用参数
|
197
|
-
| prompt | 自定义prompt
|
198
|
-
| keyword | 自定义请求词列表
|
199
|
-
| change_prompt_keyword | 更改提示词触发列表
|
200
|
-
| start_conversation | 开始持续对话关键词
|
201
|
-
| end_conversation | 结束持续对话关键词
|
202
|
-
| stream | 使用流式响应,获得更快的响应
|
203
|
-
| proxy | 支持 HTTP 代理,传入 http proxy URL
|
204
|
-
| gpt_options | OpenAI API 的参数字典
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
| volc_access_key | 火山引擎的 access key 请在[这里](https://console.volcengine.com/iam/keymanage/)获取 | | |
|
210
|
-
| volc_secret_key | 火山引擎的 secret key 请在[这里](https://console.volcengine.com/iam/keymanage/)获取 | | |
|
211
|
-
[这里]: <https://github.com/acheong08/EdgeGPT#getting-authentication-required>
|
171
|
+
| 参数 | 说明 | 默认值 | 可选值 |
|
172
|
+
| --------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
|
173
|
+
| hardware | 设备型号 | | |
|
174
|
+
| account | 小爱账户 | | |
|
175
|
+
| password | 小爱账户密码 | | |
|
176
|
+
| openai_key | openai的apikey | | |
|
177
|
+
| moonshot_api_key | moonshot kimi 的 [apikey](https://platform.moonshot.cn/docs/api/chat#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B) | | |
|
178
|
+
| yi_api_key | 01 wanwu 的 [apikey](https://platform.lingyiwanwu.com/apikeys) | | |
|
179
|
+
| llama_api_key | groq 的 llama3 [apikey](https://console.groq.com/docs/quickstart) | | |
|
180
|
+
| serpapi_api_key | serpapi的key 参考 [SerpAPI](https://serpapi.com/) | | |
|
181
|
+
| glm_key | chatglm 的 apikey | | |
|
182
|
+
| gemini_key | gemini 的 apikey [参考](https://makersuite.google.com/app/apikey) | | |
|
183
|
+
| gemini_api_domain | gemini 的自定义域名 [参考](https://github.com/antergone/palm-netlify-proxy) | |
|
184
|
+
| qwen_key | qwen 的 apikey [参考](https://help.aliyun.com/zh/dashscope/developer-reference/api-details) | | |
|
185
|
+
| cookie | 小爱账户cookie (如果用上面密码登录可以不填) | | |
|
186
|
+
| mi_did | 设备did | | |
|
187
|
+
| use_command | 使用 MI command 与小爱交互 | `false` | |
|
188
|
+
| mute_xiaoai | 快速停掉小爱自己的回答 | `true` | |
|
189
|
+
| verbose | 是否打印详细日志 | `false` | |
|
190
|
+
| bot | 使用的 bot 类型,目前支持 chatgptapi,newbing, qwen, gemini | `chatgptapi` | |
|
191
|
+
| tts | 使用的 TTS 类型 | `mi` | `edge`、 `openai`、`azure`、`volc`、`baidu`、`google`、`minimax` |
|
192
|
+
| tts_options | TTS 参数字典,参考 [tetos](https://github.com/frostming/tetos) 获取可用参数 | | |
|
193
|
+
| prompt | 自定义prompt | `请用100字以内回答` | |
|
194
|
+
| keyword | 自定义请求词列表 | `["请"]` | |
|
195
|
+
| change_prompt_keyword | 更改提示词触发列表 | `["更改提示词"]` | |
|
196
|
+
| start_conversation | 开始持续对话关键词 | `开始持续对话` | |
|
197
|
+
| end_conversation | 结束持续对话关键词 | `结束持续对话` | |
|
198
|
+
| stream | 使用流式响应,获得更快的响应 | `true` | |
|
199
|
+
| proxy | 支持 HTTP 代理,传入 http proxy URL | "" | |
|
200
|
+
| gpt_options | OpenAI API 的参数字典 | `{}` | |
|
201
|
+
| deployment_id | Azure OpenAI 服务的 deployment ID | 参考这个[如何找到deployment_id](https://github.com/yihong0618/xiaogpt/issues/347#issuecomment-1784410784) | |
|
202
|
+
| api_base | 如果需要替换默认的api,或者使用Azure OpenAI 服务 | 例如:`https://abc-def.openai.azure.com/` |
|
203
|
+
| volc_access_key | 火山引擎的 access key 请在[这里](https://console.volcengine.com/iam/keymanage/)获取 | | |
|
204
|
+
| volc_secret_key | 火山引擎的 secret key 请在[这里](https://console.volcengine.com/iam/keymanage/)获取 | |
|
212
205
|
|
213
206
|
## 注意
|
214
207
|
|
@@ -254,13 +247,13 @@ docker run -e OPENAI_API_KEY=<your-openapi-key> yihong0618/xiaogpt --account=<yo
|
|
254
247
|
xiaogpt的配置文件可通过指定volume /config,以及指定参数--config来处理,如
|
255
248
|
|
256
249
|
```shell
|
257
|
-
docker run -v <your-config-dir>:/config yihong0618/xiaogpt --config=/config/config.
|
250
|
+
docker run -v <your-config-dir>:/config yihong0618/xiaogpt --config=/config/config.yaml
|
258
251
|
```
|
259
252
|
|
260
253
|
### 网络使用 host 模型
|
261
254
|
|
262
255
|
```shell
|
263
|
-
docker run -v <your-config-dir>:/config --network=host yihong0618/xiaogpt --config=/config/config.
|
256
|
+
docker run -v <your-config-dir>:/config --network=host yihong0618/xiaogpt --config=/config/config.yaml
|
264
257
|
```
|
265
258
|
|
266
259
|
### 本地编译Docker Image
|
@@ -293,10 +286,8 @@ docker build --build-arg PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple
|
|
293
286
|
|
294
287
|
你可以通过参数 `tts`, 来启用它
|
295
288
|
|
296
|
-
```
|
297
|
-
|
298
|
-
"tts": "edge",
|
299
|
-
}
|
289
|
+
```yaml
|
290
|
+
tts: edge
|
300
291
|
```
|
301
292
|
|
302
293
|
For edge 查看更多语言支持, 从中选择一个
|
@@ -310,7 +301,7 @@ edge-tts --list-voices
|
|
310
301
|
由于 Edge TTS 启动了一个本地的 HTTP 服务,所以需要将容器的端口映射到宿主机上,并且指定本地机器的 hostname:
|
311
302
|
|
312
303
|
```shell
|
313
|
-
docker run -v <your-config-dir>:/config -p 9527:9527 -e XIAOGPT_HOSTNAME=<your ip> yihong0618/xiaogpt --config=/config/config.
|
304
|
+
docker run -v <your-config-dir>:/config -p 9527:9527 -e XIAOGPT_HOSTNAME=<your ip> yihong0618/xiaogpt --config=/config/config.yaml
|
314
305
|
```
|
315
306
|
|
316
307
|
注意端口必须映射为与容器内一致,XIAOGPT_HOSTNAME 需要设置为宿主机的 IP 地址,否则小爱无法正常播放语音。
|
@@ -18,7 +18,6 @@ dependencies = [
|
|
18
18
|
"rich",
|
19
19
|
"zhipuai>=2.0.1",
|
20
20
|
"httpx[socks]",
|
21
|
-
"EdgeGPT==0.1.26",
|
22
21
|
"langchain>=0.0.343",
|
23
22
|
"beautifulsoup4>=4.12.0",
|
24
23
|
"google-search-results>=2.4.2",
|
@@ -27,9 +26,10 @@ dependencies = [
|
|
27
26
|
"dashscope>=1.10.0",
|
28
27
|
"tetos>=0.2.1",
|
29
28
|
"groq>=0.5.0",
|
29
|
+
"pyyaml>=6.0.1",
|
30
30
|
]
|
31
31
|
dynamic = []
|
32
|
-
version = "2.
|
32
|
+
version = "2.71"
|
33
33
|
|
34
34
|
[project.license]
|
35
35
|
text = "MIT"
|
@@ -50,27 +50,25 @@ locked = [
|
|
50
50
|
"attrs==23.2.0",
|
51
51
|
"azure-cognitiveservices-speech==1.37.0",
|
52
52
|
"beautifulsoup4==4.12.3",
|
53
|
-
"bingimagecreator==0.5.0",
|
54
53
|
"cachetools==5.3.2",
|
55
54
|
"certifi==2024.2.2",
|
56
55
|
"charset-normalizer==3.3.2",
|
57
56
|
"click==8.1.7",
|
58
57
|
"colorama==0.4.6 ; platform_system == \"Windows\"",
|
59
|
-
"dashscope==1.
|
58
|
+
"dashscope==1.19.0",
|
60
59
|
"dataclasses-json==0.6.3",
|
61
60
|
"distro==1.9.0",
|
62
61
|
"edge-tts==6.1.10",
|
63
|
-
"edgegpt==0.1.26",
|
64
62
|
"exceptiongroup==1.2.0 ; python_version < \"3.11\"",
|
65
63
|
"frozenlist==1.4.1",
|
66
|
-
"google-ai-generativelanguage==0.6.
|
64
|
+
"google-ai-generativelanguage==0.6.3",
|
67
65
|
"google-api-core==2.15.0",
|
68
66
|
"google-api-core[grpc]==2.15.0",
|
69
67
|
"google-api-python-client==2.125.0",
|
70
68
|
"google-auth==2.26.1",
|
71
69
|
"google-auth-httplib2==0.2.0",
|
72
70
|
"google-cloud-texttospeech==2.16.3",
|
73
|
-
"google-generativeai==0.5.
|
71
|
+
"google-generativeai==0.5.3",
|
74
72
|
"google-search-results==2.4.2",
|
75
73
|
"googleapis-common-protos==1.62.0",
|
76
74
|
"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\"",
|
@@ -85,9 +83,9 @@ locked = [
|
|
85
83
|
"idna==3.7",
|
86
84
|
"jsonpatch==1.33",
|
87
85
|
"jsonpointer==2.4",
|
88
|
-
"langchain==0.1.
|
89
|
-
"langchain-community==0.0.
|
90
|
-
"langchain-core==0.1.
|
86
|
+
"langchain==0.1.20",
|
87
|
+
"langchain-community==0.0.38",
|
88
|
+
"langchain-core==0.1.52",
|
91
89
|
"langchain-text-splitters==0.0.1",
|
92
90
|
"langsmith==0.1.45",
|
93
91
|
"markdown-it-py==3.0.0",
|
@@ -99,10 +97,9 @@ locked = [
|
|
99
97
|
"mypy-extensions==1.0.0",
|
100
98
|
"numexpr==2.10.0",
|
101
99
|
"numpy==1.26.3",
|
102
|
-
"openai==1.
|
100
|
+
"openai==1.29.0",
|
103
101
|
"orjson==3.10.0",
|
104
102
|
"packaging==23.2",
|
105
|
-
"prompt-toolkit==3.0.43",
|
106
103
|
"proto-plus==1.23.0",
|
107
104
|
"protobuf==4.25.1",
|
108
105
|
"pyasn1==0.5.1",
|
@@ -113,7 +110,6 @@ locked = [
|
|
113
110
|
"pyjwt==2.8.0",
|
114
111
|
"pyparsing==3.1.2 ; python_version > \"3.0\"",
|
115
112
|
"pyyaml==6.0.1",
|
116
|
-
"regex==2023.12.25",
|
117
113
|
"requests==2.31.0",
|
118
114
|
"rich==13.7.1",
|
119
115
|
"rsa==4.9",
|
@@ -128,8 +124,6 @@ locked = [
|
|
128
124
|
"typing-inspect==0.9.0",
|
129
125
|
"uritemplate==4.1.1",
|
130
126
|
"urllib3==2.1.0",
|
131
|
-
"wcwidth==0.2.13",
|
132
|
-
"websockets==12.0",
|
133
127
|
"yarl==1.9.4",
|
134
128
|
"zhipuai==2.0.1.20240423.1",
|
135
129
|
]
|
@@ -6,15 +6,13 @@ from xiaogpt.bot.doubao_bot import DoubaoBot
|
|
6
6
|
from xiaogpt.bot.gemini_bot import GeminiBot
|
7
7
|
from xiaogpt.bot.glm_bot import GLMBot
|
8
8
|
from xiaogpt.bot.langchain_bot import LangChainBot
|
9
|
-
from xiaogpt.bot.
|
10
|
-
from xiaogpt.bot.qwen_bot import QwenBot
|
9
|
+
from xiaogpt.bot.llama_bot import LlamaBot
|
11
10
|
from xiaogpt.bot.moonshot_bot import MoonshotBot
|
11
|
+
from xiaogpt.bot.qwen_bot import QwenBot
|
12
12
|
from xiaogpt.bot.yi_bot import YiBot
|
13
|
-
from xiaogpt.bot.llama_bot import LlamaBot
|
14
13
|
from xiaogpt.config import Config
|
15
14
|
|
16
15
|
BOTS: dict[str, type[BaseBot]] = {
|
17
|
-
"newbing": NewBingBot,
|
18
16
|
"chatgptapi": ChatGPTBot,
|
19
17
|
"glm": GLMBot,
|
20
18
|
"gemini": GeminiBot,
|
@@ -36,7 +34,6 @@ def get_bot(config: Config) -> BaseBot:
|
|
36
34
|
|
37
35
|
__all__ = [
|
38
36
|
"ChatGPTBot",
|
39
|
-
"NewBingBot",
|
40
37
|
"GLMBot",
|
41
38
|
"GeminiBot",
|
42
39
|
"MoonshotBot",
|
@@ -16,7 +16,7 @@ if TYPE_CHECKING:
|
|
16
16
|
@dataclasses.dataclass
|
17
17
|
class ChatGPTBot(ChatHistoryMixin, BaseBot):
|
18
18
|
name: ClassVar[str] = "ChatGPT"
|
19
|
-
default_options: ClassVar[dict[str, str]] = {"model": "gpt-
|
19
|
+
default_options: ClassVar[dict[str, str]] = {"model": "gpt-4o-2024-05-13"}
|
20
20
|
openai_key: str
|
21
21
|
api_base: str | None = None
|
22
22
|
proxy: str | None = None
|
@@ -145,13 +145,6 @@ def main():
|
|
145
145
|
const="langchain",
|
146
146
|
help="if use langchain",
|
147
147
|
)
|
148
|
-
bot_group.add_argument(
|
149
|
-
"--use_newbing",
|
150
|
-
dest="bot",
|
151
|
-
action="store_const",
|
152
|
-
const="newbing",
|
153
|
-
help="if use newbing",
|
154
|
-
)
|
155
148
|
bot_group.add_argument(
|
156
149
|
"--use_glm",
|
157
150
|
dest="bot",
|
@@ -198,7 +191,6 @@ def main():
|
|
198
191
|
help="bot type",
|
199
192
|
choices=[
|
200
193
|
"chatgptapi",
|
201
|
-
"newbing",
|
202
194
|
"glm",
|
203
195
|
"gemini",
|
204
196
|
"langchain",
|
@@ -6,6 +6,8 @@ import os
|
|
6
6
|
from dataclasses import dataclass, field
|
7
7
|
from typing import Any, Iterable, Literal
|
8
8
|
|
9
|
+
import yaml
|
10
|
+
|
9
11
|
from xiaogpt.utils import validate_proxy
|
10
12
|
|
11
13
|
LATEST_ASK_API = "https://userprofile.mina.mi.com/device_profile/v2/conversation?source=dialogu&hardware={hardware}×tamp={timestamp}&limit=2"
|
@@ -84,18 +86,10 @@ class Config:
|
|
84
86
|
] = "mi"
|
85
87
|
tts_options: dict[str, Any] = field(default_factory=dict)
|
86
88
|
gpt_options: dict[str, Any] = field(default_factory=dict)
|
87
|
-
bing_cookie_path: str = ""
|
88
|
-
bing_cookies: dict | None = None
|
89
89
|
|
90
90
|
def __post_init__(self) -> None:
|
91
91
|
if self.proxy:
|
92
92
|
validate_proxy(self.proxy)
|
93
|
-
if self.bot == "newbing":
|
94
|
-
if not (self.bing_cookie_path or self.bing_cookies):
|
95
|
-
raise Exception(
|
96
|
-
"New bing bot needs bing_cookie_path or bing_cookies, read this: "
|
97
|
-
"https://github.com/acheong08/EdgeGPT#getting-authentication-required"
|
98
|
-
)
|
99
93
|
if (
|
100
94
|
self.api_base
|
101
95
|
and self.api_base.endswith(("openai.azure.com", "openai.azure.com/"))
|
@@ -140,7 +134,10 @@ class Config:
|
|
140
134
|
def read_from_file(cls, config_path: str) -> dict:
|
141
135
|
result = {}
|
142
136
|
with open(config_path, "rb") as f:
|
143
|
-
|
137
|
+
if config_path.endswith(".json"):
|
138
|
+
config = json.load(f)
|
139
|
+
else:
|
140
|
+
config = yaml.safe_load(f)
|
144
141
|
for key, value in config.items():
|
145
142
|
if value is None:
|
146
143
|
continue
|
@@ -1,81 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
import re
|
4
|
-
|
5
|
-
from xiaogpt.bot.base_bot import BaseBot, ChatHistoryMixin
|
6
|
-
from xiaogpt.utils import split_sentences
|
7
|
-
|
8
|
-
_reference_link_re = re.compile(r"\[\d+\]: .+?\n+")
|
9
|
-
|
10
|
-
|
11
|
-
class NewBingBot(ChatHistoryMixin, BaseBot):
|
12
|
-
name = "Bing"
|
13
|
-
|
14
|
-
def __init__(
|
15
|
-
self,
|
16
|
-
bing_cookie_path: str = "",
|
17
|
-
bing_cookies: dict | None = None,
|
18
|
-
proxy: str | None = None,
|
19
|
-
):
|
20
|
-
from EdgeGPT import Chatbot
|
21
|
-
|
22
|
-
self.history = []
|
23
|
-
self._bot = Chatbot(
|
24
|
-
cookiePath=bing_cookie_path, cookies=bing_cookies, proxy=proxy
|
25
|
-
)
|
26
|
-
|
27
|
-
@classmethod
|
28
|
-
def from_config(cls, config):
|
29
|
-
return cls(
|
30
|
-
bing_cookie_path=config.bing_cookie_path,
|
31
|
-
bing_cookies=config.bing_cookies,
|
32
|
-
proxy=config.proxy,
|
33
|
-
)
|
34
|
-
|
35
|
-
@staticmethod
|
36
|
-
def clean_text(s):
|
37
|
-
s = s.replace("**", "")
|
38
|
-
s = _reference_link_re.sub("", s)
|
39
|
-
s = re.sub(r"\[[\^\d]+\]", "", s)
|
40
|
-
return s.strip()
|
41
|
-
|
42
|
-
async def ask(self, query, **options):
|
43
|
-
from EdgeGPT import ConversationStyle
|
44
|
-
|
45
|
-
kwargs = {"conversation_style": ConversationStyle.balanced, **options}
|
46
|
-
completion = await self._bot.ask(prompt=query, **kwargs)
|
47
|
-
try:
|
48
|
-
text = self.clean_text(completion["item"]["messages"][1]["text"])
|
49
|
-
except Exception as e:
|
50
|
-
print(str(e))
|
51
|
-
return
|
52
|
-
print(text)
|
53
|
-
return text
|
54
|
-
|
55
|
-
async def ask_stream(self, query, **options):
|
56
|
-
from EdgeGPT import ConversationStyle
|
57
|
-
|
58
|
-
kwargs = {"conversation_style": ConversationStyle.balanced, **options}
|
59
|
-
try:
|
60
|
-
completion = self._bot.ask_stream(prompt=query, **kwargs)
|
61
|
-
except Exception:
|
62
|
-
return
|
63
|
-
|
64
|
-
async def text_gen():
|
65
|
-
current = ""
|
66
|
-
async for final, resp in completion:
|
67
|
-
if final:
|
68
|
-
break
|
69
|
-
text = self.clean_text(resp)
|
70
|
-
if text == current:
|
71
|
-
continue
|
72
|
-
diff = text[len(current) :]
|
73
|
-
print(diff, end="")
|
74
|
-
yield diff
|
75
|
-
current = text
|
76
|
-
|
77
|
-
try:
|
78
|
-
async for sentence in split_sentences(text_gen()):
|
79
|
-
yield sentence
|
80
|
-
finally:
|
81
|
-
print()
|
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
|