## 架构改造 将 recorder/tunnel/managed_mcp 三个有状态单例模块拆成 mindcli/pipelines/ 下的无状态管线 + health.py 调用方持有状态。 参照 hermes-overlay/infra/pipelines/anyfile2md.py 的分层模式。 ### pipelines/ 层(无状态) - audio_capture.py: capture() 工厂函数返回独立 CaptureHandle, 无单例无互斥,双工模式(system+mic 并行)在代码层面可用 - tunnel_session.py: connect() 工厂函数 + on_status 回调, 消除 health ⇄ tunnel 循环耦合(单向数据流) - tool_proxy.py: ToolProxy 替代 ManagedMCP,非单例 ### health.py 改造 - _active_captures dict 按 chatId 索引,可多实例并存 - _tunnel_handle 由调用方持有,on_status 回调更新状态 - /record/stop 支持 ?chatId= 停单路或全停 - /record/status 返回所有活跃录音列表 ### cli.py 改造 - chat/ask 走 run_agent headless + Cloud Gateway JWT(铁律 A) - 保留 --offline 走 vendor TUI(铁律 C:断开即自治) - mind update 修复 pipx 场景: - 检测 pipx venv → pipx reinstall - 非 pipx → sys.executable -m pip(修复 venv 里 pip 找不到) - 防降级保护(远端版本低于本地时不升级) - 远端 upgradeCmd 字段下发 ### 顺手修复 - health.py / capability.py 的 HERMES_COMMIT → VENDOR_COMMIT - 版本号 0.1.0 → 0.2.0(__init__.py + pyproject.toml) - 新增 versions.json 仓库模板(installCmd 改为 pipx,新增 upgradeCmd) ### 删除 - recorder.py → 逻辑迁入 pipelines/audio_capture.py - tunnel.py → 逻辑迁入 pipelines/tunnel_session.py - managed_mcp.py → 逻辑迁入 pipelines/tool_proxy.py SPEC: docs/SPEC_mindcli_atomization.md
80 lines
2.4 KiB
Python
80 lines
2.4 KiB
Python
"""
|
||
Mind CLI — 能力扫描器。
|
||
|
||
扫描本地可用的内置工具和 MCP Server,生成 capability report
|
||
供 Tunnel 握手时上报给 Cloud。
|
||
"""
|
||
|
||
import os
|
||
import platform
|
||
from typing import Any
|
||
|
||
import mindcli
|
||
|
||
|
||
# ── 内置工具注册表 ────────────────────────────────────
|
||
# 只暴露 Cloud 端有意义的本地工具(文件操作、终端、搜索等)
|
||
# 浏览器工具、TTS 等纯交互工具不上报
|
||
_BUILTIN_TOOLS: list[dict[str, str]] = [
|
||
{"name": "terminal", "type": "builtin", "desc": "执行终端命令"},
|
||
{"name": "file_read", "type": "builtin", "desc": "读取本地文件"},
|
||
{"name": "file_write", "type": "builtin", "desc": "写入本地文件"},
|
||
{"name": "file_ops", "type": "builtin", "desc": "文件操作(复制/移动/删除)"},
|
||
{"name": "grep", "type": "builtin", "desc": "文本搜索"},
|
||
{"name": "code_execution", "type": "builtin", "desc": "执行代码片段"},
|
||
]
|
||
|
||
|
||
def scan_capabilities() -> dict[str, Any]:
|
||
"""
|
||
扫描本地可用工具,返回 capability report。
|
||
|
||
返回格式:
|
||
{
|
||
"version": "0.1.0",
|
||
"vendor": "16f9d020",
|
||
"platform": "Darwin",
|
||
"arch": "arm64",
|
||
"python": "3.12.11",
|
||
"tools": [
|
||
{"name": "terminal", "type": "builtin", "desc": "..."},
|
||
...
|
||
],
|
||
"mcp_servers": [] # Phase 2+ 从 config.yaml 读取
|
||
}
|
||
"""
|
||
import sys
|
||
|
||
return {
|
||
"version": mindcli.__version__,
|
||
"vendor": _get_vendor_commit(),
|
||
"platform": platform.system(),
|
||
"arch": platform.machine(),
|
||
"python": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
|
||
"tools": list(_BUILTIN_TOOLS),
|
||
"mcp_servers": _scan_mcp_servers(),
|
||
}
|
||
|
||
|
||
def get_tool_names() -> list[str]:
|
||
"""返回所有内置工具名称列表。"""
|
||
return [t["name"] for t in _BUILTIN_TOOLS]
|
||
|
||
|
||
def _scan_mcp_servers() -> list[dict[str, str]]:
|
||
"""
|
||
扫描用户配置的第三方 MCP Server。
|
||
|
||
TODO: 从 ~/.mindcli/config.yaml 的 mcp_servers 段读取。
|
||
"""
|
||
return []
|
||
|
||
|
||
def _get_vendor_commit() -> str:
|
||
commit_file = os.path.join(mindcli._VENDOR_DIR, "VENDOR_COMMIT")
|
||
try:
|
||
with open(commit_file) as f:
|
||
return f.read().strip()
|
||
except FileNotFoundError:
|
||
return "unknown"
|