xiaogpt 2.83__tar.gz → 2.90__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.
Files changed (29) hide show
  1. {xiaogpt-2.83 → xiaogpt-2.90}/PKG-INFO +30 -18
  2. {xiaogpt-2.83 → xiaogpt-2.90}/README.md +2 -1
  3. {xiaogpt-2.83 → xiaogpt-2.90}/pyproject.toml +28 -17
  4. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/utils.py +22 -1
  5. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/xiaogpt.py +6 -20
  6. {xiaogpt-2.83 → xiaogpt-2.90}/LICENSE +0 -0
  7. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/__init__.py +0 -0
  8. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/__main__.py +0 -0
  9. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/bot/__init__.py +0 -0
  10. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/bot/base_bot.py +0 -0
  11. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/bot/chatgptapi_bot.py +0 -0
  12. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/bot/doubao_bot.py +0 -0
  13. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/bot/gemini_bot.py +0 -0
  14. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/bot/glm_bot.py +0 -0
  15. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/bot/langchain_bot.py +0 -0
  16. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/bot/llama_bot.py +0 -0
  17. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/bot/moonshot_bot.py +0 -0
  18. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/bot/qwen_bot.py +0 -0
  19. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/bot/yi_bot.py +0 -0
  20. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/cli.py +0 -0
  21. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/config.py +0 -0
  22. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/langchain/callbacks.py +0 -0
  23. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/langchain/chain.py +0 -0
  24. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/langchain/examples/email/mail_box.py +0 -0
  25. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/langchain/examples/email/mail_summary_tools.py +0 -0
  26. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/tts/__init__.py +0 -0
  27. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/tts/base.py +0 -0
  28. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/tts/mi.py +0 -0
  29. {xiaogpt-2.83 → xiaogpt-2.90}/xiaogpt/tts/tetos.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: xiaogpt
3
- Version: 2.83
3
+ Version: 2.90
4
4
  Summary: Play ChatGPT or other LLM with xiaomi AI speaker
5
5
  Author-Email: yihong0618 <zouzou0208@gmail.com>
6
6
  License: MIT
@@ -25,6 +25,7 @@ Requires-Dist: tetos>=0.2.1
25
25
  Requires-Dist: groq>=0.5.0
26
26
  Requires-Dist: pyyaml>=6.0.1
27
27
  Requires-Dist: langchain-community>=0.0.38
28
+ Requires-Dist: lingua-language-detector>=2.0.2; python_version < "3.13"
28
29
  Requires-Dist: aiohttp==3.9.5; extra == "locked"
29
30
  Requires-Dist: aiosignal==1.3.1; extra == "locked"
30
31
  Requires-Dist: annotated-types==0.6.0; extra == "locked"
@@ -38,24 +39,25 @@ Requires-Dist: certifi==2024.2.2; extra == "locked"
38
39
  Requires-Dist: charset-normalizer==3.3.2; extra == "locked"
39
40
  Requires-Dist: click==8.1.7; extra == "locked"
40
41
  Requires-Dist: colorama==0.4.6; platform_system == "Windows" and extra == "locked"
41
- Requires-Dist: dashscope==1.19.1; extra == "locked"
42
+ Requires-Dist: dashscope==1.20.1; extra == "locked"
42
43
  Requires-Dist: dataclasses-json==0.6.3; extra == "locked"
43
44
  Requires-Dist: distro==1.9.0; extra == "locked"
44
45
  Requires-Dist: edge-tts==6.1.10; extra == "locked"
46
+ Requires-Dist: et-xmlfile==1.1.0; python_version ~= "3.8" and python_full_version != "3.9.7" and extra == "locked"
45
47
  Requires-Dist: exceptiongroup==1.2.0; python_version < "3.11" and extra == "locked"
46
48
  Requires-Dist: frozenlist==1.4.1; extra == "locked"
47
- Requires-Dist: google-ai-generativelanguage==0.6.4; extra == "locked"
49
+ Requires-Dist: google-ai-generativelanguage==0.6.6; extra == "locked"
48
50
  Requires-Dist: google-api-core==2.15.0; extra == "locked"
49
51
  Requires-Dist: google-api-core[grpc]==2.15.0; extra == "locked"
50
52
  Requires-Dist: google-api-python-client==2.125.0; extra == "locked"
51
53
  Requires-Dist: google-auth==2.26.1; extra == "locked"
