xiaogpt 2.25__py3-none-any.whl → 2.30__py3-none-any.whl
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/bot/chatgptapi_bot.py +1 -1
- xiaogpt/cli.py +18 -1
- xiaogpt/config.py +8 -1
- xiaogpt/tts/__init__.py +3 -0
- xiaogpt/tts/azure.py +97 -0
- xiaogpt/tts/base.py +1 -1
- xiaogpt/xiaogpt.py +73 -69
- {xiaogpt-2.25.dist-info → xiaogpt-2.30.dist-info}/METADATA +69 -39
- {xiaogpt-2.25.dist-info → xiaogpt-2.30.dist-info}/RECORD +12 -11
- {xiaogpt-2.25.dist-info → xiaogpt-2.30.dist-info}/WHEEL +0 -0
- {xiaogpt-2.25.dist-info → xiaogpt-2.30.dist-info}/entry_points.txt +0 -0
- {xiaogpt-2.25.dist-info → xiaogpt-2.30.dist-info}/licenses/LICENSE +0 -0
xiaogpt/bot/chatgptapi_bot.py
CHANGED
@@ -30,7 +30,7 @@ class ChatGPTBot(ChatHistoryMixin, BaseBot):
|
|
30
30
|
return openai.AsyncAzureOpenAI(
|
31
31
|
api_key=self.openai_key,
|
32
32
|
azure_endpoint=self.api_base,
|
33
|
-
api_version="
|
33
|
+
api_version="2024-02-15-preview",
|
34
34
|
azure_deployment=self.deployment_id,
|
35
35
|
http_client=sess,
|
36
36
|
)
|
xiaogpt/cli.py
CHANGED
@@ -90,6 +90,16 @@ def main():
|
|
90
90
|
default=None,
|
91
91
|
help="show info",
|
92
92
|
)
|
93
|
+
parser.add_argument(
|
94
|
+
"--azure_tts_speech_key",
|
95
|
+
dest="azure_tts_speech_key",
|
96
|
+
help="if use azure tts",
|
97
|
+
)
|
98
|
+
parser.add_argument(
|
99
|
+
"--azure_tts_service_region",
|
100
|
+
dest="azure_tts_service_region",
|
101
|
+
help="if use azure tts",
|
102
|
+
)
|
93
103
|
tts_group = parser.add_mutually_exclusive_group()
|
94
104
|
tts_group.add_argument(
|
95
105
|
"--enable_edge_tts",
|
@@ -98,7 +108,11 @@ def main():
|
|
98
108
|
const="edge",
|
99
109
|
help="if use edge tts",
|
100
110
|
)
|
101
|
-
tts_group.add_argument(
|
111
|
+
tts_group.add_argument(
|
112
|
+
"--tts",
|
113
|
+
help="tts type",
|
114
|
+
choices=["mi", "edge", "openai", "azure"],
|
115
|
+
)
|
102
116
|
bot_group = parser.add_mutually_exclusive_group()
|
103
117
|
bot_group.add_argument(
|
104
118
|
"--use_gpt3",
|
@@ -197,6 +211,9 @@ def main():
|
|
197
211
|
options = parser.parse_args()
|
198
212
|
if options.bot in ["bard"] and options.stream:
|
199
213
|
raise Exception("For now Bard do not support stream")
|
214
|
+
if options.tts in ["edge", "openai", "azure"]:
|
215
|
+
print("Will close stream to better tts")
|
216
|
+
options.stream = False
|
200
217
|
config = Config.from_options(options)
|
201
218
|
|
202
219
|
miboy = MiGPT(config)
|
xiaogpt/config.py
CHANGED
@@ -81,11 +81,13 @@ class Config:
|
|
81
81
|
start_conversation: str = "开始持续对话"
|
82
82
|
end_conversation: str = "结束持续对话"
|
83
83
|
stream: bool = False
|
84
|
-
tts: Literal["mi", "edge"] = "mi"
|
84
|
+
tts: Literal["mi", "edge", "azure", "openai"] = "mi"
|
85
85
|
tts_voice: str | None = None
|
86
86
|
gpt_options: dict[str, Any] = field(default_factory=dict)
|
87
87
|
bing_cookie_path: str = ""
|
88
88
|
bing_cookies: dict | None = None
|
89
|
+
azure_tts_speech_key: str | None = None
|
90
|
+
azure_tts_service_region: str = "eastasia"
|
89
91
|
|
90
92
|
def __post_init__(self) -> None:
|
91
93
|
if self.proxy:
|
@@ -110,6 +112,11 @@ class Config:
|
|
110
112
|
raise Exception(
|
111
113
|
"Using GPT api needs openai API key, please google how to"
|
112
114
|
)
|
115
|
+
if self.tts == "azure" and not self.azure_tts_speech_key:
|
116
|
+
raise Exception("Using Azure TTS needs azure speech key")
|
117
|
+
if self.tts in ["azure", "edge", "openai"]:
|
118
|
+
print("Will close stream when use tts: {self.tts} for better experience")
|
119
|
+
self.stream = False
|
113
120
|
|
114
121
|
@property
|
115
122
|
def tts_command(self) -> str:
|
xiaogpt/tts/__init__.py
CHANGED
xiaogpt/tts/azure.py
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import logging
|
4
|
+
import tempfile
|
5
|
+
from pathlib import Path
|
6
|
+
from typing import Optional
|
7
|
+
|
8
|
+
import azure.cognitiveservices.speech as speechsdk
|
9
|
+
|
10
|
+
from xiaogpt.tts.base import AudioFileTTS
|
11
|
+
from xiaogpt.utils import calculate_tts_elapse
|
12
|
+
|
13
|
+
logger = logging.getLogger(__name__)
|
14
|
+
|
15
|
+
|
16
|
+
class AzureTTS(AudioFileTTS):
|
17
|
+
voice_name = "zh-CN-XiaoxiaoMultilingualNeural"
|
18
|
+
|
19
|
+
async def make_audio_file(self, query: str, text: str) -> tuple[Path, float]:
|
20
|
+
output_file = tempfile.NamedTemporaryFile(
|
21
|
+
suffix=".mp3", mode="wb", delete=False, dir=self.dirname.name
|
22
|
+
)
|
23
|
+
|
24
|
+
speech_synthesizer = self._build_speech_synthesizer(output_file.name)
|
25
|
+
result: Optional[speechsdk.SpeechSynthesisResult] = (
|
26
|
+
speech_synthesizer.speak_text_async(text).get()
|
27
|
+
)
|
28
|
+
if result is None:
|
29
|
+
raise RuntimeError(
|
30
|
+
f"Failed to get tts from azure with voice={self.voice_name}"
|
31
|
+
)
|
32
|
+
# Check result
|
33
|
+
if result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted:
|
34
|
+
logger.debug("Speech synthesized for text [{}]".format(text))
|
35
|
+
return Path(output_file.name), calculate_tts_elapse(text)
|
36
|
+
elif result.reason == speechsdk.ResultReason.Canceled:
|
37
|
+
cancellation_details = result.cancellation_details
|
38
|
+
logger.warning(f"Speech synthesis canceled: {cancellation_details.reason}")
|
39
|
+
if cancellation_details.reason == speechsdk.CancellationReason.Error:
|
40
|
+
errmsg = f"Error details: {cancellation_details.error_details}"
|
41
|
+
logger.error(errmsg)
|
42
|
+
raise RuntimeError(errmsg)
|
43
|
+
raise RuntimeError(f"Failed to get tts from azure with voice={self.voice_name}")
|
44
|
+
|
45
|
+
def _build_speech_synthesizer(self, filename: str):
|
46
|
+
speech_key = self.config.azure_tts_speech_key
|
47
|
+
service_region = self.config.azure_tts_service_region
|
48
|
+
if not speech_key:
|
49
|
+
raise Exception("Azure tts need speech key")
|
50
|
+
speech_config = speechsdk.SpeechConfig(
|
51
|
+
subscription=speech_key, region=service_region
|
52
|
+
)
|
53
|
+
speech_config.set_speech_synthesis_output_format(
|
54
|
+
speechsdk.SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3
|
55
|
+
)
|
56
|
+
if self.config.proxy:
|
57
|
+
host, port, username, password = self._parse_proxy(self.config.proxy)
|
58
|
+
|
59
|
+
if username and password:
|
60
|
+
speech_config.set_proxy(
|
61
|
+
hostname=host, port=port, username=username, password=password
|
62
|
+
)
|
63
|
+
else:
|
64
|
+
speech_config.set_proxy(hostname=host, port=port)
|
65
|
+
|
66
|
+
speech_config.speech_synthesis_voice_name = (
|
67
|
+
self.config.tts_voice or self.voice_name
|
68
|
+
)
|
69
|
+
speech_synthesizer = speechsdk.SpeechSynthesizer(
|
70
|
+
speech_config=speech_config,
|
71
|
+
audio_config=speechsdk.audio.AudioOutputConfig(filename=filename), # type: ignore
|
72
|
+
)
|
73
|
+
return speech_synthesizer
|
74
|
+
|
75
|
+
def _parse_proxy(self, proxy_str: str):
|
76
|
+
proxy_str = proxy_str
|
77
|
+
proxy_str_splited = proxy_str.split("://")
|
78
|
+
proxy_type = proxy_str_splited[0]
|
79
|
+
proxy_addr = proxy_str_splited[1]
|
80
|
+
|
81
|
+
if proxy_type == "http":
|
82
|
+
if "@" in proxy_addr:
|
83
|
+
proxy_addr_splited = proxy_addr.split("@")
|
84
|
+
proxy_auth = proxy_addr_splited[0]
|
85
|
+
proxy_addr_netloc = proxy_addr_splited[1]
|
86
|
+
proxy_auth_splited = proxy_auth.split(":")
|
87
|
+
username = proxy_auth_splited[0]
|
88
|
+
password = proxy_auth_splited[1]
|
89
|
+
else:
|
90
|
+
proxy_addr_netloc = proxy_addr
|
91
|
+
username, password = None, None
|
92
|
+
|
93
|
+
proxy_addr_netloc_splited = proxy_addr_netloc.split(":")
|
94
|
+
host = proxy_addr_netloc_splited[0]
|
95
|
+
port = int(proxy_addr_netloc_splited[1])
|
96
|
+
return host, port, username, password
|
97
|
+
raise NotImplementedError
|
xiaogpt/tts/base.py
CHANGED
@@ -123,7 +123,7 @@ class AudioFileTTS(TTS):
|
|
123
123
|
break
|
124
124
|
else:
|
125
125
|
url, duration = result
|
126
|
-
logger.debug("Playing URL %s(%s seconds)", url, duration)
|
126
|
+
logger.debug("Playing URL %s (%s seconds)", url, duration)
|
127
127
|
await self.mina_service.play_by_url(self.device_id, url)
|
128
128
|
await self.wait_for_duration(duration)
|
129
129
|
await task
|
xiaogpt/xiaogpt.py
CHANGED
@@ -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
|
26
|
+
from xiaogpt.tts import TTS, EdgeTTS, MiTTS, AzureTTS
|
27
27
|
from xiaogpt.tts.openai import OpenAITTS
|
28
28
|
from xiaogpt.utils import (
|
29
29
|
parse_cookie_string,
|
@@ -51,6 +51,7 @@ class MiGPT:
|
|
51
51
|
self.log.setLevel(logging.DEBUG if config.verbose else logging.INFO)
|
52
52
|
self.log.addHandler(RichHandler())
|
53
53
|
self.log.debug(config)
|
54
|
+
self.mi_session = ClientSession()
|
54
55
|
|
55
56
|
async def poll_latest_ask(self):
|
56
57
|
async with ClientSession() as session:
|
@@ -78,8 +79,8 @@ class MiGPT:
|
|
78
79
|
async def init_all_data(self, session):
|
79
80
|
await self.login_miboy(session)
|
80
81
|
await self._init_data_hardware()
|
81
|
-
|
82
|
-
self.cookie_jar =
|
82
|
+
self.mi_session.cookie_jar.update_cookies(self.get_cookie())
|
83
|
+
self.cookie_jar = self.mi_session.cookie_jar
|
83
84
|
self.tts # init tts
|
84
85
|
|
85
86
|
async def login_miboy(self, session):
|
@@ -215,14 +216,17 @@ class MiGPT:
|
|
215
216
|
data = await r.json()
|
216
217
|
except Exception:
|
217
218
|
self.log.warning("get latest ask from xiaoai error, retry")
|
218
|
-
if i ==
|
219
|
+
if i == 1:
|
219
220
|
# tricky way to fix #282 #272 # if it is the third time we re init all data
|
220
221
|
print("Maybe outof date trying to re init it")
|
221
|
-
await self.
|
222
|
+
await self._retry()
|
222
223
|
else:
|
223
224
|
return self._get_last_query(data)
|
224
225
|
return None
|
225
226
|
|
227
|
+
async def _retry(self):
|
228
|
+
await self.init_all_data(self.mi_session)
|
229
|
+
|
226
230
|
def _get_last_query(self, data: dict) -> dict | None:
|
227
231
|
if d := data.get("data"):
|
228
232
|
records = json.loads(d).get("records")
|
@@ -256,6 +260,8 @@ class MiGPT:
|
|
256
260
|
def tts(self) -> TTS:
|
257
261
|
if self.config.tts == "edge":
|
258
262
|
return EdgeTTS(self.mina_service, self.device_id, self.config)
|
263
|
+
elif self.config.tts == "azure":
|
264
|
+
return AzureTTS(self.mina_service, self.device_id, self.config)
|
259
265
|
elif self.config.tts == "openai":
|
260
266
|
return OpenAITTS(self.mina_service, self.device_id, self.config)
|
261
267
|
else:
|
@@ -339,71 +345,69 @@ class MiGPT:
|
|
339
345
|
)
|
340
346
|
|
341
347
|
async def run_forever(self):
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
await self.stop_if_xiaoai_is_playing()
|
369
|
-
continue
|
348
|
+
await self.init_all_data(self.mi_session)
|
349
|
+
task = asyncio.create_task(self.poll_latest_ask())
|
350
|
+
assert task is not None # to keep the reference to task, do not remove this
|
351
|
+
print(
|
352
|
+
f"Running xiaogpt now, 用[green]{'/'.join(self.config.keyword)}[/]开头来提问"
|
353
|
+
)
|
354
|
+
print(f"或用[green]{self.config.start_conversation}[/]开始持续对话")
|
355
|
+
while True:
|
356
|
+
self.polling_event.set()
|
357
|
+
new_record = await self.last_record.get()
|
358
|
+
self.polling_event.clear() # stop polling when processing the question
|
359
|
+
query = new_record.get("query", "").strip()
|
360
|
+
|
361
|
+
if query == self.config.start_conversation:
|
362
|
+
if not self.in_conversation:
|
363
|
+
print("开始对话")
|
364
|
+
self.in_conversation = True
|
365
|
+
await self.wakeup_xiaoai()
|
366
|
+
await self.stop_if_xiaoai_is_playing()
|
367
|
+
continue
|
368
|
+
elif query == self.config.end_conversation:
|
369
|
+
if self.in_conversation:
|
370
|
+
print("结束对话")
|
371
|
+
self.in_conversation = False
|
372
|
+
await self.stop_if_xiaoai_is_playing()
|
373
|
+
continue
|
370
374
|
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
+
# we can change prompt
|
376
|
+
if self.need_change_prompt(new_record):
|
377
|
+
print(new_record)
|
378
|
+
self._change_prompt(new_record.get("query", ""))
|
375
379
|
|
376
|
-
|
377
|
-
|
378
|
-
|
380
|
+
if not self.need_ask_gpt(new_record):
|
381
|
+
self.log.debug("No new xiao ai record")
|
382
|
+
continue
|
379
383
|
|
380
|
-
|
381
|
-
|
384
|
+
# drop 帮我回答
|
385
|
+
query = re.sub(rf"^({'|'.join(self.config.keyword)})", "", query)
|
382
386
|
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
387
|
+
print("-" * 20)
|
388
|
+
print("问题:" + query + "?")
|
389
|
+
if not self.chatbot.has_history():
|
390
|
+
query = f"{query},{self.config.prompt}"
|
391
|
+
if self.config.mute_xiaoai:
|
392
|
+
await self.stop_if_xiaoai_is_playing()
|
393
|
+
else:
|
394
|
+
# waiting for xiaoai speaker done
|
395
|
+
await asyncio.sleep(8)
|
396
|
+
await self.do_tts(f"正在问{self.chatbot.name}请耐心等待")
|
397
|
+
try:
|
398
|
+
print(
|
399
|
+
"以下是小爱的回答: ",
|
400
|
+
new_record.get("answers", [])[0].get("tts", {}).get("text"),
|
401
|
+
)
|
402
|
+
except IndexError:
|
403
|
+
print("小爱没回")
|
404
|
+
print(f"以下是 {self.chatbot.name} 的回答: ", end="")
|
405
|
+
try:
|
406
|
+
await self.tts.synthesize(query, self.ask_gpt(query))
|
407
|
+
except Exception as e:
|
408
|
+
print(f"{self.chatbot.name} 回答出错 {str(e)}")
|
409
|
+
else:
|
410
|
+
print("回答完毕")
|
411
|
+
if self.in_conversation:
|
412
|
+
print(f"继续对话, 或用`{self.config.end_conversation}`结束对话")
|
413
|
+
await self.wakeup_xiaoai()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: xiaogpt
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.30
|
4
4
|
Summary: Play ChatGPT or other LLM with xiaomi AI speaker
|
5
5
|
Author-Email: yihong0618 <zouzou0208@gmail.com>
|
6
6
|
License: MIT
|
@@ -14,6 +14,7 @@ Requires-Dist: openai>=1
|
|
14
14
|
Requires-Dist: aiohttp
|
15
15
|
Requires-Dist: rich
|
16
16
|
Requires-Dist: zhipuai==2.0.1
|
17
|
+
Requires-Dist: httpx==0.24.1
|
17
18
|
Requires-Dist: bardapi
|
18
19
|
Requires-Dist: edge-tts>=6.1.3
|
19
20
|
Requires-Dist: EdgeGPT==0.1.26
|
@@ -23,6 +24,8 @@ Requires-Dist: google-search-results>=2.4.2
|
|
23
24
|
Requires-Dist: google-generativeai
|
24
25
|
Requires-Dist: numexpr>=2.8.6
|
25
26
|
Requires-Dist: dashscope==1.10.0
|
27
|
+
Requires-Dist: httpcore==0.15.0
|
28
|
+
Requires-Dist: azure-cognitiveservices-speech>=1.37.0
|
26
29
|
Description-Content-Type: text/markdown
|
27
30
|
|
28
31
|
# xiaogpt
|
@@ -47,15 +50,33 @@ Play ChatGPT and other LLM with Xiaomi AI Speaker
|
|
47
50
|
- [Bard](https://github.com/dsdanielpark/Bard-API)
|
48
51
|
- [通义千问](https://help.aliyun.com/zh/dashscope/developer-reference/api-details)
|
49
52
|
|
50
|
-
##
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
53
|
+
## 获取小米音响DID
|
54
|
+
### Windows(使用 set 设置环境变量)
|
55
|
+
```cmd
|
56
|
+
pip install miservice_fork
|
57
|
+
set MI_USER=xxxx
|
58
|
+
set MI_PASS=xxx
|
59
|
+
micli list 得到did
|
60
|
+
set MI_DID=xxxx
|
61
|
+
```
|
57
62
|
|
58
63
|
- 如果获取did报错时,请更换一下无线网络,有很大概率解决问题。
|
64
|
+
|
65
|
+
### Linux(使用 export 设置环境变量)
|
66
|
+
```sh
|
67
|
+
# 1、安装模块
|
68
|
+
pip install miservice_fork
|
69
|
+
|
70
|
+
# 2、设置环境用户参数
|
71
|
+
export MI_USER=xxxx
|
72
|
+
export MI_PASS=xxx
|
73
|
+
|
74
|
+
# 3、使用micli list 得到did
|
75
|
+
micli list
|
76
|
+
|
77
|
+
# 4、根据did设置环境DID参数
|
78
|
+
export MI_DID=xxxx
|
79
|
+
```
|
59
80
|
|
60
81
|
## 一点原理
|
61
82
|
|
@@ -85,6 +106,7 @@ Play ChatGPT and other LLM with Xiaomi AI Speaker
|
|
85
106
|
- 可以跟小爱说 `开始持续对话` 自动进入持续对话状态,`结束持续对话` 结束持续对话状态。
|
86
107
|
- 可以使用 `--tts edge` 来获取更好的 tts 能力
|
87
108
|
- 可以使用 `--tts openai` 来获取 openai tts 能力
|
109
|
+
- 可以使用 `--tts azure --azure_tts_speech_key <your-speech-key>` 来获取 Azure TTS 能力
|
88
110
|
- 可以使用 `--use_langchain` 替代 `--use_chatgpt_api` 来调用 LangChain(默认 chatgpt)服务,实现上网检索、数学运算..
|
89
111
|
|
90
112
|
e.g.
|
@@ -183,37 +205,39 @@ Bard-API [参考](https://github.com/dsdanielpark/Bard-API)
|
|
183
205
|
|
184
206
|
## 配置项说明
|
185
207
|
|
186
|
-
| 参数
|
187
|
-
|
|
188
|
-
| hardware
|
189
|
-
| account
|
190
|
-
| password
|
191
|
-
| openai_key
|
192
|
-
| serpapi_api_key
|
193
|
-
| glm_key
|
194
|
-
| gemini_key
|
195
|
-
| qwen_key
|
196
|
-
| bard_token
|
197
|
-
| cookie
|
198
|
-
| mi_did
|
199
|
-
| use_command
|
200
|
-
| mute_xiaoai
|
201
|
-
| verbose
|
202
|
-
| bot
|
203
|
-
| tts
|
204
|
-
| tts_voice
|
205
|
-
| prompt
|
206
|
-
| keyword
|
207
|
-
| change_prompt_keyword
|
208
|
-
| start_conversation
|
209
|
-
| end_conversation
|
210
|
-
| stream
|
211
|
-
| proxy
|
212
|
-
| gpt_options
|
213
|
-
| bing_cookie_path
|
214
|
-
| bing_cookies
|
215
|
-
| deployment_id
|
216
|
-
| api_base
|
208
|
+
| 参数 | 说明 | 默认值 | 可选值 |
|
209
|
+
| ------------------------ | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
210
|
+
| hardware | 设备型号 | | |
|
211
|
+
| account | 小爱账户 | | |
|
212
|
+
| password | 小爱账户密码 | | |
|
213
|
+
| openai_key | openai的apikey | | |
|
214
|
+
| serpapi_api_key | serpapi的key 参考 [SerpAPI](https://serpapi.com/) | | |
|
215
|
+
| glm_key | chatglm 的 apikey | | |
|
216
|
+
| gemini_key | gemini 的 apikey [参考](https://makersuite.google.com/app/apikey) | | |
|
217
|
+
| qwen_key | qwen 的 apikey [参考](https://help.aliyun.com/zh/dashscope/developer-reference/api-details) | | |
|
218
|
+
| bard_token | bard 的 token 参考 [Bard-API](https://github.com/dsdanielpark/Bard-API) | | |
|
219
|
+
| cookie | 小爱账户cookie (如果用上面密码登录可以不填) | | |
|
220
|
+
| mi_did | 设备did | | |
|
221
|
+
| use_command | 使用 MI command 与小爱交互 | `false` | |
|
222
|
+
| mute_xiaoai | 快速停掉小爱自己的回答 | `true` | |
|
223
|
+
| verbose | 是否打印详细日志 | `false` | |
|
224
|
+
| bot | 使用的 bot 类型,目前支持gpt3,chatgptapi和newbing | `chatgptapi` | |
|
225
|
+
| tts | 使用的 TTS 类型 | `mi` | `edge`、 `openai`、`azure` |
|
226
|
+
| tts_voice | TTS 的嗓音 | `zh-CN-XiaoxiaoNeural`(edge), `alloy`(openai), `zh-CN-XiaoxiaoMultilingualNeural`(azure) | |
|
227
|
+
| prompt | 自定义prompt | `请用100字以内回答` | |
|
228
|
+
| keyword | 自定义请求词列表 | `["请"]` | |
|
229
|
+
| change_prompt_keyword | 更改提示词触发列表 | `["更改提示词"]` | |
|
230
|
+
| start_conversation | 开始持续对话关键词 | `开始持续对话` | |
|
231
|
+
| end_conversation | 结束持续对话关键词 | `结束持续对话` | |
|
232
|
+
| stream | 使用流式响应,获得更快的响应 | `false` | |
|
233
|
+
| proxy | 支持 HTTP 代理,传入 http proxy URL | "" | |
|
234
|
+
| gpt_options | OpenAI API 的参数字典 | `{}` | |
|
235
|
+
| bing_cookie_path | NewBing使用的cookie路径,参考[这里]获取 | 也可通过环境变量 `COOKIE_FILE` 设置 | |
|
236
|
+
| bing_cookies | NewBing使用的cookie字典,参考[这里]获取 | | |
|
237
|
+
| deployment_id | Azure OpenAI 服务的 deployment ID | 参考这个[如何找到deployment_id](https://github.com/yihong0618/xiaogpt/issues/347#issuecomment-1784410784) | |
|
238
|
+
| api_base | 如果需要替换默认的api,或者使用Azure OpenAI 服务 | 例如:`https://abc-def.openai.azure.com/` | |
|
239
|
+
| azure_tts_speech_key | Azure TTS key | null | |
|
240
|
+
| 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) |
|
217
241
|
|
218
242
|
[这里]: https://github.com/acheong08/EdgeGPT#getting-authentication-required
|
219
243
|
|
@@ -264,6 +288,12 @@ xiaogpt的配置文件可通过指定volume /config,以及指定参数--config
|
|
264
288
|
docker run -v <your-config-dir>:/config yihong0618/xiaogpt --config=/config/config.json
|
265
289
|
```
|
266
290
|
|
291
|
+
### 网络使用 host 模型
|
292
|
+
|
293
|
+
```shell
|
294
|
+
docker run -v <your-config-dir>:/config --network=host yihong0618/xiaogpt --config=/config/config.json
|
295
|
+
```
|
296
|
+
|
267
297
|
### 本地编译Docker Image
|
268
298
|
|
269
299
|
```shell
|
@@ -1,30 +1,31 @@
|
|
1
|
-
xiaogpt-2.
|
2
|
-
xiaogpt-2.
|
3
|
-
xiaogpt-2.
|
4
|
-
xiaogpt-2.
|
1
|
+
xiaogpt-2.30.dist-info/METADATA,sha256=XtLWjKNLdkPj3UE_52Yv2FiplsNkOD0CvrKLRUshE3k,24670
|
2
|
+
xiaogpt-2.30.dist-info/WHEEL,sha256=N2J68yzZqJh3mI_Wg92rwhw0rtJDFpZj9bwQIMJgaVg,90
|
3
|
+
xiaogpt-2.30.dist-info/entry_points.txt,sha256=zLFzA72qQ_eWBepdA2YU5vdXFqORH8wXhv2Ox1vnYP8,46
|
4
|
+
xiaogpt-2.30.dist-info/licenses/LICENSE,sha256=XdClh516MvlnOf9749JZHCxSB7y6_fyXcWmLDz6IkZY,1063
|
5
5
|
xiaogpt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
6
|
xiaogpt/__main__.py,sha256=MSmt_5Xg84uHqzTN38JwgseJK8rsJn_11A8WD99VtEo,61
|
7
7
|
xiaogpt/bot/__init__.py,sha256=O3Wq7WRwTVdKJdKZxkBtCPdRJ8uXrQE0dqHa1ekOnfQ,1073
|
8
8
|
xiaogpt/bot/bard_bot.py,sha256=qC8m87mWvtbiwipKl_OMYCqRbh79gkyZEytgz5DysC0,840
|
9
9
|
xiaogpt/bot/base_bot.py,sha256=oKn6LLFHXol4hKrSrjnxknrOqrcGICtT_GPPYRNxpkw,1467
|
10
|
-
xiaogpt/bot/chatgptapi_bot.py,sha256=
|
10
|
+
xiaogpt/bot/chatgptapi_bot.py,sha256=JYlq1D-YZxRwAPpd5dTFSBU7h1KNdWA7FTwgyvMxr7c,3656
|
11
11
|
xiaogpt/bot/gemini_bot.py,sha256=udKrWYP7U83AWpNBggwRp9bvgR2DTHqLMX9E_DLFv-I,1840
|
12
12
|
xiaogpt/bot/glm_bot.py,sha256=QoMJbnu5_rHDz4tzwn7gh3IoAuw7E4hZQLAfziMAvNY,1825
|
13
13
|
xiaogpt/bot/gpt3_bot.py,sha256=enX45_wrGjAtOh-anf8KnjCJluWSARZbjTGD_WZgoms,2781
|
14
14
|
xiaogpt/bot/langchain_bot.py,sha256=4Uz5iOYzA2ongCklS-9zBse2fw-7kEE_9wITH7wdVCc,1944
|
15
15
|
xiaogpt/bot/newbing_bot.py,sha256=afUmw6tyMXbgGZvfQQWaA5h0-e0V0isFolW-WGhd0Vs,2289
|
16
16
|
xiaogpt/bot/qwen_bot.py,sha256=325lMa4Z38rRh47HDa3J4XjvSs4SWOqMVhrMWzkGNo4,3657
|
17
|
-
xiaogpt/cli.py,sha256=
|
18
|
-
xiaogpt/config.py,sha256=
|
17
|
+
xiaogpt/cli.py,sha256=prTtwZjwC5RDZeh3eJWzBXTUHkOvFk7hAhuq9Mmeya8,5506
|
18
|
+
xiaogpt/config.py,sha256=jKumR4BROqRnshBk79mqUAKuqSkW7gsCCPukYNzCWho,6703
|
19
19
|
xiaogpt/langchain/callbacks.py,sha256=yR9AXQt9OHVYBWC47Q1I_BUT4Xg9iM44vnW2vv0BLpE,2616
|
20
20
|
xiaogpt/langchain/chain.py,sha256=z0cqRlL0ElWnf31ByxZBN7AKOT-svXQDt5_NDft_nYc,1495
|
21
21
|
xiaogpt/langchain/examples/email/mail_box.py,sha256=xauqrjE4-G4XPQnokUPE-MZgAaHQ_VrUDLlbfYTdCoo,6372
|
22
22
|
xiaogpt/langchain/examples/email/mail_summary_tools.py,sha256=6cWvBJUaA7iaywcHdbUoww8WiCtaNw3TmwyxyF4DY7E,1561
|
23
|
-
xiaogpt/tts/__init__.py,sha256=
|
24
|
-
xiaogpt/tts/
|
23
|
+
xiaogpt/tts/__init__.py,sha256=SZ0FVKbKVbuV7xfRtpwUt5cmqyNQaFa7LyGRYsmdDNE,220
|
24
|
+
xiaogpt/tts/azure.py,sha256=Kxgc_XIWYo0A-xZrfZ_Qs2T7BzyRVCHhfzPKGKgjiXU,3978
|
25
|
+
xiaogpt/tts/base.py,sha256=-fcF5PJ1p0AHSR8GNf0LJbIbZ1m_92WXXX7ZrfzgC3s,4923
|
25
26
|
xiaogpt/tts/edge.py,sha256=yMFGxRTi086XS1d_mbMzQ365bvG4KgAz8ZptaoDAfGU,1172
|
26
27
|
xiaogpt/tts/mi.py,sha256=9HkgGWByAs7k8sTpRdVlgJnnmjc44RNAccJa6tGDlXk,1096
|
27
28
|
xiaogpt/tts/openai.py,sha256=_Qk12zYY-UuXLKvQVe3PqIvCmoRW9OcVCqQRoGCXvNc,1533
|
28
29
|
xiaogpt/utils.py,sha256=B7NCH7g19hcwHDXsnBJPTU6UcWnXoEntKWm-pgcet2I,2072
|
29
|
-
xiaogpt/xiaogpt.py,sha256=
|
30
|
-
xiaogpt-2.
|
30
|
+
xiaogpt/xiaogpt.py,sha256=KrgvlHkhXDxlb4gUIXqDIDr6wMuiDhL13stDglYk1dk,15400
|
31
|
+
xiaogpt-2.30.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|