xiaogpt 1.50__py3-none-any.whl → 1.60__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/__init__.py CHANGED
@@ -4,12 +4,16 @@ from xiaogpt.bot.base_bot import BaseBot
4
4
  from xiaogpt.bot.chatgptapi_bot import ChatGPTBot
5
5
  from xiaogpt.bot.gpt3_bot import GPT3Bot
6
6
  from xiaogpt.bot.newbing_bot import NewBingBot
7
+ from xiaogpt.bot.glm_bot import GLMBot
8
+ from xiaogpt.bot.bard_bot import BardBot
7
9
  from xiaogpt.config import Config
8
10
 
9
11
  BOTS: dict[str, type[BaseBot]] = {
10
12
  "gpt3": GPT3Bot,
11
13
  "newbing": NewBingBot,
12
14
  "chatgptapi": ChatGPTBot,
15
+ "glm": GLMBot,
16
+ "bard": BardBot,
13
17
  }
14
18
 
15
19
 
@@ -20,4 +24,4 @@ def get_bot(config: Config) -> BaseBot:
20
24
  raise ValueError(f"Unsupported bot {config.bot}, must be one of {list(BOTS)}")
21
25
 
22
26
 
23
- __all__ = ["GPT3Bot", "ChatGPTBot", "NewBingBot", "get_bot"]
27
+ __all__ = ["GPT3Bot", "ChatGPTBot", "NewBingBot", "GLMBot", "BardBot", "get_bot"]
@@ -0,0 +1,32 @@
1
+ """ChatGLM bot"""
2
+ from __future__ import annotations
3
+ from typing import Any
4
+
5
+ from bardapi import BardAsync
6
+ from rich import print
7
+
8
+ from xiaogpt.bot.base_bot import BaseBot
9
+
10
+
11
+ class BardBot(BaseBot):
12
+ def __init__(
13
+ self,
14
+ bard_token: str,
15
+ ) -> None:
16
+ self._bot = BardAsync(token=bard_token)
17
+ self.history = []
18
+
19
+ @classmethod
20
+ def from_config(cls, config):
21
+ return cls(bard_token=config.bard_token)
22
+
23
+ async def ask(self, query, **options):
24
+ try:
25
+ r = await self._bot.get_answer(query)
26
+ except Exception as e:
27
+ print(str(e))
28
+ print(r["content"])
29
+ return r["content"]
30
+
31
+ def ask_stream(self, query: str, **options: Any):
32
+ raise Exception("Bard do not support stream")
@@ -48,7 +48,11 @@ class ChatGPTBot(BaseBot):
48
48
  ms.append({"role": "assistant", "content": h[1]})
49
49
  ms.append({"role": "user", "content": f"{query}"})
50
50
  kwargs = {**self.default_options, **options}
51
- completion = await openai.ChatCompletion.acreate(messages=ms, **kwargs)
51
+ try:
52
+ completion = await openai.ChatCompletion.acreate(messages=ms, **kwargs)
53
+ except Exception as e:
54
+ print(str(e))
55
+ return ""
52
56
  message = (
53
57
  completion["choices"][0]
54
58
  .get("message")
@@ -72,9 +76,13 @@ class ChatGPTBot(BaseBot):
72
76
  kwargs = {"model": "gpt-3.5-turbo", **options}
73
77
  if openai.api_type == "azure":
74
78
  kwargs["deployment_id"] = self.deployment_id
75
- completion = await openai.ChatCompletion.acreate(
76
- messages=ms, stream=True, **kwargs
77
- )
79
+ try:
80
+ completion = await openai.ChatCompletion.acreate(
81
+ messages=ms, stream=True, **kwargs
82
+ )
83
+ except Exception as e:
84
+ print(str(e))
85
+ return
78
86
 
79
87
  async def text_gen():
80
88
  async for event in completion:
xiaogpt/bot/glm_bot.py ADDED
@@ -0,0 +1,50 @@
1
+ """ChatGLM bot"""
2
+ from __future__ import annotations
3
+ from typing import Any, AsyncGenerator
4
+
5
+ import zhipuai
6
+ from rich import print
7
+
8
+ from xiaogpt.bot.base_bot import BaseBot
9
+
10
+
11
+ class GLMBot(BaseBot):
12
+ default_options = {"model": "chatglm_130b"}
13
+
14
+ def __init__(
15
+ self,
16
+ glm_key: str,
17
+ ) -> None:
18
+ self.history = []
19
+ zhipuai.api_key = glm_key
20
+
21
+ @classmethod
22
+ def from_config(cls, config):
23
+ return cls(glm_key=config.glm_key)
24
+
25
+ def ask(self, query, **options):
26
+ ms = []
27
+ for h in self.history:
28
+ ms.append({"role": "user", "content": h[0]})
29
+ ms.append({"role": "assistant", "content": h[1]})
30
+ kwargs = {**self.default_options, **options}
31
+ kwargs["prompt"] = ms
32
+ ms.append({"role": "user", "content": f"{query}"})
33
+ try:
34
+ r = zhipuai.model_api.sse_invoke(**kwargs)
35
+ except Exception as e:
36
+ print(str(e))
37
+ return
38
+ message = ""
39
+ for i in r.events():
40
+ message += str(i.data)
41
+
42
+ self.history.append([f"{query}", message])
43
+ # only keep 5 history
44
+ first_history = self.history.pop(0)
45
+ self.history = [first_history] + self.history[-5:]
46
+ print(message)
47
+ return message
48
+
49
+ def ask_stream(self, query: str, **options: Any):
50
+ raise Exception("GLM do not support stream")
xiaogpt/bot/gpt3_bot.py CHANGED
@@ -29,7 +29,11 @@ class GPT3Bot(BaseBot):
29
29
  "top_p": 1,
30
30
  **options,
31
31
  }