52
54
  Requires-Dist: google-auth-httplib2==0.2.0; extra == "locked"
53
55
  Requires-Dist: google-cloud-texttospeech==2.16.3; extra == "locked"
54
- Requires-Dist: google-generativeai==0.5.4; extra == "locked"
56
+ Requires-Dist: google-generativeai==0.7.1; extra == "locked"
55
57
  Requires-Dist: google-search-results==2.4.2; extra == "locked"
56
58
  Requires-Dist: googleapis-common-protos==1.62.0; extra == "locked"
57
59
  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"
58
- Requires-Dist: groq==0.6.0; extra == "locked"
60
+ Requires-Dist: groq==0.9.0; extra == "locked"
59
61
  Requires-Dist: grpcio==1.60.0; extra == "locked"
60
62
  Requires-Dist: grpcio-status==1.60.0; extra == "locked"
61
63
  Requires-Dist: h11==0.14.0; extra == "locked"
@@ -66,49 +68,58 @@ Requires-Dist: httpx[socks]==0.27.0; extra == "locked"
66
68
  Requires-Dist: idna==3.7; extra == "locked"
67
69
  Requires-Dist: jsonpatch==1.33; extra == "locked"
68
70
  Requires-Dist: jsonpointer==2.4; extra == "locked"
69
- Requires-Dist: langchain==0.2.0; extra == "locked"
70
- Requires-Dist: langchain-community==0.2.0; extra == "locked"
71
- Requires-Dist: langchain-core==0.2.0; extra == "locked"
71
+ Requires-Dist: langchain==0.2.6; extra == "locked"
72
+ Requires-Dist: langchain-community==0.2.6; extra == "locked"
73
+ Requires-Dist: langchain-core==0.2.11; extra == "locked"
72
74
  Requires-Dist: langchain-text-splitters==0.2.0; extra == "locked"
73
- Requires-Dist: langsmith==0.1.45; extra == "locked"
75
+ Requires-Dist: langsmith==0.1.84; extra == "locked"
76
+ Requires-Dist: lingua-language-detector==2.0.2; python_version < "3.13" and extra == "locked"
74
77
  Requires-Dist: markdown-it-py==3.0.0; extra == "locked"
75
78
  Requires-Dist: marshmallow==3.20.1; extra == "locked"
76
79
  Requires-Dist: mdurl==0.1.2; extra == "locked"
77
- Requires-Dist: miservice-fork==2.5.0; extra == "locked"
80
+ Requires-Dist: miservice-fork==2.7.0; extra == "locked"
78
81
  Requires-Dist: multidict==6.0.5; extra == "locked"
79
82
  Requires-Dist: mutagen==1.47.0; extra == "locked"
80
83
  Requires-Dist: mypy-extensions==1.0.0; extra == "locked"
81
- Requires-Dist: numexpr==2.10.0; extra == "locked"
84
+ Requires-Dist: numexpr==2.10.1; extra == "locked"
82
85
  Requires-Dist: numpy==1.26.3; extra == "locked"
83
- Requires-Dist: openai==1.30.1; extra == "locked"
86
+ Requires-Dist: openai==1.35.10; extra == "locked"
87
+ Requires-Dist: openpyxl==3.1.5; python_version ~= "3.8" and python_full_version != "3.9.7" and extra == "locked"
84
88
  Requires-Dist: orjson==3.10.0; extra == "locked"
85
89
  Requires-Dist: packaging==23.2; extra == "locked"
90
+ Requires-Dist: pandas==2.2.2; python_version ~= "3.8" and python_full_version != "3.9.7" and extra == "locked"
86
91
  Requires-Dist: proto-plus==1.23.0; extra == "locked"
87
92
  Requires-Dist: protobuf==4.25.1; extra == "locked"
88
93
  Requires-Dist: pyasn1==0.5.1; extra == "locked"
89
94
  Requires-Dist: pyasn1-modules==0.3.0; extra == "locked"
90
- Requires-Dist: pydantic==2.5.3; extra == "locked"
91
- Requires-Dist: pydantic-core==2.14.6; extra == "locked"
95
+ Requires-Dist: pydantic==2.8.2; extra == "locked"
96
+ Requires-Dist: pydantic-core==2.20.1; extra == "locked"
92
97
  Requires-Dist: pygments==2.17.2; extra == "locked"
93
98
  Requires-Dist: pyjwt==2.8.0; extra == "locked"
