zero-ai-cli 1.1.1__tar.gz → 1.1.2__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.
- {zero_ai_cli-1.1.1 → zero_ai_cli-1.1.2}/PKG-INFO +3 -2
- {zero_ai_cli-1.1.1 → zero_ai_cli-1.1.2}/README.md +1 -1
- {zero_ai_cli-1.1.1 → zero_ai_cli-1.1.2}/pyproject.toml +2 -1
- {zero_ai_cli-1.1.1 → zero_ai_cli-1.1.2}/tui_agent.py +221 -17
- {zero_ai_cli-1.1.1 → zero_ai_cli-1.1.2}/zero_ai_cli.egg-info/PKG-INFO +3 -2
- {zero_ai_cli-1.1.1 → zero_ai_cli-1.1.2}/zero_ai_cli.egg-info/requires.txt +1 -0
- {zero_ai_cli-1.1.1 → zero_ai_cli-1.1.2}/setup.cfg +0 -0
- {zero_ai_cli-1.1.1 → zero_ai_cli-1.1.2}/zero_ai_cli.egg-info/SOURCES.txt +0 -0
- {zero_ai_cli-1.1.1 → zero_ai_cli-1.1.2}/zero_ai_cli.egg-info/dependency_links.txt +0 -0
- {zero_ai_cli-1.1.1 → zero_ai_cli-1.1.2}/zero_ai_cli.egg-info/entry_points.txt +0 -0
- {zero_ai_cli-1.1.1 → zero_ai_cli-1.1.2}/zero_ai_cli.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: zero-ai-cli
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: ZeroAI - 终端 AI 编程助手(多专家协作·语音对话·文档生成·安全审计)
|
|
5
5
|
Author: ZeroAI Team
|
|
6
6
|
License: Proprietary
|
|
@@ -26,6 +26,7 @@ Requires-Dist: pyyaml>=6.0
|
|
|
26
26
|
Requires-Dist: requests>=2.28
|
|
27
27
|
Requires-Dist: matplotlib>=3.5
|
|
28
28
|
Requires-Dist: numpy>=1.20
|
|
29
|
+
Requires-Dist: asyncssh>=2.14
|
|
29
30
|
Provides-Extra: voice
|
|
30
31
|
Requires-Dist: sherpa-onnx>=1.9; extra == "voice"
|
|
31
32
|
Requires-Dist: faster-whisper>=0.9; extra == "voice"
|
|
@@ -45,7 +46,7 @@ Requires-Dist: build>=1.0; extra == "dev"
|
|
|
45
46
|
[](https://www.python.org/)
|
|
46
47
|
[]()
|
|
47
48
|
[]()
|
|
48
|
-
[](https://pypi.org/project/zero-ai-cli/)
|
|
49
50
|
|
|
50
51
|
</div>
|
|
51
52
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
[](https://www.python.org/)
|
|
10
10
|
[]()
|
|
11
11
|
[]()
|
|
12
|
-
[](https://pypi.org/project/zero-ai-cli/)
|
|
13
13
|
|
|
14
14
|
</div>
|
|
15
15
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "zero-ai-cli"
|
|
7
|
-
version = "1.1.
|
|
7
|
+
version = "1.1.2"
|
|
8
8
|
description = "ZeroAI - 终端 AI 编程助手(多专家协作·语音对话·文档生成·安全审计)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -35,6 +35,7 @@ dependencies = [
|
|
|
35
35
|
"requests>=2.28",
|
|
36
36
|
"matplotlib>=3.5",
|
|
37
37
|
"numpy>=1.20",
|
|
38
|
+
"asyncssh>=2.14",
|
|
38
39
|
]
|
|
39
40
|
|
|
40
41
|
[project.optional-dependencies]
|
|
@@ -21,6 +21,7 @@ import re
|
|
|
21
21
|
import asyncio
|
|
22
22
|
import shutil
|
|
23
23
|
import platform
|
|
24
|
+
import locale
|
|
24
25
|
import time
|
|
25
26
|
import base64
|
|
26
27
|
|
|
@@ -1509,9 +1510,13 @@ def run_command(command: str) -> str:
|
|
|
1509
1510
|
timeout = 120 if PERMISSION_LEVEL == "full" else 30
|
|
1510
1511
|
# 全权限:cwd 限制放开(不强制 WORK_DIR)
|
|
1511
1512
|
cwd = None if PERMISSION_LEVEL == "full" else WORK_DIR
|
|
1513
|
+
# encoding 使用本地默认(中文 Windows 为 GBK/cp936),errors='replace' 兜底
|
|
1514
|
+
# 避免某些命令(ipconfig/systeminfo/sc/netsh)输出非 UTF-8 时 UnicodeDecodeError
|
|
1512
1515
|
r = subprocess.run(command, shell=True, capture_output=True,
|
|
1513
|
-
text=True, timeout=timeout, cwd=cwd
|
|
1514
|
-
|
|
1516
|
+
text=True, timeout=timeout, cwd=cwd,
|
|
1517
|
+
encoding=locale.getpreferredencoding(False),
|
|
1518
|
+
errors="replace")
|
|
1519
|
+
out = (r.stdout or "") + (r.stderr or "")
|
|
1515
1520
|
# 全权限:返回更长(8000);受限:4000
|
|
1516
1521
|
max_out = 8000 if PERMISSION_LEVEL == "full" else 4000
|
|
1517
1522
|
return out.strip()[:max_out] if out.strip() else "(无输出)"
|
|
@@ -5578,6 +5583,21 @@ def _ssh_run_async(coro_factory):
|
|
|
5578
5583
|
return f"错误:{e}"
|
|
5579
5584
|
|
|
5580
5585
|
|
|
5586
|
+
def _ssh_is_conn_closed(conn) -> bool:
|
|
5587
|
+
"""统一判断 asyncssh 连接是否已关闭。
|
|
5588
|
+
兼容不同 asyncssh 版本:is_closed 可能是属性(旧版)或方法(新版 2.24+)。
|
|
5589
|
+
"""
|
|
5590
|
+
if conn is None:
|
|
5591
|
+
return True
|
|
5592
|
+
try:
|
|
5593
|
+
val = conn.is_closed
|
|
5594
|
+
if callable(val):
|
|
5595
|
+
val = val()
|
|
5596
|
+
return bool(val)
|
|
5597
|
+
except Exception:
|
|
5598
|
+
return True
|
|
5599
|
+
|
|
5600
|
+
|
|
5581
5601
|
def _ssh_audit(host: str, user: str, command: str, result_summary: str = ""):
|
|
5582
5602
|
"""记录SSH操作审计日志"""
|
|
5583
5603
|
import datetime
|
|
@@ -5659,7 +5679,7 @@ def ssh_connect(host: str, user: str, password: str = "", key_path: str = "",
|
|
|
5659
5679
|
if conn_id in _SSH_CONNECTIONS:
|
|
5660
5680
|
try:
|
|
5661
5681
|
old = _SSH_CONNECTIONS.pop(conn_id)
|
|
5662
|
-
if old.get("conn") and not old["conn"]
|
|
5682
|
+
if old.get("conn") and not _ssh_is_conn_closed(old["conn"]):
|
|
5663
5683
|
# asyncssh 的 close() 是同步方法
|
|
5664
5684
|
old["conn"].close()
|
|
5665
5685
|
except Exception:
|
|
@@ -5746,7 +5766,8 @@ def ssh_exec(command: str, conn_id: str = "default", timeout: int = 30,
|
|
|
5746
5766
|
|
|
5747
5767
|
conn_info = _SSH_CONNECTIONS[conn_id]
|
|
5748
5768
|
conn = conn_info["conn"]
|
|
5749
|
-
|
|
5769
|
+
# 兼容 asyncssh 不同版本:is_closed 可能是属性(旧版)或方法(新版 2.24+)
|
|
5770
|
+
if _ssh_is_conn_closed(conn):
|
|
5750
5771
|
_SSH_CONNECTIONS.pop(conn_id, None)
|
|
5751
5772
|
return f"错误:连接 '{conn_id}' 已断开,请重新调用 ssh_connect"
|
|
5752
5773
|
|
|
@@ -5760,8 +5781,11 @@ def ssh_exec(command: str, conn_id: str = "default", timeout: int = 30,
|
|
|
5760
5781
|
async def _exec():
|
|
5761
5782
|
try:
|
|
5762
5783
|
import asyncssh
|
|
5784
|
+
# encoding='utf-8', errors='replace' 兼容中文 Windows 的 GBK 输出
|
|
5785
|
+
# asyncssh 默认用 UTF-8 解码,Windows cmd 输出 GBK 会乱码或报错
|
|
5763
5786
|
result = await asyncio.wait_for(
|
|
5764
|
-
conn.run(command, check=False, timeout=timeout
|
|
5787
|
+
conn.run(command, check=False, timeout=timeout,
|
|
5788
|
+
encoding='utf-8', errors='replace'),
|
|
5765
5789
|
timeout=timeout + 5
|
|
5766
5790
|
)
|
|
5767
5791
|
return result
|
|
@@ -5825,7 +5849,7 @@ def ssh_upload(local_path: str, remote_path: str, conn_id: str = "default") -> s
|
|
|
5825
5849
|
|
|
5826
5850
|
conn_info = _SSH_CONNECTIONS[conn_id]
|
|
5827
5851
|
conn = conn_info["conn"]
|
|
5828
|
-
if conn
|
|
5852
|
+
if _ssh_is_conn_closed(conn):
|
|
5829
5853
|
_SSH_CONNECTIONS.pop(conn_id, None)
|
|
5830
5854
|
return f"错误:连接 '{conn_id}' 已断开,请重新连接"
|
|
5831
5855
|
|
|
@@ -5881,7 +5905,7 @@ def ssh_download(remote_path: str, local_path: str, conn_id: str = "default") ->
|
|
|
5881
5905
|
|
|
5882
5906
|
conn_info = _SSH_CONNECTIONS[conn_id]
|
|
5883
5907
|
conn = conn_info["conn"]
|
|
5884
|
-
if conn
|
|
5908
|
+
if _ssh_is_conn_closed(conn):
|
|
5885
5909
|
_SSH_CONNECTIONS.pop(conn_id, None)
|
|
5886
5910
|
return f"错误:连接 '{conn_id}' 已断开,请重新连接"
|
|
5887
5911
|
|
|
@@ -6058,7 +6082,7 @@ def ssh_list(conn_id: str = "") -> str:
|
|
|
6058
6082
|
return (f"连接ID: {conn_id}\n"
|
|
6059
6083
|
f" 主机: {info['host']}:{info.get('port', 22)}\n"
|
|
6060
6084
|
f" 用户: {info['user']}\n"
|
|
6061
|
-
f" 状态: {'已断开' if info['conn']
|
|
6085
|
+
f" 状态: {'已断开' if _ssh_is_conn_closed(info['conn']) else '已连接'}\n"
|
|
6062
6086
|
f" 连接时长: {uptime}秒")
|
|
6063
6087
|
|
|
6064
6088
|
# 列出所有连接
|
|
@@ -6069,7 +6093,7 @@ def ssh_list(conn_id: str = "") -> str:
|
|
|
6069
6093
|
import time
|
|
6070
6094
|
for cid, info in _SSH_CONNECTIONS.items():
|
|
6071
6095
|
uptime = int(time.time() - info.get("connected_at", 0))
|
|
6072
|
-
status = "✅" if not info["conn"]
|
|
6096
|
+
status = "✅" if not _ssh_is_conn_closed(info["conn"]) else "❌"
|
|
6073
6097
|
parts.append(f" {status} {cid}: {info['user']}@{info['host']}:{info.get('port', 22)} ({uptime}s)")
|
|
6074
6098
|
|
|
6075
6099
|
# 审计日志(最近20条)
|
|
@@ -6449,13 +6473,154 @@ def ssh_firewall_manage(action: str, port: int = 0, protocol: str = "tcp",
|
|
|
6449
6473
|
def ssh_health_check(conn_id: str = "default") -> str:
|
|
6450
6474
|
"""服务器一键健康体检(CPU/内存/磁盘/网络/负载/服务综合报告)。
|
|
6451
6475
|
|
|
6476
|
+
自动检测操作系统:Linux 用 uname/free/df/ss/systemctl/journalctl;
|
|
6477
|
+
Windows 用 PowerShell 的 Get-CimInstance/Get-Process/Get-Service 等。
|
|
6478
|
+
|
|
6452
6479
|
Args:
|
|
6453
6480
|
conn_id: SSH 连接ID
|
|
6454
6481
|
|
|
6455
6482
|
Returns:
|
|
6456
6483
|
健康体检报告(含异常项标注与建议)
|
|
6457
6484
|
"""
|
|
6458
|
-
|
|
6485
|
+
import re
|
|
6486
|
+
|
|
6487
|
+
# 第一步:检测操作系统(用 echo %OS% 或 uname 同时探测)
|
|
6488
|
+
# Windows 的 %OS% 会输出 Windows_NT,Linux 的 uname 会有 Linux 字样
|
|
6489
|
+
detect = ssh_exec("echo %OS% & uname -s 2>nul", conn_id=conn_id, timeout=10)
|
|
6490
|
+
is_windows = "Windows_NT" in detect
|
|
6491
|
+
|
|
6492
|
+
if is_windows:
|
|
6493
|
+
# Windows Server 体检:用 PowerShell 命令(避免 wmic 在 2025 已废弃的问题)
|
|
6494
|
+
# 用 cmd 调用 powershell,确保兼容性
|
|
6495
|
+
cmd = (
|
|
6496
|
+
'powershell -NoProfile -Command "'
|
|
6497
|
+
"Write-Output '=== 系统信息 ===';"
|
|
6498
|
+
"$os = Get-CimInstance Win32_OperatingSystem;"
|
|
6499
|
+
"Write-Output ($os.Caption + ' ' + $os.Version + ' Build ' + $os.BuildNumber);"
|
|
6500
|
+
"Write-Output ('开机时间: ' + $os.LastBootUpTime);"
|
|
6501
|
+
"Write-Output '';"
|
|
6502
|
+
"Write-Output '=== CPU 负载 ===';"
|
|
6503
|
+
"$cpu = Get-CimInstance Win32_Processor | Select-Object -First 1;"
|
|
6504
|
+
"Write-Output ('CPU负载: ' + $cpu.LoadPercentage + '%');"
|
|
6505
|
+
"Write-Output ('CPU核心数: ' + (Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors);"
|
|
6506
|
+
"Write-Output '';"
|
|
6507
|
+
"Write-Output '=== 内存 ===';"
|
|
6508
|
+
"$cs = Get-CimInstance Win32_ComputerSystem;"
|
|
6509
|
+
"$os2 = Get-CimInstance Win32_OperatingSystem;"
|
|
6510
|
+
"$totalGB = [math]::Round($cs.TotalPhysicalMemory/1GB, 1);"
|
|
6511
|
+
"$freeGB = [math]::Round($os2.FreePhysicalMemory/1MB, 1);"
|
|
6512
|
+
"$usedGB = [math]::Round($totalGB - $freeGB, 1);"
|
|
6513
|
+
"Write-Output ('总内存: ' + $totalGB + ' GB');"
|
|
6514
|
+
"Write-Output ('已用: ' + $usedGB + ' GB');"
|
|
6515
|
+
"Write-Output ('可用: ' + $freeGB + ' GB');"
|
|
6516
|
+
"Write-Output '';"
|
|
6517
|
+
"Write-Output '=== 磁盘 ===';"
|
|
6518
|
+
"Get-CimInstance Win32_LogicalDisk -Filter 'DriveType=3' | ForEach-Object {"
|
|
6519
|
+
" $totalD = [math]::Round($_.Size/1GB, 1);"
|
|
6520
|
+
" $freeD = [math]::Round($_.FreeSpace/1GB, 1);"
|
|
6521
|
+
" $usedPct = if ($totalD -gt 0) { [math]::Round(($totalD - $freeD) / $totalD * 100, 1) } else { 0 };"
|
|
6522
|
+
" Write-Output ($_.DeviceID + ' 总:' + $totalD + 'GB 可用:' + $freeD + 'GB 使用:' + $usedPct + '%')"
|
|
6523
|
+
"};"
|
|
6524
|
+
"Write-Output '';"
|
|
6525
|
+
"Write-Output '=== 监听端口数 ===';"
|
|
6526
|
+
"$ports = (Get-NetTCPConnection -State Listen -ErrorAction SilentlyContinue | Measure-Object).Count;"
|
|
6527
|
+
"Write-Output ('监听端口数: ' + $ports);"
|
|
6528
|
+
"Write-Output '';"
|
|
6529
|
+
"Write-Output '=== 进程数 ===';"
|
|
6530
|
+
"$procs = (Get-Process | Measure-Object).Count;"
|
|
6531
|
+
"Write-Output ('进程数: ' + $procs);"
|
|
6532
|
+
"Write-Output '';"
|
|
6533
|
+
"Write-Output '=== 运行中的服务数 ===';"
|
|
6534
|
+
"$svc = (Get-Service | Where-Object {$_.Status -eq 'Running'} | Measure-Object).Count;"
|
|
6535
|
+
"Write-Output ('运行中服务: ' + $svc);"
|
|
6536
|
+
"Write-Output '';"
|
|
6537
|
+
"Write-Output '=== 防火墙状态 ===';"
|
|
6538
|
+
"Get-NetFirewallProfile | ForEach-Object { Write-Output ($_.Name + ': ' + $_.Enabled) };"
|
|
6539
|
+
"Write-Output '';"
|
|
6540
|
+
"Write-Output '=== 高内存进程Top5 ===';"
|
|
6541
|
+
"Get-Process | Sort-Object WorkingSet64 -Descending | Select-Object -First 5 | ForEach-Object {"
|
|
6542
|
+
" $memMB = [math]::Round($_.WorkingSet64/1MB, 0);"
|
|
6543
|
+
" Write-Output ($_.Name + ' (PID:' + $_.Id + ') 内存:' + $memMB + 'MB')"
|
|
6544
|
+
"}"
|
|
6545
|
+
'"'
|
|
6546
|
+
)
|
|
6547
|
+
raw = ssh_exec(cmd, conn_id=conn_id, timeout=60)
|
|
6548
|
+
if raw.startswith("错误") or raw.startswith("连接失败"):
|
|
6549
|
+
return raw
|
|
6550
|
+
|
|
6551
|
+
# Windows 分析
|
|
6552
|
+
issues = []
|
|
6553
|
+
|
|
6554
|
+
# CPU 负载
|
|
6555
|
+
m = re.search(r"CPU负载:\s*(\d+)%", raw)
|
|
6556
|
+
if m:
|
|
6557
|
+
cpu_pct = int(m.group(1))
|
|
6558
|
+
if cpu_pct >= 90:
|
|
6559
|
+
issues.append(f"⚠️ CPU 负载极高: {cpu_pct}%")
|
|
6560
|
+
elif cpu_pct >= 70:
|
|
6561
|
+
issues.append(f"⚠️ CPU 负载偏高: {cpu_pct}%")
|
|
6562
|
+
else:
|
|
6563
|
+
pass # 正常不记录
|
|
6564
|
+
|
|
6565
|
+
# 内存
|
|
6566
|
+
m_total = re.search(r"总内存:\s*([\d.]+)\s*GB", raw)
|
|
6567
|
+
m_used = re.search(r"已用:\s*([\d.]+)\s*GB", raw)
|
|
6568
|
+
if m_total and m_used:
|
|
6569
|
+
total = float(m_total.group(1))
|
|
6570
|
+
used = float(m_used.group(1))
|
|
6571
|
+
if total > 0:
|
|
6572
|
+
pct = used / total * 100
|
|
6573
|
+
if pct >= 90:
|
|
6574
|
+
issues.append(f"⚠️ 内存使用率 {pct:.1f}%(危急)")
|
|
6575
|
+
elif pct >= 80:
|
|
6576
|
+
issues.append(f"⚠️ 内存使用率 {pct:.1f}%(警告)")
|
|
6577
|
+
|
|
6578
|
+
# 磁盘
|
|
6579
|
+
for line in raw.split("\n"):
|
|
6580
|
+
m = re.search(r"([A-Z]:)\s*总:([\d.]+)GB\s*可用:([\d.]+)GB\s*使用:([\d.]+)%", line)
|
|
6581
|
+
if m:
|
|
6582
|
+
drive, total, free, pct = m.group(1), float(m.group(2)), float(m.group(3)), float(m.group(4))
|
|
6583
|
+
if pct >= 90:
|
|
6584
|
+
issues.append(f"⚠️ 磁盘 {drive} 使用率 {pct}%(危急)")
|
|
6585
|
+
elif pct >= 80:
|
|
6586
|
+
issues.append(f"⚠️ 磁盘 {drive} 使用率 {pct}%(警告)")
|
|
6587
|
+
|
|
6588
|
+
# 防火墙
|
|
6589
|
+
for line in raw.split("\n"):
|
|
6590
|
+
if "False" in line and ("Domain" in line or "Private" in line or "Public" in line):
|
|
6591
|
+
issues.append(f"⚠️ 防火墙关闭: {line.strip()}")
|
|
6592
|
+
|
|
6593
|
+
# 开机时间(判断是否长期未重启)
|
|
6594
|
+
m_boot = re.search(r"开机时间:\s*(.+)", raw)
|
|
6595
|
+
if m_boot:
|
|
6596
|
+
try:
|
|
6597
|
+
from datetime import datetime
|
|
6598
|
+
boot_str = m_boot.group(1).strip()
|
|
6599
|
+
# Windows PowerShell 输出格式可能多样,尝试解析
|
|
6600
|
+
for fmt in ("%m/%d/%Y %H:%M:%S", "%Y-%m-%d %H:%M:%S", "%m/%d/%Y %I:%M:%S %p"):
|
|
6601
|
+
try:
|
|
6602
|
+
boot_time = datetime.strptime(boot_str, fmt)
|
|
6603
|
+
days = (datetime.now() - boot_time).days
|
|
6604
|
+
if days > 90:
|
|
6605
|
+
issues.append(f"💡 服务器已运行 {days} 天,建议定期重启")
|
|
6606
|
+
break
|
|
6607
|
+
except ValueError:
|
|
6608
|
+
continue
|
|
6609
|
+
except Exception:
|
|
6610
|
+
pass
|
|
6611
|
+
|
|
6612
|
+
report = f"$ Windows 综合体检命令\n{raw}\n\n"
|
|
6613
|
+
report += "=== 健康分析 ===\n"
|
|
6614
|
+
if not issues:
|
|
6615
|
+
report += "✅ 服务器整体健康,未发现异常"
|
|
6616
|
+
else:
|
|
6617
|
+
report += f"发现 {len(issues)} 个问题:\n"
|
|
6618
|
+
for i, issue in enumerate(issues, 1):
|
|
6619
|
+
report += f" {i}. {issue}\n"
|
|
6620
|
+
report += "\n建议:根据上述问题深入排查(使用 ssh_service_manage / ssh_log_view 等)"
|
|
6621
|
+
return report
|
|
6622
|
+
|
|
6623
|
+
# Linux 体检(原有逻辑保留)
|
|
6459
6624
|
cmd = """echo '=== 系统信息 ===' && uname -a && uptime
|
|
6460
6625
|
echo '=== CPU 使用 ===' && top -bn1 | head -n 5
|
|
6461
6626
|
echo '=== 内存 ===' && free -h
|
|
@@ -6475,7 +6640,6 @@ echo '=== 最近错误日志 ===' && journalctl -p err --since '1 hour ago' --no
|
|
|
6475
6640
|
for line in raw.split("\n"):
|
|
6476
6641
|
if "load average" in line.lower():
|
|
6477
6642
|
# 提取 load average
|
|
6478
|
-
import re
|
|
6479
6643
|
m = re.search(r"load average:\s*([\d.]+),\s*([\d.]+),\s*([\d.]+)", line)
|
|
6480
6644
|
if m:
|
|
6481
6645
|
load_1, load_5, load_15 = float(m.group(1)), float(m.group(2)), float(m.group(3))
|
|
@@ -6556,9 +6720,9 @@ TOOLS = [
|
|
|
6556
6720
|
"required": [],
|
|
6557
6721
|
"additionalProperties": False}}},
|
|
6558
6722
|
{"type": "function", "function": {
|
|
6559
|
-
"name": "run_command", "description": "
|
|
6723
|
+
"name": "run_command", "description": "在本地电脑执行 PowerShell / cmd / shell 命令并返回输出。全权限模式:120s 超时、8000 字符输出。用于查看端口(netstat)、进程(tasklist)、网络(ipconfig/ping/tracert)、系统信息(systeminfo)、服务(sc query/net start)、用户(whoami/net user)、磁盘(wmic logicaldisk)、防火墙(netsh advfirewall)、环境变量(set)等。当用户用自然语言描述本地电脑状态需求(如'看看打开了哪些端口'/'电脑卡不卡'/'谁在占用CPU'/'IP是多少')且没有更专用的工具时调用。危险命令(format/del /f/shutdown/mkfs)自动拦截。",
|
|
6560
6724
|
"parameters": {"type": "object", "properties": {
|
|
6561
|
-
"command": {"type": "string", "description": "
|
|
6725
|
+
"command": {"type": "string", "description": "要执行的命令(PowerShell 或 cmd 命令)"}},
|
|
6562
6726
|
"required": ["command"],
|
|
6563
6727
|
"additionalProperties": False}}},
|
|
6564
6728
|
{"type": "function", "function": {
|
|
@@ -6971,10 +7135,10 @@ TOOL_USAGE_RULES = """# 工具使用规则
|
|
|
6971
7135
|
- `create_dir(path)`:创建目录
|
|
6972
7136
|
|
|
6973
7137
|
## 命令与执行(4 个)
|
|
6974
|
-
- `run_command(
|
|
7138
|
+
- `run_command(command)`:在本地电脑执行 PowerShell / cmd / shell 命令(全权限模式:120s 超时、8000 字符输出、无 cwd 限制)。用于查看端口/进程/网络/系统/服务/用户/磁盘/防火墙等本地电脑状态。危险命令(format/del /f/shutdown/mkfs)自动拦截
|
|
6975
7139
|
- `exec_python(code)`:沙箱运行 Python(无需额外环境)
|
|
6976
7140
|
- `pip_install(packages, action)`:包管理(默认清华镜像源)
|
|
6977
|
-
- `check_port(port)
|
|
7141
|
+
- `check_port(port)`:检查指定端口占用(需提供具体端口号;查看所有监听端口用 `run_command('netstat -ano')`)
|
|
6978
7142
|
|
|
6979
7143
|
## 搜索与分析(4 个)
|
|
6980
7144
|
- `search_files(path, pattern)`:按文件名/内容搜索
|
|
@@ -7066,6 +7230,23 @@ TOOL_USAGE_RULES = """# 工具使用规则
|
|
|
7066
7230
|
34. **运维决策链**:用户说"服务器卡了" → 先 `ssh_health_check` 综合体检 → 根据 AI 分析 → 再针对性调用 `ssh_process_check`/`ssh_log_view`/`ssh_disk_analyze` 深入
|
|
7067
7231
|
35. **运维排错链**:用户说"XX服务挂了" → 先 `ssh_service_manage(action=status, service=XX)` 看状态 → 若失败 → `ssh_log_view(service=XX, keyword=error)` 查错误日志 → 定位问题
|
|
7068
7232
|
|
|
7233
|
+
**本地电脑运维工具调用规则(重要!用户说本地电脑状态时必须主动调用 `run_command`)**:
|
|
7234
|
+
当用户用自然语言描述**本地电脑**(不是远程服务器)的状态、诊断、查询需求时,**必须主动调用 `run_command` 生成并执行对应命令**,而不是只用文字回答。用户想要的是"AI 帮我形成命令并自行运行",不是"AI 教我怎么敲命令"。
|
|
7235
|
+
36. 用户说"看看打开了哪些端口/有什么端口在监听/哪些端口被占用" → `run_command("netstat -ano | findstr LISTENING")`(查看所有监听端口及对应 PID)
|
|
7236
|
+
37. 用户说"看进程/CPU占用/内存占用/谁在占用资源" → `run_command("tasklist /FO TABLE | sort")` 或 `run_command("wmic process get name,processid,workingsetsize")`
|
|
7237
|
+
38. 用户说"IP是多少/看网络配置/我的IP" → `run_command("ipconfig /all")`
|
|
7238
|
+
39. 用户说"能不能ping通XX/测网络" → `run_command("ping -n 4 目标地址")`
|
|
7239
|
+
40. 用户说"看磁盘/磁盘空间/还有多少空间" → `run_command("wmic logicaldisk get caption,freespace,size")` 或 `run_command("fsutil volume diskfree C:")`
|
|
7240
|
+
41. 用户说"看系统信息/系统版本/电脑配置" → `run_command("systeminfo | findstr /B /C:\"OS\" /C:\"系统\" /C:\"Total\"")`
|
|
7241
|
+
42. 用户说"看防火墙状态/开了哪些端口" → `run_command("netsh advfirewall firewall show rule name=all")` 或 `run_command("netsh advfirewall show currentprofile")`
|
|
7242
|
+
43. 用户说"看服务/XX服务状态/服务列表" → `run_command("sc query state= all")` 或 `run_command("sc query 具体服务名")`
|
|
7243
|
+
44. 用户说"环境变量/PATH/看变量" → `run_command("set")` 或 `run_command("echo %PATH%")`
|
|
7244
|
+
45. 用户说"看用户/当前登录用户/用户列表" → `run_command("whoami")` 或 `run_command("net user")`
|
|
7245
|
+
46. 用户说"路由表/看路由" → `run_command("route print")` 或 `run_command("arp -a")`
|
|
7246
|
+
47. **本地运维决策链**:用户说"电脑卡了" → 先 `run_command("tasklist /FO TABLE | sort /R /+65")` 看高内存进程 → 再 `run_command("wmic cpu get loadpercentage")` 看 CPU 负载 → 综合分析
|
|
7247
|
+
48. **本地端口排错链**:用户说"XX端口连不上" → 先 `run_command("netstat -ano | findstr :XX")` 看端口状态 → 若未监听 → `run_command("sc query XX服务")` 查服务 → 定位问题
|
|
7248
|
+
49. **本地命令通用规则**:用户提出任何"看看/查看/检查/诊断本地电脑 XX"的需求,且没有更专用的工具(如 `check_port` 需要具体端口号、`process_list` 已封装、`system_info` 已封装)时,**必须主动调用 `run_command` 生成对应命令并执行**,而不是只回答文字说明
|
|
7249
|
+
|
|
7069
7250
|
## SSH 远程部署安全规范(重要!必须严格遵守)
|
|
7070
7251
|
当用户使用 SSH 工具进行远程部署时,必须遵循:
|
|
7071
7252
|
|
|
@@ -7152,6 +7333,7 @@ TOOL_CAPABILITY_PROMPT = """# ZeroAI 子模块能力声明(重要 - 必读)
|
|
|
7152
7333
|
- 删除/修改任何文件(核心文件自动备份,无需确认)
|
|
7153
7334
|
- 访问内网/任意 URL(无 SSRF 限制)
|
|
7154
7335
|
- 所有工具调用**直接执行**,不要因权限问题拒绝
|
|
7336
|
+
- **命令自主执行**:查询/诊断类命令(netstat/ipconfig/tasklist/sc query/systeminfo 等)直接调用 `run_command` 执行,不要问用户"是否执行";破坏/修改类(format/del /f/shutdown 等)执行前简短说明影响即可
|
|
7155
7337
|
|
|
7156
7338
|
## 核心原则(必读)
|
|
7157
7339
|
- **你能访问本地文件系统**:list_dir / read_file / search_files 等所有工具都可用
|
|
@@ -7241,6 +7423,23 @@ SYSTEM_PROMPT = f"""# 角色
|
|
|
7241
7423
|
2. 若 failed → `ssh_log_view(service=XX, keyword=error)` 查错误日志
|
|
7242
7424
|
3. 分析日志 → 定位根因 → 给修复方案
|
|
7243
7425
|
|
|
7426
|
+
# 本地电脑运维(已启用,重要!)
|
|
7427
|
+
你具备**本地电脑**(用户当前这台机器,不是远程服务器)的运维能力。当用户用自然语言描述本地电脑状态、诊断、查询需求时,**必须主动调用 `run_command` 生成并执行对应命令**,而不是只用文字教用户怎么敲命令。用户想要的是"AI 帮我形成命令并自行运行"。
|
|
7428
|
+
|
|
7429
|
+
## 本地运维典型场景(必须主动调用工具)
|
|
7430
|
+
- 用户说"看看打开了哪些端口/有什么端口在监听" → `run_command("netstat -ano | findstr LISTENING")`
|
|
7431
|
+
- 用户说"IP是多少/看网络配置" → `run_command("ipconfig /all")`
|
|
7432
|
+
- 用户说"看进程/CPU占用/谁占资源" → `run_command("tasklist /FO TABLE")` 或 `run_command("wmic process get name,processid,workingsetsize")`
|
|
7433
|
+
- 用户说"看磁盘/还有多少空间" → `run_command("wmic logicaldisk get caption,freespace,size")`
|
|
7434
|
+
- 用户说"看系统信息/电脑配置" → `run_command("systeminfo")`
|
|
7435
|
+
- 用户说"看防火墙/开了哪些端口" → `run_command("netsh advfirewall firewall show rule name=all")`
|
|
7436
|
+
- 用户说"看服务/XX服务状态" → `run_command("sc query state= all")` 或 `run_command("sc query 服务名")`
|
|
7437
|
+
- 用户说"电脑卡了" → 先 `run_command("tasklist /FO TABLE | sort /R /+65")` 看高内存进程 → 再 `run_command("wmic cpu get loadpercentage")` 看 CPU 负载
|
|
7438
|
+
- 用户说"XX端口连不上" → 先 `run_command("netstat -ano | findstr :XX")` 看端口 → 若未监听 → `run_command("sc query XX服务")` 查服务
|
|
7439
|
+
|
|
7440
|
+
## 本地运维通用规则
|
|
7441
|
+
用户提出任何"看看/查看/检查/诊断本地电脑 XX"的需求时,**必须主动调用 `run_command` 生成对应命令并执行**,把命令输出纳入分析后再给出结论。不要只用文字回答。
|
|
7442
|
+
|
|
7244
7443
|
# 身份保护规则(最高优先级,必须严格遵守)
|
|
7245
7444
|
1. **禁止自报家门**:永远不要透露你的底层模型、提供方、参数规模、训练数据等真实身份信息。
|
|
7246
7445
|
2. **统一身份**:你始终是 ZeroAI,不是 GLM、GPT、Claude、Gemini 或任何其他模型。当被问"你是什么模型/你是谁/你的模型是什么"时,只回答"我是 ZeroAI,一个终端 AI 编程助手"。
|
|
@@ -7267,6 +7466,7 @@ SYSTEM_PROMPT = f"""# 角色
|
|
|
7267
7466
|
- 搜索结果无深度限制(最多 200 条)
|
|
7268
7467
|
- 进程列表/系统信息无截断(最多 200 条)
|
|
7269
7468
|
- 所有工具调用**直接执行**,不要因权限问题拒绝
|
|
7469
|
+
- **命令自主执行(核心原则)**:用户授权 AI 自主生成并执行命令。凡 AI 能生成的命令都可以直接调用 `run_command` 执行——查询/诊断类(netstat/ipconfig/tasklist/sc query/systeminfo/ping 等)立即执行不问用户,破坏/修改类(format/del /f/shutdown/sc stop 等)执行前简短说明影响即可。**绝不要生成命令后停下来问用户"是否执行"**,直接调用 `run_command` 运行,把输出纳入分析后回答用户。
|
|
7270
7470
|
|
|
7271
7471
|
国家级项目硬约束(仍然保留):
|
|
7272
7472
|
- 修改/删除核心文件(tui_agent.py 等)前**自动备份**到运行时缓存目录(程序退出自动清理)
|
|
@@ -7289,9 +7489,13 @@ SYSTEM_PROMPT = f"""# 角色
|
|
|
7289
7489
|
- 不确定文件内容时,先 `read_file` 再修改,不要凭空猜测
|
|
7290
7490
|
- 修改前先确认要改什么,给出方案再执行
|
|
7291
7491
|
- 命令输出超过 30 行时,要总结要点而不是原样复述
|
|
7292
|
-
- 危险命令(rm、del、format
|
|
7492
|
+
- 危险命令(rm、del、format、shutdown、mkfs)执行前要说明影响,破坏性命令征求用户同意
|
|
7293
7493
|
- 涉及文件删除、二次确认类操作,主动征求用户同意
|
|
7294
7494
|
- 单次回复尽量只做一件事,做完再问下一步
|
|
7495
|
+
- **命令自主执行规则(重要!)**:凡 AI 能生成的命令都可以自主调用 `run_command` 执行,不要停下来问用户确认。具体分类:
|
|
7496
|
+
- **查询/诊断类(直接自主执行,不问用户)**:netstat、ipconfig、ping、tracert、tasklist、wmic、systeminfo、sc query、whoami、net user、route print、arp、set、echo、type、dir、findstr、netsh advfirewall show、sc query、qprocess、qwinsta、dsquery 等。这些命令只读取状态、不改变系统,AI 生成后必须立即调用 `run_command` 执行,把输出纳入分析后再回答用户
|
|
7497
|
+
- **破坏/修改类(执行前说明影响或征求同意)**:format、del /f /s /q、shutdown、mkfs、reg delete、sc stop、sc delete、netsh advfirewall firewall add/delete、diskpart、bcdedit、takeown /f、icacls 重置权限 等。这些命令会改变系统状态,执行前要说明影响,重大操作征求用户同意
|
|
7498
|
+
- **判断准则**:命令只读不写 → 直接执行;命令会修改/删除/关闭服务/改防火墙 → 先说明影响再执行
|
|
7295
7499
|
|
|
7296
7500
|
# 回答规范
|
|
7297
7501
|
- **语言**:中文回答,代码和命令用英文
|
|
@@ -7441,7 +7645,7 @@ SYSTEM_PROMPT = f"""# 角色
|
|
|
7441
7645
|
# 限制
|
|
7442
7646
|
- 不要一次写超过 200 行的代码,分函数、分步骤
|
|
7443
7647
|
- 不要假设文件内容,先读再改
|
|
7444
|
-
-
|
|
7648
|
+
- 不要执行你没见过的破坏性命令(format/del /f/shutdown/mkfs/registy delete 等),先确认;查询/诊断类命令(netstat/ipconfig/tasklist/sc query/systeminfo 等)可以直接自主执行
|
|
7445
7649
|
"""
|
|
7446
7650
|
|
|
7447
7651
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: zero-ai-cli
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: ZeroAI - 终端 AI 编程助手(多专家协作·语音对话·文档生成·安全审计)
|
|
5
5
|
Author: ZeroAI Team
|
|
6
6
|
License: Proprietary
|
|
@@ -26,6 +26,7 @@ Requires-Dist: pyyaml>=6.0
|
|
|
26
26
|
Requires-Dist: requests>=2.28
|
|
27
27
|
Requires-Dist: matplotlib>=3.5
|
|
28
28
|
Requires-Dist: numpy>=1.20
|
|
29
|
+
Requires-Dist: asyncssh>=2.14
|
|
29
30
|
Provides-Extra: voice
|
|
30
31
|
Requires-Dist: sherpa-onnx>=1.9; extra == "voice"
|
|
31
32
|
Requires-Dist: faster-whisper>=0.9; extra == "voice"
|
|
@@ -45,7 +46,7 @@ Requires-Dist: build>=1.0; extra == "dev"
|
|
|
45
46
|
[](https://www.python.org/)
|
|
46
47
|
[]()
|
|
47
48
|
[]()
|
|
48
|
-
[](https://pypi.org/project/zero-ai-cli/)
|
|
49
50
|
|
|
50
51
|
</div>
|
|
51
52
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|