32
- completion = await openai.Completion.acreate(**data)
32
+ try:
33
+ completion = await openai.Completion.acreate(**data)
34
+ except Exception as e:
35
+ print(str(e))
36
+ return ""
33
37
  print(completion["choices"][0]["text"])
34
38
  return completion["choices"][0]["text"]
35
39
 
@@ -43,12 +47,17 @@ class GPT3Bot(BaseBot):
43
47
  "stream": True,
44
48
  **options,
45
49
  }
46
- completion = await openai.Completion.acreate(**data)
50
+ try:
51
+ completion = await openai.Completion.acreate(**data)
52
+ except Exception as e:
53
+ print(str(e))
54
+ return
47
55
 
48
56
  async def text_gen():
49
57
  async for event in completion:
50
- print(event["text"], end="")
51
- yield event["text"]
58
+ text = event["choices"][0]["text"]
59
+ print(text, end="")
60
+ yield text
52
61
 
53
62
  try:
54
63
  async for sentence in split_sentences(text_gen()):
@@ -40,13 +40,20 @@ class NewBingBot(BaseBot):
40
40
  async def ask(self, query, **options):
41
41
  kwargs = {"conversation_style": ConversationStyle.balanced, **options}
42
42
  completion = await self._bot.ask(prompt=query, **kwargs)
43
- text = self.clean_text(completion["item"]["messages"][1]["text"])
43
+ try:
44
+ text = self.clean_text(completion["item"]["messages"][1]["text"])
45
+ except Exception as e:
46
+ print(str(e))
47
+ return
44
48
  print(text)
45
49
  return text
46
50
 
47
51
  async def ask_stream(self, query, **options):
48
52
  kwargs = {"conversation_style": ConversationStyle.balanced, **options}
49
- completion = self._bot.ask_stream(prompt=query, **kwargs)
53
+ try:
54
+ completion = self._bot.ask_stream(prompt=query, **kwargs)
55
+ except Exception as e:
56
+ return
50
57
 
51
58
  async def text_gen():
52
59
  current = ""
xiaogpt/cli.py CHANGED
@@ -27,6 +27,16 @@ def main():
27
27
  dest="openai_key",
28
28
  help="openai api key",
29
29
  )
30
+ parser.add_argument(
31
+ "--glm_key",
32
+ dest="glm_key",
33
+ help="chatglm api key",
34
+ )
35
+ parser.add_argument(
36
+ "--bard_token",
37
+ dest="bard_token",
38
+ help="google bard token see https://github.com/dsdanielpark/Bard-API",
39
+ )
30
40
  parser.add_argument(
31
41
  "--proxy",
32
42
  dest="proxy",
@@ -94,13 +104,30 @@ def main():
94
104
  const="newbing",
95
105
  help="if use newbing",
96
106
  )