94
99
  Requires-Dist: pyparsing==3.1.2; python_version > "3.0" and extra == "locked"
100
+ Requires-Dist: python-dateutil==2.9.0.post0; python_version ~= "3.8" and python_full_version != "3.9.7" and extra == "locked"
101
+ Requires-Dist: pytz==2024.1; python_version ~= "3.8" and python_full_version != "3.9.7" and extra == "locked"
95
102
  Requires-Dist: pyyaml==6.0.1; extra == "locked"
96
103
  Requires-Dist: requests==2.31.0; extra == "locked"
97
104
  Requires-Dist: rich==13.7.1; extra == "locked"
98
105
  Requires-Dist: rsa==4.9; extra == "locked"
106
+ Requires-Dist: six==1.16.0; python_version ~= "3.8" and python_full_version != "3.9.7" and extra == "locked"
99
107
  Requires-Dist: sniffio==1.3.0; extra == "locked"
100
108
  Requires-Dist: socksio==1.0.0; extra == "locked"
101
109
  Requires-Dist: soupsieve==2.5; extra == "locked"
102
110
  Requires-Dist: sqlalchemy==2.0.25; extra == "locked"
103
111
  Requires-Dist: tenacity==8.2.3; extra == "locked"
104
- Requires-Dist: tetos==0.2.1; extra == "locked"
112
+ Requires-Dist: tetos==0.3.0; extra == "locked"
105
113
  Requires-Dist: tqdm==4.66.1; extra == "locked"
106
- Requires-Dist: typing-extensions==4.9.0; extra == "locked"
114
+ Requires-Dist: typing-extensions==4.12.2; extra == "locked"
107
115
  Requires-Dist: typing-inspect==0.9.0; extra == "locked"
116
+ Requires-Dist: tzdata==2024.1; python_version ~= "3.8" and python_full_version != "3.9.7" and extra == "locked"
108
117
  Requires-Dist: uritemplate==4.1.1; extra == "locked"
109
118
  Requires-Dist: urllib3==2.1.0; extra == "locked"
119
+ Requires-Dist: websocket-client==1.8.0; extra == "locked"
120
+ Requires-Dist: websockets==12.0; extra == "locked"
110
121
  Requires-Dist: yarl==1.9.4; extra == "locked"
111
- Requires-Dist: zhipuai==2.0.1.20240423.1; extra == "locked"
122
+ Requires-Dist: zhipuai==2.1.2; extra == "locked"
112
123
  Provides-Extra: locked
113
124
  Description-Content-Type: text/markdown
114
125
 
@@ -420,9 +431,10 @@ docker run -v <your-config-dir>:/config -p 9527:9527 -e XIAOGPT_HOSTNAME=<your i
420
431
 
421
432
  注意端口必须映射为与容器内一致,XIAOGPT_HOSTNAME 需要设置为宿主机的 IP 地址,否则小爱无法正常播放语音。
422
433
 
423
- ## 推荐的 fork
434
+ ## 推荐的类似项目
424
435
 
