xiaogpt 2.60__py3-none-any.whl → 2.61__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
@@ -2,11 +2,12 @@ from __future__ import annotations
2
2
 
3
3
  from xiaogpt.bot.base_bot import BaseBot
4
4
  from xiaogpt.bot.chatgptapi_bot import ChatGPTBot
5
- from xiaogpt.bot.newbing_bot import NewBingBot
6
- from xiaogpt.bot.glm_bot import GLMBot
5
+ from xiaogpt.bot.doubao_bot import DoubaoBot
7
6
  from xiaogpt.bot.gemini_bot import GeminiBot
8
- from xiaogpt.bot.qwen_bot import QwenBot
7
+ from xiaogpt.bot.glm_bot import GLMBot
9
8
  from xiaogpt.bot.langchain_bot import LangChainBot
9
+ from xiaogpt.bot.newbing_bot import NewBingBot
10
+ from xiaogpt.bot.qwen_bot import QwenBot
10
11
  from xiaogpt.config import Config
11
12
 
12
13
  BOTS: dict[str, type[BaseBot]] = {
@@ -16,6 +17,7 @@ BOTS: dict[str, type[BaseBot]] = {
16
17
  "gemini": GeminiBot,
17
18
  "qwen": QwenBot,
18
19
  "langchain": LangChainBot,
20
+ "doubao": DoubaoBot,
19
21
  }
20
22
 
21
23
 
@@ -34,4 +36,5 @@ __all__ = [
34
36
  "QwenBot",
35
37
  "get_bot",
36
38
  "LangChainBot",
39
+ "DoubaoBot",
37
40
  ]
@@ -0,0 +1,76 @@
1
+ """ChatGLM bot"""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from typing import Any, AsyncIterator
7
+
8
+ import httpx
9
+ from rich import print
10
+
11
+ from xiaogpt.bot.base_bot import BaseBot, ChatHistoryMixin
12
+ from xiaogpt.config import Config
13
+ from xiaogpt.utils import split_sentences
14
+
15
+
16
+ class DoubaoBot(ChatHistoryMixin, BaseBot):
17
+ API_URL = "https://maas-api.ml-platform-cn-beijing.volces.com"
18
+ name = "豆包"
19
+ default_options = {"model": "skylark-chat"}
20
+
21
+ def __init__(self, access_key: str, secret_key: str) -> None:
22
+ from tetos.volc import VolcSignAuth
23
+
24
+ self.auth = VolcSignAuth(access_key, secret_key, "ml_maas", "cn-beijing")
25
+ self.history = []
26
+
27
+ @classmethod
28
+ def from_config(cls, config: Config):
29
+ return cls(access_key=config.volc_access_key, secret_key=config.volc_secret_key)
30
+
31
+ def _get_data(self, query: str, **options: Any):
32
+ options = {**self.default_options, **options}
33
+ model = options.pop("model")
34
+ ms = self.get_messages()
35
+ ms.append({"role": "user", "content": query})
36
+ return {"model": {"name": model}, "parameters": options, "messages": ms}
37
+
38
+ async def ask(self, query, **options):
39
+ data = self._get_data(query, **options)
40
+ async with httpx.AsyncClient(base_url=self.API_URL, auth=self.auth) as client:
41
+ resp = await client.post("/api/v1/chat", json=data)
42
+ resp.raise_for_status()
43
+ try:
44
+ message = resp.json()["choice"]["message"]["content"]
45
+ except Exception as e:
46
+ print(str(e))
47
+ return
48
+ self.add_message(query, message)
49
+ print(message)
50
+ return message
51
+
52
+ async def ask_stream(self, query: str, **options: Any):
53
+ data = self._get_data(query, **options)
54
+ data["stream"] = True
55
+
56
+ async def sse_gen(line_iter: AsyncIterator[str]) -> AsyncIterator[str]:
57
+ message = ""
58
+ async for chunk in line_iter:
59
+ if not chunk.startswith("data:"):
60
+ continue
61
+ message = chunk[5:].strip()
62
+ if message == "[DONE]":
63
+ break
64
+ data = json.loads(message)
65
+ text = data["choice"]["message"]["content"]
66
+ print(text, end="", flush=True)
67
+ message += text
68
+ yield text
69
+ print()
70
+ self.add_message(query, message)
71
+
72
+ async with httpx.AsyncClient(base_url=self.API_URL, auth=self.auth) as client:
73
+ async with client.stream("POST", "/api/v1/chat", json=data) as resp:
74
+ resp.raise_for_status()
75
+ async for sentence in split_sentences(sse_gen(resp.aiter_lines())):
76
+ yield sentence
xiaogpt/bot/gemini_bot.py CHANGED
@@ -12,7 +12,7 @@ generation_config = {
12
12
  "temperature": 0.7,
13
13
  "top_p": 1,
14
14
  "top_k": 1,
15
- "max_output_tokens": 2048,
15
+ "max_output_tokens": 4096,
16
16
  }
17
17
 
18
18
  safety_settings = [
@@ -32,10 +32,26 @@ safety_settings = [
32
32
  class GeminiBot(ChatHistoryMixin, BaseBot):
33
33
  name = "Gemini"
34
34
 
35
- def __init__(self, gemini_key: str) -> None:
35
+ def __init__(self, gemini_key: str, gemini_api_domain: str) -> None:
36
36
  import google.generativeai as genai
37
37
 
38
- genai.configure(api_key=gemini_key)
38
+ from google.auth import api_key
39
+
40
+ credentials = api_key.Credentials(gemini_key)
41
+ if len(gemini_api_domain) > 0:
42
+ print("Use custom gemini_api_domain: " + gemini_api_domain)
43
+ credentials._universe_domain = gemini_api_domain
44
+ genai.configure(
45
+ transport="rest",
46
+ credentials=credentials,
47
+ client_options={
48
+ "api_endpoint": "https://" + gemini_api_domain,
49
+ "universe_domain": gemini_api_domain,
50
+ },
51
+ )
52
+ else:
53
+ genai.configure(api_key=gemini_key)
54
+
39
55
  self.history = []
40
56
  model = genai.GenerativeModel(
41
57
  model_name="gemini-pro",
@@ -46,11 +62,13 @@ class GeminiBot(ChatHistoryMixin, BaseBot):
46
62
 
47
63
  @classmethod
48
64
  def from_config(cls, config):
49
- return cls(gemini_key=config.gemini_key)
65
+ return cls(
66
+ gemini_key=config.gemini_key, gemini_api_domain=config.gemini_api_domain
67
+ )
50
68
 
51
69
  async def ask(self, query, **options):
52
- self.convo.send_message(query)
53
- message = self.convo.last.text.strip()
70
+ response = self.convo.send_message(query)
71
+ message = response.text.strip()
54
72
  print(message)
55
73
  if len(self.convo.history) > 10:
56
74
  self.convo.history = self.convo.history[2:]
xiaogpt/cli.py CHANGED
@@ -37,6 +37,11 @@ def main():
37
37
  dest="gemini_key",
38
38
  help="gemini api key",
39
39
  )
40
+ parser.add_argument(
41
+ "--gemini_api_domain",
42
+ dest="gemini_api_domain",
43
+ help="custom gemini api domain",
44
+ )
40
45
  parser.add_argument(
41
46
  "--qwen_key",
42
47
  dest="qwen_key",
@@ -78,6 +83,8 @@ def main():
78
83
  default=None,
79
84
  help="try to mute xiaoai answer",
80
85
  )
86
+ parser.add_argument("--volc-access-key", help="Volcengine access key")
87
+ parser.add_argument("--volc-secret-key", help="Volcengine secret key")
81
88
  parser.add_argument(
82
89
  "--verbose",
83
90
  dest="verbose",
xiaogpt/config.py CHANGED
@@ -56,6 +56,11 @@ class Config:
56
56
  gemini_key: str = os.getenv("GEMINI_KEY", "") # keep the old rule
57
57
  qwen_key: str = os.getenv("DASHSCOPE_API_KEY", "") # keep the old rule
58
58
  serpapi_api_key: str = os.getenv("SERPAPI_API_KEY", "")
59
+ gemini_api_domain: str = os.getenv(
60
+ "GEMINI_API_DOMAIN", ""
61
+ ) # 自行部署的 Google Gemini 代理
62
+ volc_access_key: str = os.getenv("VOLC_ACCESS_KEY", "")
63
+ volc_secret_key: str = os.getenv("VOLC_SECRET_KEY", "")
59
64
  proxy: str | None = None
60
65
  mi_did: str = os.getenv("MI_DID", "")
61
66
  keyword: Iterable[str] = KEY_WORD
@@ -117,6 +122,13 @@ class Config:
117
122
  for key, value in vars(options).items():
118
123
  if value is not None and key in cls.__dataclass_fields__:
119
124
  config[key] = value
125
+ if config.get("tts") == "volc":
126
+ config.setdefault("tts_options", {}).setdefault(
127
+ "access_key", config.get("volc_access_key")
128
+ )
129
+ config.setdefault("tts_options", {}).setdefault(
130
+ "secret_key", config.get("volc_secret_key")
131
+ )
120
132
  return cls(**config)
121
133
 
122
134
  @classmethod
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: xiaogpt
3
- Version: 2.60
3
+ Version: 2.61
4
4
  Summary: Play ChatGPT or other LLM with xiaomi AI speaker
5
5
  Author-Email: yihong0618 <zouzou0208@gmail.com>
6
6
  License: MIT
@@ -22,7 +22,7 @@ Requires-Dist: google-search-results>=2.4.2
22
22
  Requires-Dist: google-generativeai
23
23
  Requires-Dist: numexpr>=2.8.6
24
24
  Requires-Dist: dashscope>=1.10.0
25
- Requires-Dist: tetos>=0.1.0
25
+ Requires-Dist: tetos>=0.1.1
26
26
  Requires-Dist: aiohttp==3.9.5; extra == "locked"
27
27
  Requires-Dist: aiosignal==1.3.1; extra == "locked"
28
28
  Requires-Dist: annotated-types==0.6.0; extra == "locked"
@@ -102,7 +102,7 @@ Requires-Dist: socksio==1.0.0; extra == "locked"
102
102
  Requires-Dist: soupsieve==2.5; extra == "locked"
103
103
  Requires-Dist: sqlalchemy==2.0.25; extra == "locked"
104
104
  Requires-Dist: tenacity==8.2.3; extra == "locked"
105
- Requires-Dist: tetos==0.1.0; extra == "locked"
105
+ Requires-Dist: tetos==0.1.1; extra == "locked"
106
106
  Requires-Dist: tqdm==4.66.1; extra == "locked"
107
107
  Requires-Dist: typing-extensions==4.9.0; extra == "locked"
108
108
  Requires-Dist: typing-inspect==0.9.0; extra == "locked"
@@ -191,6 +191,8 @@ xiaogpt --hardware LX06 --mute_xiaoai --use_chatgpt_api
191
191
  xiaogpt --hardware LX06 --mute_xiaoai --stream
192
192
  # 如果你想使用 google 的 gemini
193
193
  xiaogpt --hardware LX06 --mute_xiaoai --use_gemini --gemini_key ${gemini_key}
194
+ # 如果你想使用自己的 google gemini 服务
195
+ python3 xiaogpt.py --hardware LX06 --mute_xiaoai --use_gemini --gemini_key ${gemini_key} --gemini_api_domain ${gemini_api_domain}
194
196
  # 如果你想使用阿里的通义千问
195
197
  xiaogpt --hardware LX06 --mute_xiaoai --use_qwen --qen_key ${qwen_key}
196
198
  # 如果你想用 edge-tts
@@ -218,6 +220,8 @@ python3 xiaogpt.py --hardware LX06 --mute_xiaoai --stream
218
220
  python3 xiaogpt.py --hardware LX06 --mute_xiaoai --use_glm --glm_key ${glm_key}
219
221
  # 如果你想使用 google 的 gemini
220
222
  python3 xiaogpt.py --hardware LX06 --mute_xiaoai --use_gemini --gemini_key ${gemini_key}
223
+ # 如果你想使用自己的 google gemini 服务
224
+ python3 xiaogpt.py --hardware LX06 --mute_xiaoai --use_gemini --gemini_key ${gemini_key} --gemini_api_domain ${gemini_api_domain}
221
225
  # 如果你想使用阿里的通义千问
222
226
  python3 xiaogpt.py --hardware LX06 --mute_xiaoai --use_qwen --qen_key ${qwen_key}
223
227
  # 如果你想使用 LangChain+SerpApi 实现上网检索或其他本地服务(目前仅支持 stream 模式)
@@ -272,6 +276,7 @@ ChatGLM [文档](http://open.bigmodel.cn/doc/api#chatglm_130b)
272
276
  | serpapi_api_key | serpapi的key 参考 [SerpAPI](https://serpapi.com/) | | |
273
277
  | glm_key | chatglm 的 apikey | | |
274
278
  | gemini_key | gemini 的 apikey [参考](https://makersuite.google.com/app/apikey) | | |
279
+ | gemini_api_domain | gemini 的自定义域名 [参考](https://github.com/antergone/palm-netlify-proxy) | |
275
280
  | qwen_key | qwen 的 apikey [参考](https://help.aliyun.com/zh/dashscope/developer-reference/api-details) | | |
276
281
  | cookie | 小爱账户cookie (如果用上面密码登录可以不填) | | |
277
282
  | mi_did | 设备did | | |
@@ -292,9 +297,9 @@ ChatGLM [文档](http://open.bigmodel.cn/doc/api#chatglm_130b)
292
297
  | bing_cookie_path | NewBing使用的cookie路径,参考[这里]获取 | 也可通过环境变量 `COOKIE_FILE` 设置 | |
293
298
  | bing_cookies | NewBing使用的cookie字典,参考[这里]获取 | | |
294
299
  | deployment_id | Azure OpenAI 服务的 deployment ID | 参考这个[如何找到deployment_id](https://github.com/yihong0618/xiaogpt/issues/347#issuecomment-1784410784) | |
295
- | api_base | 如果需要替换默认的api,或者使用Azure OpenAI 服务 | 例如:`https://abc-def.openai.azure.com/` | |
296
-
297
-
300
+ | api_base | 如果需要替换默认的api,或者使用Azure OpenAI 服务 | 例如:`https://abc-def.openai.azure.com/` |
301
+ | volc_access_key | 火山引擎的 access key 请在[这里](https://console.volcengine.com/iam/keymanage/)获取 | | |
302
+ | volc_secret_key | 火山引擎的 secret key 请在[这里](https://console.volcengine.com/iam/keymanage/)获取 | | |
298
303
  [这里]: https://github.com/acheong08/EdgeGPT#getting-authentication-required
299
304
 
300
305
  ## 注意
@@ -1,19 +1,20 @@
1
- xiaogpt-2.60.dist-info/METADATA,sha256=WlspZJW0q2G9Zm4bA-bMBXiToOQpWIT6JafQnUEwZV4,26836
2
- xiaogpt-2.60.dist-info/WHEEL,sha256=7sv5iXvIiTVJSnAxCz2tGBm9DHsb2vPSzeYeT7pvGUY,90
3
- xiaogpt-2.60.dist-info/entry_points.txt,sha256=zLFzA72qQ_eWBepdA2YU5vdXFqORH8wXhv2Ox1vnYP8,46
4
- xiaogpt-2.60.dist-info/licenses/LICENSE,sha256=XdClh516MvlnOf9749JZHCxSB7y6_fyXcWmLDz6IkZY,1063
1
+ xiaogpt-2.61.dist-info/METADATA,sha256=UWMVMRGMTJSpxviAmmPkwSpMGQGOJmQ74GBFTrGNWww,28013
2
+ xiaogpt-2.61.dist-info/WHEEL,sha256=7sv5iXvIiTVJSnAxCz2tGBm9DHsb2vPSzeYeT7pvGUY,90
3
+ xiaogpt-2.61.dist-info/entry_points.txt,sha256=zLFzA72qQ_eWBepdA2YU5vdXFqORH8wXhv2Ox1vnYP8,46
4
+ xiaogpt-2.61.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
- xiaogpt/bot/__init__.py,sha256=7K9v6j6xDkuvIrJwjby0Ec_1ywd4Si0Ww9S_R8M3LeU,919
7
+ xiaogpt/bot/__init__.py,sha256=kOIY1lR0r-tbrnlcv_lj3cXxcwM4UpM8THxQ-JrRfwM,1006
8
8
  xiaogpt/bot/base_bot.py,sha256=oKn6LLFHXol4hKrSrjnxknrOqrcGICtT_GPPYRNxpkw,1467
9
9
  xiaogpt/bot/chatgptapi_bot.py,sha256=JYlq1D-YZxRwAPpd5dTFSBU7h1KNdWA7FTwgyvMxr7c,3656
10
- xiaogpt/bot/gemini_bot.py,sha256=udKrWYP7U83AWpNBggwRp9bvgR2DTHqLMX9E_DLFv-I,1840
10
+ xiaogpt/bot/doubao_bot.py,sha256=UufQmYcPbwTLTYDZUQwRy4Hg24vgPEa3hdeZWMWw9YM,2773
11
+ xiaogpt/bot/gemini_bot.py,sha256=vX-fTWyPwdB4N0HDQ9uIRCB4KvV-YgBqXjkrqgg4WHs,2516
11
12
  xiaogpt/bot/glm_bot.py,sha256=QoMJbnu5_rHDz4tzwn7gh3IoAuw7E4hZQLAfziMAvNY,1825
12
13
  xiaogpt/bot/langchain_bot.py,sha256=4Uz5iOYzA2ongCklS-9zBse2fw-7kEE_9wITH7wdVCc,1944
13
14
  xiaogpt/bot/newbing_bot.py,sha256=afUmw6tyMXbgGZvfQQWaA5h0-e0V0isFolW-WGhd0Vs,2289
14
15
  xiaogpt/bot/qwen_bot.py,sha256=325lMa4Z38rRh47HDa3J4XjvSs4SWOqMVhrMWzkGNo4,3657
15
- xiaogpt/cli.py,sha256=0ZmBmJ3dV748EaFYmKnxgGcSWy9LYoqLixKhVcRVCa4,4409
16
- xiaogpt/config.py,sha256=5k7UqyALvUGF9H6QID9p_i3dIB8BZG1XJePjwtsf2Lg,5896
16
+ xiaogpt/cli.py,sha256=y7Cs1M5IbCjtdbeLU9h_2__fLT-7C8qt3FIDrG2LaBQ,4696
17
+ xiaogpt/config.py,sha256=hCdggjjmBpQ_BX1teOuatjxUO9tRCUbSa3TLSnoiRkA,6444
17
18
  xiaogpt/langchain/callbacks.py,sha256=yR9AXQt9OHVYBWC47Q1I_BUT4Xg9iM44vnW2vv0BLpE,2616
18
19
  xiaogpt/langchain/chain.py,sha256=z0cqRlL0ElWnf31ByxZBN7AKOT-svXQDt5_NDft_nYc,1495
19
20
  xiaogpt/langchain/examples/email/mail_box.py,sha256=xauqrjE4-G4XPQnokUPE-MZgAaHQ_VrUDLlbfYTdCoo,6372
@@ -24,4 +25,4 @@ xiaogpt/tts/mi.py,sha256=1MzCB27DBohPQ_4Xz4W_FV9p-chJFDavOHB89NviLcM,1095
24
25
  xiaogpt/tts/tetos.py,sha256=9DaSrfU8Pf_aa7mI6JXMvE70XYJogIPvbim4Yuhcc3k,1903
25
26
  xiaogpt/utils.py,sha256=B7NCH7g19hcwHDXsnBJPTU6UcWnXoEntKWm-pgcet2I,2072
26
27
  xiaogpt/xiaogpt.py,sha256=Be5kUkn7H4lKU032dmaHP9LJAQKb65hMvulJMnVc5-g,15821
27
- xiaogpt-2.60.dist-info/RECORD,,
28
+ xiaogpt-2.61.dist-info/RECORD,,
File without changes