107
+ group.add_argument(
108
+ "--use_glm",
109
+ dest="bot",
110
+ action="store_const",
111
+ const="glm",
112
+ help="if use chatglm",
113
+ )
114
+ group.add_argument(
115
+ "--use_bard",
116
+ dest="bot",
117
+ action="store_const",
118
+ const="bard",
119
+ help="if use bard",
120
+ )
97
121
  parser.add_argument(
98
122
  "--bing_cookie_path",
99
123
  dest="bing_cookie_path",
100
124
  help="new bing cookies path if use new bing",
101
125
  )
102
126
  group.add_argument(
103
- "--bot", dest="bot", help="bot type", choices=["gpt3", "chatgptapi", "newbing"]
127
+ "--bot",
128
+ dest="bot",
129
+ help="bot type",
130
+ choices=["gpt3", "chatgptapi", "newbing", "glm", "bard"],
104
131
  )
105
132
  parser.add_argument(
106
133
  "--config",
@@ -129,6 +156,8 @@ def main():
129
156
  )
130
157
 
131
158
  options = parser.parse_args()
159
+ if options.bot in ["glm", "bard"] and options.stream:
160
+ raise Exception("For now ChatGLM do not support stream")
132
161
  config = Config.from_options(options)
133
162
 
134
163
  miboy = MiGPT(config)
xiaogpt/config.py CHANGED
@@ -60,6 +60,8 @@ class Config:
60
60
  account: str = os.getenv("MI_USER", "")
61
61
  password: str = os.getenv("MI_PASS", "")
62
62
  openai_key: str = os.getenv("OPENAI_API_KEY", "")
63
+ glm_key: str = os.getenv("CHATGLM_KEY", "")
64
+ bard_token: str = os.getenv("BARD_TOKEN", "")
63
65
  proxy: str | None = None
64
66
  mi_did: str = os.getenv("MI_DID", "")
65
67
  keyword: Iterable[str] = KEY_WORD
@@ -138,5 +140,9 @@ class Config:
138
140
  key, value = "bot", "gpt3"
139
141
  elif key == "use_newbing":
140
142
  key, value = "bot", "newbing"
143
+ elif key == "use_glm":
144
+ key, value = "bot", "glm"
145
+ elif key == "use_bard":
146
+ key, value = "bot", "bard"
141
147
  result[key] = value
142
148
  return result
xiaogpt/xiaogpt.py CHANGED
@@ -356,7 +356,10 @@ class MiGPT:
356
356
  if not self.config.stream:
357
357
  async with ClientSession(trust_env=True) as session:
358
358
  openai.aiosession.set(session)
359
- answer = await self.chatbot.ask(query, **self.config.gpt_options)
359
+ if self.config.bot == "glm":
360
+ answer = self._chatbot.ask(query, **self.config.gpt_options)
361
+ else:
362
+ answer = await self.chatbot.ask(query, **self.config.gpt_options)
360
363
  message = self._normalize(answer) if answer else ""
361
364
  yield message
362
365
  return
@@ -418,6 +421,7 @@ class MiGPT:
418
421
  )
419
422
 
420
423
  async def run_forever(self):
424
+ ask_name = self.config.bot.upper()
421
425
  async with ClientSession() as session:
422
426
  await self.init_all_data(session)
423
427
  task = asyncio.create_task(self.poll_latest_ask())
@@ -467,7 +471,7 @@ class MiGPT:
467
471
  else:
468
472
  # waiting for xiaoai speaker done
469
473
  await asyncio.sleep(8)
470
- await self.do_tts("正在问GPT请耐心等待")
474
+ await self.do_tts(f"正在问{ask_name}请耐心等待")
471
475
  try:
472
476
  print(
473
477
  "以下是小爱的回答: ",
@@ -475,7 +479,7 @@ class MiGPT:
475
479
  )
476
480
  except IndexError:
477
481
  print("小爱没回")
478
- print("以下是GPT的回答: ", end="")
482
+ print(f"以下是 {ask_name} 的回答: ", end="")
479
483
  try:
480
484
  if not self.config.enable_edge_tts:
481
485
  async for message in self.ask_gpt(query):
@@ -489,7 +493,7 @@ class MiGPT:
489
493
  await self.edge_tts(self.ask_gpt(query), tts_lang)
490
494
  print("回答完毕")
491
495
  except Exception as e:
492
- print(f"GPT回答出错 {str(e)}")
496
+ print(f"{ask_name} 回答出错 {str(e)}")
493
497
  if self.in_conversation:
494
498
  print(f"继续对话, 或用`{self.config.end_conversation}`结束对话")