425
436
  - [XiaoBot](https://github.com/longbai/xiaobot) -> Go语言版本的Fork, 带支持不同平台的UI
437
+ - [MiGPT](https://github.com/idootop/mi-gpt) -> Node.js 版,支持流式响应和长短期记忆
426
438
 
427
439
  ## 感谢
428
440
 
@@ -306,9 +306,10 @@ docker run -v <your-config-dir>:/config -p 9527:9527 -e XIAOGPT_HOSTNAME=<your i
306
306
 
307
307
  注意端口必须映射为与容器内一致,XIAOGPT_HOSTNAME 需要设置为宿主机的 IP 地址,否则小爱无法正常播放语音。
308
308
 
309
- ## 推荐的 fork
309
+ ## 推荐的类似项目
310
310
 
311
311
  - [XiaoBot](https://github.com/longbai/xiaobot) -> Go语言版本的Fork, 带支持不同平台的UI
312
+ - [MiGPT](https://github.com/idootop/mi-gpt) -> Node.js 版,支持流式响应和长短期记忆
312
313
 
313
314
  ## 感谢
314
315
 
@@ -28,9 +28,10 @@ dependencies = [
28
28
  "groq>=0.5.0",
29
29
  "pyyaml>=6.0.1",
30
30
  "langchain-community>=0.0.38",
31
+ "lingua-language-detector>=2.0.2; python_version < \"3.13\"",
31
32
  ]
32
33
  dynamic = []
33
- version = "2.83"
34
+ version = "2.90"
34
35
 
35
36
  [project.license]
36
37
  text = "MIT"
@@ -56,24 +57,25 @@ locked = [
56
57
  "charset-normalizer==3.3.2",
57
58
  "click==8.1.7",
58
59
  "colorama==0.4.6 ; platform_system == \"Windows\"",
59
- "dashscope==1.19.1",
60
+ "dashscope==1.20.1",
60
61
  "dataclasses-json==0.6.3",
61
62
  "distro==1.9.0",
62
63
  "edge-tts==6.1.10",
64
+ "et-xmlfile==1.1.0 ; python_version ~= \"3.8\" and python_full_version != \"3.9.7\"",
63
65
  "exceptiongroup==1.2.0 ; python_version < \"3.11\"",
64
66
  "frozenlist==1.4.1",
65
- "google-ai-generativelanguage==0.6.4",
67
+ "google-ai-generativelanguage==0.6.6",
66
68
  "google-api-core==2.15.0",
67
69
  "google-api-core[grpc]==2.15.0",
68
70
  "google-api-python-client==2.125.0",
69
71
  "google-auth==2.26.1",
70
72
  "google-auth-httplib2==0.2.0",
71
73
  "google-cloud-texttospeech==2.16.3",
72
- "google-generativeai==0.5.4",
74
+ "google-generativeai==0.7.1",
73
75
  "google-search-results==2.4.2",
74
76
  "googleapis-common-protos==1.62.0",
75
77
  "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\"",
76
- "groq==0.6.0",
78
+ "groq==0.9.0",
77
79
  "grpcio==1.60.0",
78
80
  "grpcio-status==1.60.0",
79
81
  "h11==0.14.0",
@@ -84,49 +86,58 @@ locked = [
84
86
  "idna==3.7",
85
87
  "jsonpatch==1.33",
86
88
  "jsonpointer==2.4",
87
- "langchain==0.2.0",
88
- "langchain-community==0.2.0",
89
- "langchain-core==0.2.0",
89
+ "langchain==0.2.6",
90
+ "langchain-community==0.2.6",
91
+ "langchain-core==0.2.11",
90
92
  "langchain-text-splitters==0.2.0",
91
- "langsmith==0.1.45",
93
+ "langsmith==0.1.84",
94
+ "lingua-language-detector==2.0.2 ; python_version < \"3.13\"",
92
95
  "markdown-it-py==3.0.0",
93
96
  "marshmallow==3.20.1",
94
97
  "mdurl==0.1.2",
95
- "miservice-fork==2.5.0",
98
+ "miservice-fork==2.7.0",
96
99
  "multidict==6.0.5",
97
100
  "mutagen==1.47.0",
98
101
  "mypy-extensions==1.0.0",
99
- "numexpr==2.10.0",
102
+ "numexpr==2.10.1",
100
103
  "numpy==1.26.3",
101
- "openai==1.30.1",
104
+ "openai==1.35.10",
105
+ "openpyxl==3.1.5 ; python_version ~= \"3.8\" and python_full_version != \"3.9.7\"",
102
106
  "orjson==3.10.0",
103
107
  "packaging==23.2",
108
+ "pandas==2.2.2 ; python_version ~= \"3.8\" and python_full_version != \"3.9.7\"",
104
109
  "proto-plus==1.23.0",
105
110
  "protobuf==4.25.1",
106
111
  "pyasn1==0.5.1",
107
112
  "pyasn1-modules==0.3.0",
108
- "pydantic==2.5.3",
109
- "pydantic-core==2.14.6",
113
+ "pydantic==2.8.2",
114
+ "pydantic-core==2.20.1",
110
115
  "pygments==2.17.2",
111
116
  "pyjwt==2.8.0",
112
117
  "pyparsing==3.1.2 ; python_version > \"3.0\"",
118
+ "python-dateutil==2.9.0.post0 ; python_version ~= \"3.8\" and python_full_version != \"3.9.7\"",
119
+ "pytz==2024.1 ; python_version ~= \"3.8\" and python_full_version != \"3.9.7\"",
113
120
  "pyyaml==6.0.1",
114
121
  "requests==2.31.0",
115
122
  "rich==13.7.1",
116
123
  "rsa==4.9",
124
+ "six==1.16.0 ; python_version ~= \"3.8\" and python_full_version != \"3.9.7\"",
117
125
  "sniffio==1.3.0",
118
126
  "socksio==1.0.0",
119
127
  "soupsieve==2.5",
120
128
  "sqlalchemy==2.0.25",
121
129
  "tenacity==8.2.3",
122
- "tetos==0.2.1",
130
+ "tetos==0.3.0",
123
131
  "tqdm==4.66.1",
124
- "typing-extensions==4.9.0",
132
+ "typing-extensions==4.12.2",
125
133
  "typing-inspect==0.9.0",
134
+ "tzdata==2024.1 ; python_version ~= \"3.8\" and python_full_version != \"3.9.7\"",
126
135
  "uritemplate==4.1.1",
127
136
  "urllib3==2.1.0",
137
+ "websocket-client==1.8.0",
138
+ "websockets==12.0",
128
139
  "yarl==1.9.4",
129
- "zhipuai==2.0.1.20240423.1",
140
+ "zhipuai==2.1.2",
130
141
  ]
131
142
 
132
143
  [tool.pdm]
@@ -5,11 +5,14 @@ import os
5
5
  import re
6
6
  import socket
7
7
  from http.cookies import SimpleCookie
8
- from typing import AsyncIterator
8
+ from typing import TYPE_CHECKING, AsyncIterator
9
9
  from urllib.parse import urlparse
10
10
 
11
11
  from requests.utils import cookiejar_from_dict
12
12
 
13
+ if TYPE_CHECKING:
14
+ from lingua import LanguageDetector
15
+
13
16
 
14
17
  ### HELP FUNCTION ###
15
18
  def parse_cookie_string(cookie_string):
@@ -69,3 +72,21 @@ def get_hostname() -> str:
69
72
  with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
70
73
  s.connect(("8.8.8.8", 80))
71
74
  return s.getsockname()[0]
75
+
76
+
77
+ def _get_detector() -> LanguageDetector | None:
78
+ try:
79
+ from lingua import LanguageDetectorBuilder
80
+ except ImportError:
81
+ return None
82
+ return LanguageDetectorBuilder.from_all_spoken_languages().build()
83
+
84
+
85
+ _detector = _get_detector()
86
+
87
+
88
+ def detect_language(text: str) -> str:
89
+ if _detector is None:
90
+ return "zh" # default to Chinese if langdetect module is not available
91
+ lang = _detector.detect_language_of(text)
92
+ return lang.iso_code_639_1.name.lower() if lang is not None else "zh"
@@ -24,9 +24,7 @@ from xiaogpt.config import (
24
24
  Config,
25
25
  )
26
26
  from xiaogpt.tts import TTS, MiTTS, TetosTTS
27
- from xiaogpt.utils import (
28
- parse_cookie_string,
29
- )
27
+ from xiaogpt.utils import detect_language, parse_cookie_string
30
28
 
31
29
  EOF = object()
32
30
 
@@ -390,11 +388,6 @@ class MiGPT:
390
388
  query = f"{query},{self.config.prompt}"
391
389
  # some model can not detect the language code, so we need to add it
392
390
 
393
- if self.config.tts != "mi": # mi only say Chinese
394
- query += (
395
- ",并用本段话的language code作为开头,用|分隔,如:en-US|你好……"
396
- )
397
-
398
391
  if self.config.mute_xiaoai:
399
392
  await self.stop_if_xiaoai_is_playing()
400
393
  else:
@@ -420,18 +413,11 @@ class MiGPT:
420
413
  await self.wakeup_xiaoai()
421
414
 
422
415
  async def speak(self, text_stream: AsyncIterator[str]) -> None:
423
- text = await text_stream.__anext__()
424
- # See if the first part contains language code(e.g. en-US|Hello world)
425
- lang, _, first_chunk = text.rpartition("|")
426
- if len(lang) > 7:
427
- # It is not a legal language code, discard it
428
- lang, first_chunk = "", text
429
-
430
- lang = (
431
- matches[0]
432
- if (matches := re.findall(r"([a-z]{2}-[A-Z]{2})", lang))
433
- else "zh-CN"
434
- )
416
+ first_chunk = await text_stream.__anext__()
417
+ # Detect the language from the first chunk
418
+ # Add suffix '-' because tetos expects it to exist when selecting voices
419
+ # however, the nation code is never used.
420
+ lang = detect_language(first_chunk) + "-"
435
421
 
436
422
  async def gen(): # reconstruct the generator
437
423
  yield first_chunk
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