chattool 5.3.0__tar.gz → 5.4.0__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.
- {chattool-5.3.0/src/chattool.egg-info → chattool-5.4.0}/PKG-INFO +37 -9
- {chattool-5.3.0 → chattool-5.4.0}/README.md +21 -3
- {chattool-5.3.0 → chattool-5.4.0}/pyproject.toml +17 -4
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/__init__.py +2 -2
- chattool-5.4.0/src/chattool/cli/__init__.py +11 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/cli/chatenv.py +194 -5
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/cli/client/__init__.py +8 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/cli/client/cert_client.py +4 -2
- chattool-5.4.0/src/chattool/cli/client/github.py +261 -0
- chattool-5.4.0/src/chattool/cli/client/image.py +265 -0
- chattool-5.4.0/src/chattool/cli/client/mcp.py +80 -0
- chattool-5.4.0/src/chattool/cli/client/network.py +197 -0
- chattool-5.4.0/src/chattool/cli/client/tplogin.py +331 -0
- chattool-5.4.0/src/chattool/cli/client/zulip.py +368 -0
- chattool-5.4.0/src/chattool/cli/main.py +87 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/cli/service/cert_server.py +3 -2
- chattool-5.4.0/src/chattool/cli/skill.py +206 -0
- chattool-5.4.0/src/chattool/config/__init__.py +25 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/config/elements.py +1 -1
- chattool-5.4.0/src/chattool/config/github.py +20 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/config/main.py +135 -0
- chattool-5.4.0/src/chattool/docker/__init__.py +3 -0
- chattool-5.4.0/src/chattool/docker/cli.py +26 -0
- chattool-5.4.0/src/chattool/docker/elements.py +111 -0
- chattool-5.4.0/src/chattool/docker/main.py +64 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/llm/chattype.py +7 -4
- chattool-5.4.0/src/chattool/mcp/catalog.py +48 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/mcp/server.py +5 -12
- chattool-5.4.0/src/chattool/serve/__init__.py +1 -0
- chattool-5.4.0/src/chattool/serve/chrome.py +84 -0
- chattool-5.4.0/src/chattool/setup/__init__.py +0 -0
- chattool-5.4.0/src/chattool/setup/chrome.py +148 -0
- chattool-5.4.0/src/chattool/setup/cli.py +4 -0
- chattool-5.4.0/src/chattool/setup/codex.py +72 -0
- chattool-5.4.0/src/chattool/setup/elements.py +83 -0
- chattool-5.4.0/src/chattool/setup/frp.py +224 -0
- chattool-5.4.0/src/chattool/setup/main.py +25 -0
- chattool-5.4.0/src/chattool/setup/nodejs.py +66 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/__init__.py +4 -2
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/cert/acme_dns_tiny.py +4 -4
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/cert/cert_updater.py +10 -5
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/dns/base.py +1 -1
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/dns/ip_updater.py +2 -2
- chattool-5.4.0/src/chattool/tools/github/__init__.py +3 -0
- chattool-5.3.0/src/chattool/tools/githubclient.py → chattool-5.4.0/src/chattool/tools/github/client.py +3 -8
- chattool-5.4.0/src/chattool/tools/image/__init__.py +40 -0
- chattool-5.4.0/src/chattool/tools/image/base.py +30 -0
- chattool-5.4.0/src/chattool/tools/image/huggingface.py +44 -0
- chattool-5.4.0/src/chattool/tools/image/liblib.py +150 -0
- chattool-5.4.0/src/chattool/tools/image/pollinations.py +56 -0
- chattool-5.4.0/src/chattool/tools/image/siliconflow.py +92 -0
- chattool-5.4.0/src/chattool/tools/image/tongyi.py +61 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/lark/bot.py +47 -29
- chattool-5.4.0/src/chattool/tools/network/link_check.py +168 -0
- chattool-5.4.0/src/chattool/tools/tplogin.py +242 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/zulip/client.py +13 -2
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/utils/basic.py +1 -1
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/utils/fastobj.py +6 -3
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/utils/httpclient.py +23 -17
- chattool-5.4.0/src/chattool/utils/tui.py +91 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/utils/urltool.py +6 -3
- {chattool-5.3.0 → chattool-5.4.0/src/chattool.egg-info}/PKG-INFO +37 -9
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool.egg-info/SOURCES.txt +33 -1
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool.egg-info/entry_points.txt +1 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool.egg-info/requires.txt +20 -6
- chattool-5.4.0/tests/test_import.py +5 -0
- chattool-5.3.0/src/chattool/cli/__init__.py +0 -5
- chattool-5.3.0/src/chattool/cli/client/mcp.py +0 -43
- chattool-5.3.0/src/chattool/cli/client/network.py +0 -49
- chattool-5.3.0/src/chattool/cli/main.py +0 -52
- chattool-5.3.0/src/chattool/config/__init__.py +0 -15
- chattool-5.3.0/tests/test_import.py +0 -1
- {chattool-5.3.0 → chattool-5.4.0}/LICENSE +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/setup.cfg +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/_all.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/application/kb/__init__.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/application/kb/cli.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/application/kb/ingest.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/application/kb/manager.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/application/kb/storage.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/cli/client/cert_updater.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/cli/client/dns_updater.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/cli/client/lark.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/cli/service/__init__.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/cli/service/capture.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/cli/service/lark_serve.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/cli/test_cmd.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/const.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/llm/__init__.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/llm/response.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/mcp/__init__.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/mcp/dns.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/mcp/network.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/mcp/zulip.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/cert/__init__.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/cert/cert_server.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/dns/__init__.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/dns/aliyun.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/dns/tencent.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/dns/utils.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/interact.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/lark/__init__.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/lark/context.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/lark/elements.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/lark/session.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/network/__init__.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/network/scanner.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/zulip/__init__.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/tools/zulip/legacy.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/utils/__init__.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool/utils/custom_logger.py +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool.egg-info/dependency_links.txt +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/src/chattool.egg-info/top_level.txt +0 -0
- {chattool-5.3.0 → chattool-5.4.0}/tests/test_chatenv.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chattool
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.4.0
|
|
4
4
|
Summary: Toolkit for Chat API
|
|
5
5
|
Author-email: Rex Wang <1073853456@qq.com>
|
|
6
6
|
License: MIT license
|
|
@@ -19,6 +19,7 @@ Requires-Python: >=3.9
|
|
|
19
19
|
Description-Content-Type: text/markdown
|
|
20
20
|
License-File: LICENSE
|
|
21
21
|
Requires-Dist: Click>=7.0
|
|
22
|
+
Requires-Dist: questionary>=2.1.0
|
|
22
23
|
Requires-Dist: requests>=2.20
|
|
23
24
|
Requires-Dist: aiohttp>=3.8
|
|
24
25
|
Requires-Dist: tqdm>=4.60
|
|
@@ -35,13 +36,22 @@ Requires-Dist: httpx
|
|
|
35
36
|
Requires-Dist: gitpython
|
|
36
37
|
Requires-Dist: PyGithub
|
|
37
38
|
Requires-Dist: filelock
|
|
39
|
+
Provides-Extra: dns
|
|
40
|
+
Requires-Dist: netifaces; extra == "dns"
|
|
41
|
+
Requires-Dist: alibabacloud_alidns20150109>=3.5.10; extra == "dns"
|
|
42
|
+
Requires-Dist: alibabacloud_tea_openapi>=0.3.0; extra == "dns"
|
|
43
|
+
Requires-Dist: tencentcloud-sdk-python; extra == "dns"
|
|
44
|
+
Provides-Extra: lark
|
|
45
|
+
Requires-Dist: lark-oapi==1.5.3; extra == "lark"
|
|
46
|
+
Requires-Dist: flask; extra == "lark"
|
|
47
|
+
Provides-Extra: images
|
|
48
|
+
Requires-Dist: dashscope; extra == "images"
|
|
49
|
+
Provides-Extra: screenshot
|
|
50
|
+
Requires-Dist: selenium; extra == "screenshot"
|
|
51
|
+
Requires-Dist: pillow; extra == "screenshot"
|
|
52
|
+
Requires-Dist: imageio; extra == "screenshot"
|
|
38
53
|
Provides-Extra: tools
|
|
39
|
-
Requires-Dist:
|
|
40
|
-
Requires-Dist: alibabacloud_tea_openapi>=0.3.0; extra == "tools"
|
|
41
|
-
Requires-Dist: tencentcloud-sdk-python; extra == "tools"
|
|
42
|
-
Requires-Dist: netifaces; extra == "tools"
|
|
43
|
-
Requires-Dist: lark-oapi==1.5.3; extra == "tools"
|
|
44
|
-
Requires-Dist: flask; extra == "tools"
|
|
54
|
+
Requires-Dist: chattool[dns,images,lark,screenshot]; extra == "tools"
|
|
45
55
|
Provides-Extra: tests
|
|
46
56
|
Requires-Dist: coverage; extra == "tests"
|
|
47
57
|
Requires-Dist: pytest>=3; extra == "tests"
|
|
@@ -197,14 +207,32 @@ chattool dns ddns -d example.com -r nas --ip-type local --local-ip-cidr 192.168.
|
|
|
197
207
|
chattool dns cert-update -d example.com -e admin@example.com --cert-dir ./certs
|
|
198
208
|
```
|
|
199
209
|
|
|
200
|
-
### 5.
|
|
210
|
+
### 5. AI 绘图 (`chattool image`)
|
|
211
|
+
|
|
212
|
+
支持 Tongyi、Hugging Face、LiblibAI、Pollinations.ai、SiliconFlow 等平台。
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
# 安装图像依赖
|
|
216
|
+
pip install "chattool[images]"
|
|
217
|
+
|
|
218
|
+
# Pollinations(需配置 POLLINATIONS_API_KEY)
|
|
219
|
+
chattool image pollinations list-models
|
|
220
|
+
chattool image pollinations generate "a cat in space" -o cat.png
|
|
221
|
+
|
|
222
|
+
# SiliconFlow(需配置 SILICONFLOW_API_KEY)
|
|
223
|
+
chattool image siliconflow list-models
|
|
224
|
+
chattool image siliconflow generate "a cute dog" -o dog.png
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### 6. 其他工具
|
|
201
228
|
|
|
202
229
|
| 工具 | 命令 | 说明 |
|
|
203
230
|
|------|------|------|
|
|
204
231
|
| 网络扫描 | `chattool network scan` | 扫描局域网活跃主机和 SSH 端口 |
|
|
205
|
-
| MCP 服务 | `chattool mcp inspect` | MCP Server
|
|
232
|
+
| MCP 服务 | `chattool mcp info` / `chattool mcp inspect` | MCP Server 能力检查(支持 JSON 输出) |
|
|
206
233
|
| 截图服务 | `chattool serve capture` | 本地网页截图服务 |
|
|
207
234
|
| 证书分发 | `chattool serve cert` / `chattool client cert` | SSL 证书集中管理与客户端拉取 |
|
|
235
|
+
| Skills 管理 | `chattool skill install` / `chatskill install` | 安装 ChatTool skills 到 Codex / Claude Code |
|
|
208
236
|
|
|
209
237
|
## 开源协议
|
|
210
238
|
|
|
@@ -133,14 +133,32 @@ chattool dns ddns -d example.com -r nas --ip-type local --local-ip-cidr 192.168.
|
|
|
133
133
|
chattool dns cert-update -d example.com -e admin@example.com --cert-dir ./certs
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
-
### 5.
|
|
136
|
+
### 5. AI 绘图 (`chattool image`)
|
|
137
|
+
|
|
138
|
+
支持 Tongyi、Hugging Face、LiblibAI、Pollinations.ai、SiliconFlow 等平台。
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
# 安装图像依赖
|
|
142
|
+
pip install "chattool[images]"
|
|
143
|
+
|
|
144
|
+
# Pollinations(需配置 POLLINATIONS_API_KEY)
|
|
145
|
+
chattool image pollinations list-models
|
|
146
|
+
chattool image pollinations generate "a cat in space" -o cat.png
|
|
147
|
+
|
|
148
|
+
# SiliconFlow(需配置 SILICONFLOW_API_KEY)
|
|
149
|
+
chattool image siliconflow list-models
|
|
150
|
+
chattool image siliconflow generate "a cute dog" -o dog.png
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 6. 其他工具
|
|
137
154
|
|
|
138
155
|
| 工具 | 命令 | 说明 |
|
|
139
156
|
|------|------|------|
|
|
140
157
|
| 网络扫描 | `chattool network scan` | 扫描局域网活跃主机和 SSH 端口 |
|
|
141
|
-
| MCP 服务 | `chattool mcp inspect` | MCP Server
|
|
158
|
+
| MCP 服务 | `chattool mcp info` / `chattool mcp inspect` | MCP Server 能力检查(支持 JSON 输出) |
|
|
142
159
|
| 截图服务 | `chattool serve capture` | 本地网页截图服务 |
|
|
143
160
|
| 证书分发 | `chattool serve cert` / `chattool client cert` | SSL 证书集中管理与客户端拉取 |
|
|
161
|
+
| Skills 管理 | `chattool skill install` / `chatskill install` | 安装 ChatTool skills 到 Codex / Claude Code |
|
|
144
162
|
|
|
145
163
|
## 开源协议
|
|
146
164
|
|
|
@@ -151,4 +169,4 @@ MIT License
|
|
|
151
169
|
- `5.3.0` — 飞书机器人(消息收发、事件路由、AI 对话)、CLI 工具链(`chattool lark`、`chattool serve lark`)
|
|
152
170
|
- `5.0.0` — DNS 管理(阿里云/腾讯云)、DDNS、SSL 证书自动续期、环境变量集中管理
|
|
153
171
|
- `4.1.0` — 统一 `Chat` API(同步/异步/流式),默认环境变量配置
|
|
154
|
-
- 更早版本请参考仓库提交记录
|
|
172
|
+
- 更早版本请参考仓库提交记录
|
|
@@ -25,6 +25,7 @@ keywords = ["chattool"]
|
|
|
25
25
|
license = {text = "MIT license"}
|
|
26
26
|
dependencies = [
|
|
27
27
|
"Click>=7.0",
|
|
28
|
+
"questionary>=2.1.0",
|
|
28
29
|
"requests>=2.20",
|
|
29
30
|
"aiohttp>=3.8",
|
|
30
31
|
"tqdm>=4.60",
|
|
@@ -45,14 +46,27 @@ dependencies = [
|
|
|
45
46
|
]
|
|
46
47
|
|
|
47
48
|
[project.optional-dependencies]
|
|
48
|
-
|
|
49
|
+
dns = [
|
|
50
|
+
"netifaces",
|
|
49
51
|
"alibabacloud_alidns20150109>=3.5.10",
|
|
50
52
|
"alibabacloud_tea_openapi>=0.3.0",
|
|
51
53
|
"tencentcloud-sdk-python",
|
|
52
|
-
|
|
54
|
+
]
|
|
55
|
+
lark = [
|
|
53
56
|
"lark-oapi==1.5.3",
|
|
54
57
|
"flask",
|
|
55
58
|
]
|
|
59
|
+
images = [
|
|
60
|
+
"dashscope"
|
|
61
|
+
]
|
|
62
|
+
screenshot = [
|
|
63
|
+
"selenium",
|
|
64
|
+
"pillow",
|
|
65
|
+
"imageio"
|
|
66
|
+
]
|
|
67
|
+
tools = [
|
|
68
|
+
"chattool[dns, lark, images, screenshot]",
|
|
69
|
+
]
|
|
56
70
|
tests = [
|
|
57
71
|
"coverage",
|
|
58
72
|
"pytest>=3",
|
|
@@ -74,7 +88,6 @@ dev = [
|
|
|
74
88
|
"twine",
|
|
75
89
|
"chattool[docs,tests,tools]",
|
|
76
90
|
]
|
|
77
|
-
|
|
78
91
|
[project.urls]
|
|
79
92
|
Homepage = "https://github.com/cubenlp/chattool"
|
|
80
93
|
Repository = "https://github.com/cubenlp/chattool"
|
|
@@ -83,6 +96,7 @@ Repository = "https://github.com/cubenlp/chattool"
|
|
|
83
96
|
chattool = "chattool.cli:main_cli"
|
|
84
97
|
chatenv = "chattool.cli.chatenv:cli"
|
|
85
98
|
mcp-server-chattool = "chattool.mcp:main"
|
|
99
|
+
chatskill = "chattool.cli.skill:main"
|
|
86
100
|
|
|
87
101
|
[tool.setuptools.dynamic]
|
|
88
102
|
version = {attr = "chattool.__version__"}
|
|
@@ -107,4 +121,3 @@ filterwarnings = [
|
|
|
107
121
|
"ignore:websockets.legacy is deprecated:DeprecationWarning",
|
|
108
122
|
"ignore:websockets.server.WebSocketServerProtocol is deprecated:DeprecationWarning"
|
|
109
123
|
]
|
|
110
|
-
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
__author__ = """Rex Wang"""
|
|
4
4
|
__email__ = '1073853456@qq.com'
|
|
5
|
-
__version__ = '5.
|
|
5
|
+
__version__ = '5.4.0'
|
|
6
6
|
|
|
7
7
|
from dotenv import load_dotenv
|
|
8
8
|
|
|
@@ -40,4 +40,4 @@ __all__ = [
|
|
|
40
40
|
"TencentDNSClient",
|
|
41
41
|
"DynamicIPUpdater",
|
|
42
42
|
"SSLCertUpdater",
|
|
43
|
-
]
|
|
43
|
+
]
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import click
|
|
2
2
|
import shutil
|
|
3
3
|
import os
|
|
4
|
+
import sys
|
|
5
|
+
import warnings
|
|
6
|
+
warnings.filterwarnings("ignore", message=".*pkg_resources is deprecated.*")
|
|
7
|
+
# Filter DeprecationWarning from lark_oapi (asyncio.get_event_loop)
|
|
8
|
+
warnings.filterwarnings("ignore", category=DeprecationWarning, module="lark_oapi.*")
|
|
4
9
|
|
|
5
10
|
from chattool.config import BaseEnvConfig
|
|
6
11
|
from chattool.const import CHATTOOL_ENV_FILE, CHATTOOL_ENV_DIR
|
|
7
12
|
from chattool import __version__
|
|
8
13
|
from chattool.utils import mask_secret
|
|
14
|
+
from chattool.utils.tui import (
|
|
15
|
+
ask_select, ask_text, ask_confirm, get_separator,
|
|
16
|
+
create_choice, is_interactive_available, BACK_VALUE
|
|
17
|
+
)
|
|
9
18
|
|
|
10
19
|
from .test_cmd import test_cmd
|
|
11
20
|
|
|
@@ -31,13 +40,141 @@ def _resolve_config_types(config_types):
|
|
|
31
40
|
if not config_types:
|
|
32
41
|
return None
|
|
33
42
|
normalized = [t.lower() for t in config_types]
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
|
|
44
|
+
matched = []
|
|
45
|
+
|
|
46
|
+
for cls in BaseEnvConfig._registry:
|
|
47
|
+
is_match = False
|
|
48
|
+
|
|
49
|
+
for t in normalized:
|
|
50
|
+
# Check title (case-insensitive prefix)
|
|
51
|
+
if cls._title.lower().startswith(t):
|
|
52
|
+
is_match = True
|
|
53
|
+
|
|
54
|
+
# Check aliases (case-insensitive prefix)
|
|
55
|
+
if not is_match:
|
|
56
|
+
aliases = getattr(cls, '_aliases', [])
|
|
57
|
+
for alias in aliases:
|
|
58
|
+
if alias.lower().startswith(t):
|
|
59
|
+
is_match = True
|
|
60
|
+
break
|
|
61
|
+
|
|
62
|
+
if is_match:
|
|
63
|
+
break
|
|
64
|
+
|
|
65
|
+
if is_match:
|
|
66
|
+
matched.append(cls)
|
|
67
|
+
|
|
39
68
|
return matched
|
|
40
69
|
|
|
70
|
+
def _group_configs(configs):
|
|
71
|
+
groups = {
|
|
72
|
+
"Model": [],
|
|
73
|
+
"DNS": [],
|
|
74
|
+
"Image": [],
|
|
75
|
+
"Other": [],
|
|
76
|
+
}
|
|
77
|
+
for cfg in configs:
|
|
78
|
+
name = cfg.__name__
|
|
79
|
+
if name in ("OpenAIConfig", "AzureConfig", "SiliconFlowConfig"):
|
|
80
|
+
groups["Model"].append(cfg)
|
|
81
|
+
elif name in ("AliyunConfig", "TencentConfig"):
|
|
82
|
+
groups["DNS"].append(cfg)
|
|
83
|
+
elif name in ("TongyiConfig", "HuggingFaceConfig", "PollinationsConfig", "LiblibConfig"):
|
|
84
|
+
groups["Image"].append(cfg)
|
|
85
|
+
else:
|
|
86
|
+
groups["Other"].append(cfg)
|
|
87
|
+
return groups
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _configure_provider(config_cls):
|
|
91
|
+
"""Interactively configure a single provider."""
|
|
92
|
+
click.echo(f"\nConfiguring {config_cls._title}...")
|
|
93
|
+
for name, field in config_cls.get_fields().items():
|
|
94
|
+
prompt_text = f"{name}"
|
|
95
|
+
if field.desc:
|
|
96
|
+
prompt_text += f" ({field.desc})"
|
|
97
|
+
|
|
98
|
+
default_val = field.value if field.value is not None else field.default
|
|
99
|
+
|
|
100
|
+
if field.is_sensitive:
|
|
101
|
+
hint = mask_secret(default_val) if default_val else ""
|
|
102
|
+
message = f"{prompt_text}"
|
|
103
|
+
if hint:
|
|
104
|
+
message += f" [current: {hint}]"
|
|
105
|
+
message += " (leave blank to keep current)"
|
|
106
|
+
|
|
107
|
+
new_val = ask_text(message, password=True)
|
|
108
|
+
if new_val == BACK_VALUE:
|
|
109
|
+
return
|
|
110
|
+
if new_val:
|
|
111
|
+
field.value = new_val
|
|
112
|
+
else:
|
|
113
|
+
new_val = ask_text(
|
|
114
|
+
prompt_text,
|
|
115
|
+
default=str(default_val) if default_val is not None else ""
|
|
116
|
+
)
|
|
117
|
+
if new_val == BACK_VALUE:
|
|
118
|
+
return
|
|
119
|
+
if new_val:
|
|
120
|
+
field.value = new_val
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _interactive_config_loop(grouped_configs):
|
|
124
|
+
"""Main loop for interactive configuration using questionary."""
|
|
125
|
+
while True:
|
|
126
|
+
# Main Menu
|
|
127
|
+
main_choices = []
|
|
128
|
+
for section, configs in grouped_configs.items():
|
|
129
|
+
if configs:
|
|
130
|
+
main_choices.append(section)
|
|
131
|
+
|
|
132
|
+
main_choices.append(get_separator())
|
|
133
|
+
main_choices.append("Save & Exit")
|
|
134
|
+
main_choices.append("Exit without Saving")
|
|
135
|
+
|
|
136
|
+
selected_section = ask_select(
|
|
137
|
+
"Select a category to configure (Arrow keys to move, Enter to select):",
|
|
138
|
+
choices=main_choices
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
if selected_section == "Save & Exit":
|
|
142
|
+
BaseEnvConfig.save_env_file(str(CHATTOOL_ENV_FILE), __version__)
|
|
143
|
+
click.echo(f"Configuration saved to {CHATTOOL_ENV_FILE}")
|
|
144
|
+
break
|
|
145
|
+
elif selected_section == "Exit without Saving":
|
|
146
|
+
if ask_confirm("Are you sure you want to exit without saving changes?", default=False):
|
|
147
|
+
break
|
|
148
|
+
continue
|
|
149
|
+
elif selected_section == BACK_VALUE:
|
|
150
|
+
continue
|
|
151
|
+
|
|
152
|
+
# Sub Menu
|
|
153
|
+
while True:
|
|
154
|
+
configs = grouped_configs[selected_section]
|
|
155
|
+
sub_choices = []
|
|
156
|
+
for cfg in configs:
|
|
157
|
+
aliases = getattr(cfg, '_aliases', [])
|
|
158
|
+
alias_text = f" ({', '.join(aliases)})" if aliases else ""
|
|
159
|
+
sub_choices.append(create_choice(
|
|
160
|
+
title=f"{cfg._title}{alias_text}",
|
|
161
|
+
value=cfg
|
|
162
|
+
))
|
|
163
|
+
|
|
164
|
+
sub_choices.append(get_separator())
|
|
165
|
+
sub_choices.append(create_choice(title="Back", value="Back"))
|
|
166
|
+
|
|
167
|
+
selected_config = ask_select(
|
|
168
|
+
f"[{selected_section}] Select a provider to configure (Esc to back):",
|
|
169
|
+
choices=sub_choices
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
if selected_config == "Back" or selected_config == BACK_VALUE:
|
|
173
|
+
break
|
|
174
|
+
|
|
175
|
+
# Configure Provider
|
|
176
|
+
_configure_provider(selected_config)
|
|
177
|
+
|
|
41
178
|
|
|
42
179
|
@cli.command(name='cat')
|
|
43
180
|
@click.argument('name', required=False)
|
|
@@ -179,6 +316,11 @@ def init(interactive, config_types):
|
|
|
179
316
|
- Tencent: tencent, tx, tencent-dns
|
|
180
317
|
- Zulip: zulip
|
|
181
318
|
- Feishu: feishu, lark
|
|
319
|
+
- Tongyi: tongyi, dashscope
|
|
320
|
+
- HuggingFace: hf, huggingface
|
|
321
|
+
- Pollinations: pollinations, poll
|
|
322
|
+
- Liblib: liblib
|
|
323
|
+
- SiliconFlow: siliconflow (Model & Image)
|
|
182
324
|
"""
|
|
183
325
|
|
|
184
326
|
target_configs = BaseEnvConfig._registry
|
|
@@ -197,8 +339,55 @@ def init(interactive, config_types):
|
|
|
197
339
|
if CHATTOOL_ENV_FILE.exists():
|
|
198
340
|
BaseEnvConfig.load_all(CHATTOOL_ENV_FILE)
|
|
199
341
|
|
|
342
|
+
if not interactive:
|
|
343
|
+
interactive = True
|
|
344
|
+
|
|
200
345
|
if interactive:
|
|
201
346
|
click.echo("Starting interactive configuration...")
|
|
347
|
+
use_questionary = is_interactive_available()
|
|
348
|
+
|
|
349
|
+
if use_questionary:
|
|
350
|
+
if not config_types:
|
|
351
|
+
grouped = _group_configs(target_configs)
|
|
352
|
+
_interactive_config_loop(grouped)
|
|
353
|
+
return
|
|
354
|
+
else:
|
|
355
|
+
# Linear config for specific types
|
|
356
|
+
for config_cls in target_configs:
|
|
357
|
+
_configure_provider(config_cls)
|
|
358
|
+
|
|
359
|
+
BaseEnvConfig.save_env_file(str(CHATTOOL_ENV_FILE), __version__)
|
|
360
|
+
click.echo(f"Configuration saved to {CHATTOOL_ENV_FILE}")
|
|
361
|
+
return
|
|
362
|
+
|
|
363
|
+
# Fallback for non-questionary environment (pure click)
|
|
364
|
+
if not config_types:
|
|
365
|
+
grouped = _group_configs(target_configs)
|
|
366
|
+
selected_sections = []
|
|
367
|
+
click.echo("\nSelect sections to configure:")
|
|
368
|
+
for section, configs in grouped.items():
|
|
369
|
+
if not configs:
|
|
370
|
+
continue
|
|
371
|
+
if click.confirm(section, default=section == "Model"):
|
|
372
|
+
selected_sections.append(section)
|
|
373
|
+
|
|
374
|
+
if not selected_sections:
|
|
375
|
+
click.echo("No section selected. Nothing to update.")
|
|
376
|
+
return
|
|
377
|
+
|
|
378
|
+
selected_configs = []
|
|
379
|
+
for section in selected_sections:
|
|
380
|
+
click.echo(f"\n[{section}]")
|
|
381
|
+
for config_cls in grouped[section]:
|
|
382
|
+
aliases = getattr(config_cls, '_aliases', [])
|
|
383
|
+
alias_text = f" ({', '.join(aliases)})" if aliases else ""
|
|
384
|
+
if click.confirm(f"Configure {config_cls._title}{alias_text}", default=False):
|
|
385
|
+
selected_configs.append(config_cls)
|
|
386
|
+
|
|
387
|
+
if not selected_configs:
|
|
388
|
+
click.echo("No provider selected. Nothing to update.")
|
|
389
|
+
return
|
|
390
|
+
target_configs = selected_configs
|
|
202
391
|
|
|
203
392
|
for config_cls in target_configs:
|
|
204
393
|
click.echo(f"\n[{config_cls._title}]")
|
|
@@ -4,6 +4,10 @@ from .dns_updater import cli as dns_updater_cli
|
|
|
4
4
|
from .mcp import cli as mcp_cli
|
|
5
5
|
from .network import network as network_cli
|
|
6
6
|
from .lark import cli as lark_cli
|
|
7
|
+
from .image import cli as image_cli
|
|
8
|
+
from .tplogin import cli as tplogin_cli
|
|
9
|
+
from .github import cli as github_cli
|
|
10
|
+
from .zulip import cli as zulip_cli
|
|
7
11
|
|
|
8
12
|
__all__ = [
|
|
9
13
|
"cert_client",
|
|
@@ -12,4 +16,8 @@ __all__ = [
|
|
|
12
16
|
"mcp_cli",
|
|
13
17
|
"network_cli",
|
|
14
18
|
"lark_cli",
|
|
19
|
+
"image_cli",
|
|
20
|
+
"tplogin_cli",
|
|
21
|
+
"github_cli",
|
|
22
|
+
"zulip_cli",
|
|
15
23
|
]
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import click
|
|
2
|
-
import requests
|
|
3
2
|
import os
|
|
4
|
-
import git
|
|
5
3
|
from rich.console import Console
|
|
6
4
|
from rich.table import Table
|
|
7
5
|
|
|
@@ -9,6 +7,7 @@ console = Console()
|
|
|
9
7
|
|
|
10
8
|
def get_git_email():
|
|
11
9
|
"""Get email from git config"""
|
|
10
|
+
import git
|
|
12
11
|
try:
|
|
13
12
|
email = git.Git().config("--get", "user.email")
|
|
14
13
|
if email:
|
|
@@ -44,6 +43,7 @@ def cert_client():
|
|
|
44
43
|
@common_options
|
|
45
44
|
def apply(server, token, domains, email, provider, secret_id, secret_key):
|
|
46
45
|
"""申请 SSL 证书"""
|
|
46
|
+
import requests
|
|
47
47
|
server, token = get_config(server, token)
|
|
48
48
|
headers = {"X-ChatTool-Token": token} if token else {}
|
|
49
49
|
|
|
@@ -77,6 +77,7 @@ def apply(server, token, domains, email, provider, secret_id, secret_key):
|
|
|
77
77
|
@common_options
|
|
78
78
|
def list_certs(server, token):
|
|
79
79
|
"""列出已申请的证书"""
|
|
80
|
+
import requests
|
|
80
81
|
server, token = get_config(server, token)
|
|
81
82
|
headers = {"X-ChatTool-Token": token} if token else {}
|
|
82
83
|
|
|
@@ -117,6 +118,7 @@ def list_certs(server, token):
|
|
|
117
118
|
@common_options
|
|
118
119
|
def download(server, token, domain, output_dir):
|
|
119
120
|
"""下载证书文件 (cert.pem, privkey.pem)"""
|
|
121
|
+
import requests
|
|
120
122
|
server, token = get_config(server, token)
|
|
121
123
|
headers = {"X-ChatTool-Token": token} if token else {}
|
|
122
124
|
|