495
499
  await self.wakeup_xiaoai()
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: xiaogpt
3
- Version: 1.50
4
- Summary: Play ChatGPT with xiaomi AI speaker
3
+ Version: 1.60
4
+ Summary: Play ChatGPT or other LLM with xiaomi AI speaker
5
5
  Author-Email: yihong0618 <zouzou0208@gmail.com>
6
6
  License: MIT
7
7
  Classifier: License :: OSI Approved :: MIT License
@@ -13,6 +13,8 @@ Requires-Dist: miservice_fork
13
13
  Requires-Dist: openai
14
14
  Requires-Dist: aiohttp
15
15
  Requires-Dist: rich
16
+ Requires-Dist: zhipuai
17
+ Requires-Dist: bardapi
16
18
  Requires-Dist: edge-tts>=6.1.3
17
19
  Requires-Dist: EdgeGPT==0.1.26
18
20
  Description-Content-Type: text/markdown
@@ -36,6 +38,7 @@ Play ChatGPT with Xiaomi AI Speaker
36
38
  - GPT3
37
39
  - ChatGPT
38
40
  - New Bing
41
+ - [ChatGLM](http://open.bigmodel.cn/)
39
42
 
40
43
  ## Windows 获取小米音响DID
41
44
 
@@ -110,6 +113,11 @@ python3 xiaogpt.py --hardware LX06 --mute_xiaoai --stream
110
113
  # 如果你想使用 gpt3 ai
111
114
  export OPENAI_API_KEY=${your_api_key}
112
115
  python3 xiaogpt.py --hardware LX06 --mute_xiaoai --use_gpt3
116
+
117
+ # 如果你想使用 ChatGLM api
118
+ python3 xiaogpt.py --hardware LX06 --mute_xiaoai --use_glm --glm_key ${glm_key}
119
+ # 如果你想使用 google 的 bard
120
+ python3 xiaogpt.py --hardware LX06 --mute_xiaoai --use_bard --bard_token ${bard_token}
113
121
  ```
114
122
 
115
123
  ## config.json
@@ -141,6 +149,8 @@ python3 xiaogpt.py
141
149
  ```
142
150
 
143
151
  具体参数作用请参考 [Open AI API 文档](https://platform.openai.com/docs/api-reference/chat/create)。
152
+ ChatGLM [文档](http://open.bigmodel.cn/doc/api#chatglm_130b)
153
+ Bard-API [参考](https://github.com/dsdanielpark/Bard-API)
144
154
  ## 配置项说明
145
155
 
146
156
  | 参数 | 说明 | 默认值 |
@@ -149,6 +159,8 @@ python3 xiaogpt.py
149
159
  | account | 小爱账户 | |
150
160
  | password | 小爱账户密码 | |
151
161
  | openai_key | openai的apikey | |
162
+ | glm_key | chatglm 的 apikey | |
163
+ | bard_token | bard 的 token 参考 [Bard-API](https://github.com/dsdanielpark/Bard-API) | |
152
164
  | cookie | 小爱账户cookie (如果用上面密码登录可以不填) | |
153
165
  | mi_did | 设备did | |
154
166
  | use_command | 使用 MI command 与小爱交互 | `false` |
@@ -0,0 +1,18 @@
1
+ xiaogpt-1.60.dist-info/METADATA,sha256=R29SaPwyUtu65J7LcGCchYGca_RmwwTzoZLuEuCrDO4,12819
2
+ xiaogpt-1.60.dist-info/WHEEL,sha256=0QD4Fi8spmPDA9YIWsctxI6ukFf44Zgk0L9495lbqs0,90
3
+ xiaogpt-1.60.dist-info/entry_points.txt,sha256=zLFzA72qQ_eWBepdA2YU5vdXFqORH8wXhv2Ox1vnYP8,46
4
+ xiaogpt-1.60.dist-info/licenses/LICENSE,sha256=XdClh516MvlnOf9749JZHCxSB7y6_fyXcWmLDz6IkZY,1063
5
+ xiaogpt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ xiaogpt/__main__.py,sha256=MSmt_5Xg84uHqzTN38JwgseJK8rsJn_11A8WD99VtEo,61
7
+ xiaogpt/bot/__init__.py,sha256=CrxzcQXn4DZVw83l8qXWQOZxSFbo7570mjyTcZTi6Jk,780
8
+ xiaogpt/bot/bard_bot.py,sha256=UKgfLLKwte8XBZFl7H7bAQRZM17qbI8Sa2AUrtzBrwM,774
9
+ xiaogpt/bot/base_bot.py,sha256=kzbUw1eQrgFqkE_eZZrWmcbPdwFrQezJBLm7cJAM8qw,554
10
+ xiaogpt/bot/chatgptapi_bot.py,sha256=cq0CwXD6ynNw7hB-bYubP0Nsz7pT49JYKp0_UjRoIps,3477
11
+ xiaogpt/bot/glm_bot.py,sha256=aenSgy6w5GKCAlJ9vrmNUliHOgVqen8OHsDpcLYWzj8,1385
12
+ xiaogpt/bot/gpt3_bot.py,sha256=Ju_c9izW09XbCCSgZTp-3Rjz1zBMeBGj19zH0UwqGFw,1827
13
+ xiaogpt/bot/newbing_bot.py,sha256=fRRrNnnw6xVFlkp4aQ37XRrOCnZmc2tCyMmW7BFgrOE,2156
14
+ xiaogpt/cli.py,sha256=DXSH-5YEejQdPkrfbrKoykCglkvyUzvVN7-sRHk2kEI,4152
15
+ xiaogpt/config.py,sha256=6_GMtOx2_CMHfZwlC0q7JKm9QI1oF04P1G3zpB1Fhks,5604
16
+ xiaogpt/utils.py,sha256=kJ8nOBkilEoo1i2uUSp9tkUWV4pWrd5_EzEicZXzNjY,2071
17
+ xiaogpt/xiaogpt.py,sha256=KeRQqXL6DV1_nG0tw0sxCiZFQwXQ-mpULvnia43JboU,18769
18
+ xiaogpt-1.60.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: pdm-backend (2.1.2)
2
+ Generator: pdm-backend (2.1.4)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,16 +0,0 @@
1
- xiaogpt-1.50.dist-info/METADATA,sha256=s-urqI40icxt4GrMzdNbtWIOeI1DjbEzAPY65DcOhhQ,12066
2
- xiaogpt-1.50.dist-info/WHEEL,sha256=g58cvAsF5_9d0VXJuk7F0rhl6nAjUc5P9vx880WkZtI,90
3
- xiaogpt-1.50.dist-info/entry_points.txt,sha256=zLFzA72qQ_eWBepdA2YU5vdXFqORH8wXhv2Ox1vnYP8,46
4
- xiaogpt-1.50.dist-info/licenses/LICENSE,sha256=XdClh516MvlnOf9749JZHCxSB7y6_fyXcWmLDz6IkZY,1063
5
- xiaogpt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- xiaogpt/__main__.py,sha256=MSmt_5Xg84uHqzTN38JwgseJK8rsJn_11A8WD99VtEo,61
7
- xiaogpt/bot/__init__.py,sha256=ggkvJF_CgTJkYGvklIfKQalM5MyshZHShl5vugLZTiY,639
8
- xiaogpt/bot/base_bot.py,sha256=kzbUw1eQrgFqkE_eZZrWmcbPdwFrQezJBLm7cJAM8qw,554
9
- xiaogpt/bot/chatgptapi_bot.py,sha256=XcePzPpTo5ofVJtT6IBjSRjj0aoppdJ8Zs18spAc76o,3280
10
- xiaogpt/bot/gpt3_bot.py,sha256=D9F_8ZGKp264ro6aTCzV3PGZ3ZSdj__-Idi5_xmkga0,1605
11
- xiaogpt/bot/newbing_bot.py,sha256=OBTZYWEqd3sfPl_0BrQxXZC79l8-l-2ikYFIhc4plqI,1996
12
- xiaogpt/cli.py,sha256=YP8OcSN0Xqw7FRhp0VRb6SSBND-czYVi2BhKITHnki8,3415
13
- xiaogpt/config.py,sha256=O-hGXaaDvHFjpwWxSrLxfdGaO7OxJILfn99swElGkCs,5318
14
- xiaogpt/utils.py,sha256=kJ8nOBkilEoo1i2uUSp9tkUWV4pWrd5_EzEicZXzNjY,2071
15
- xiaogpt/xiaogpt.py,sha256=OByDLqV2AmDZ-QsJIgCnR2b8A0b2O-d7nqMAF-0z2M8,18548
16
- xiaogpt-1.50.dist-info/RECORD,,