Skip to content

Agent cli#34

Open
tastelikefeet wants to merge 18 commits into
modelscope:mainfrom
tastelikefeet:feat/agent
Open

Agent cli#34
tastelikefeet wants to merge 18 commits into
modelscope:mainfrom
tastelikefeet:feat/agent

Conversation

@tastelikefeet

@tastelikefeet tastelikefeet commented Jul 4, 2026

Copy link
Copy Markdown

命令行用法

# 登录(前置条件)
ms login --token <your-token>

# 上传本地 agent 文件到远端仓库
ms agent upload -f qwenpaw -r user/my-agent
ms agent upload -f nanobot -r user/my-agent -n reviewer --dry-run

# 从远端下载 agent 文件到本地
ms agent download -f qwenpaw -r user/my-agent
ms agent download -f nanobot -r user/my-agent --target-framework qwenpaw

# 后台同步守护进程(默认 push-only)
ms agent watch -f qwenpaw -r user/my-agent
ms agent watch -f qwenpaw -r user/my-agent --pull   # 双向同步

# 停止 watch 守护进程
ms agent stop

# 列出远端仓库
ms agent list --owner user --page-size 20

# 查看本地状态
ms agent status -f qwenpaw

# 格式转换(纯本地,无网络)
ms agent convert --from-framework nanobot --target-framework qwenpaw

# 备份管理
ms agent backups -f qwenpaw
ms agent restore --from-backup last -f qwenpaw

支持的框架:nanobot, openclaw, hermes, qwenpaw, openhuman, qoder


测试用例覆盖

测试文件 范围 场景
test_watch_sync.py 集成测试(真实 API) 12 个场景:push/pull/冲突/删除传播/首次同步/空操作/状态持久化/并发/individual-watch 拦截
test_upload_download.py 集成测试(真实 API) upload/download/dry-run/跨框架转换下载/token 可选下载
test_cli.py 单元测试(mock client) argparse 路由、参数传递、错误路径、所有子命令
test_merge.py 单元测试 merge_resources:section merger、heartbeat merger、默认模板注入
test_agent_frameworks.py 单元测试 workspace spec:模式匹配、collect、list_agents、apply、6 个框架全覆盖
test_workspace.py 单元测试 WorkspaceSpec 抽象契约、路径遍历防护

薄弱点与建议

1. download_repo_file 未检查 HTTP 错误状态码

# _api.py L192-194
resp = self._openapi.request("GET", url=dl_url, unwrap=False)
return resp.content if binary else resp.text

unwrap=False 跳过了 _decode() 的错误检查,HTTP 4xx/5xx 会静默返回错误 body 作为"文件内容"。

建议:添加 resp.raise_for_status() 或手动检查 resp.status_code


2. _refresh_baseline 重试无指数退避

# _watcher.py L222-223
if e.status_code == 500 and attempt < 2:
    time.sleep(3)  # 固定 3s,无退避

建议:改为 time.sleep(2 ** attempt) 实现指数退避,减轻服务端压力。


3. Windows _find_watch_pids_windows 使用已弃用的 wmic

Windows 10+ 已标记 wmic 为 deprecated,未来版本可能移除。

建议:改用 tasklist /FO CSV /FI "IMAGENAME eq python*" 或引入 psutil


4. detect_local_changes 每次全量计算 SHA256

# _sync.py L77-78
for rel, content in local_resources.items():
    local_sha = sha256_content(content)

watch 每 120s 触发一次,每次对所有文件计算 SHA256。工作区文件量大时有性能瓶颈。

建议:先比对 mtime/size 快速过滤,仅对疑似变更文件计算 SHA256。(注:当前 collect_bytes 已将文件读入内存,实际瓶颈在磁盘 IO 而非 hash 计算本身)


5. cmd_recover 中 zip 提取路径安全日志不足

# _commands.py L682-685
file_target = (resolved_root / info.filename).resolve()
if not file_target.is_relative_to(resolved_root):
    print(f"  Skipped (path traversal): {info.filename}")
    continue

路径遍历防护逻辑正确,但仅用 print 输出。在生产环境中这类安全事件应通过 logger 记录。

建议:改用 logger.warning("Path traversal blocked: %s", info.filename)


6. cmd_list 缺少 endpoint 为空的前置检查

当用户未登录且未设置环境变量时,AgentApi(endpoint=None) 会 fallback 到 HubConfig 默认值。如果默认值也为空,会产生不友好的错误信息。

建议:在 cmd_list 开头显式检查 endpoint,给出明确提示。


7. _openapi.pyrequest()pathurl 互斥性未校验

def request(self, method, path="", *, url=None, ...):
    # 内部: final_url = url or self._url(path)

同时传入 pathurl 时,url 优先,但缺少参数互斥的显式校验或文档警告。

建议:添加 assert not (path and url) 或在 docstring 中明确说明优先级。


8. 测试覆盖缺失场景

缺失场景 风险等级 说明
Windows 平台 daemon 化、stop 文件机制、进程清理均无测试
网络异常恢复 连接超时、DNS 失败后 watch 的重试行为
sync state 损坏 JSON 文件损坏后降级行为(代码已处理,但无测试验证)
并发安全 两个 watch 进程竞争同一 sync state 文件
路径遍历攻击 恶意 zip 中的 ../ 路径(代码已防护,建议补测试)

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces an Agent workspace management SDK and CLI for ModelScope Hub, supporting multiple frameworks (Hermes, Nanobot, OpenClaw, OpenHuman, Qoder, QwenPaw) with features like local-to-remote upload, download, format conversion, and background bidirectional sync. The review feedback highlights several critical issues: the Windows background daemon lacks an entry point to execute, the CLI fails to fall back to saved credentials in HubConfig when arguments are omitted, and unquote decodes too many characters in the OSS URL normalization. Additionally, signal registration should be guarded against non-main threads, PID file unlinking needs to verify the current process ID to prevent race conditions, framework auto-inference from backup filenames is broken for compound names, and task insertion in HeartbeatMerger places new tasks above the placeholder comment instead of below it.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/modelscope_hub/agent/_watcher.py
Comment thread src/modelscope_hub/cli/agent.py Outdated
Comment thread src/modelscope_hub/agent/_api.py Outdated
Comment thread src/modelscope_hub/agent/_watcher.py Outdated
Comment thread src/modelscope_hub/agent/_watcher.py Outdated
Comment thread src/modelscope_hub/agent/_watcher.py Outdated
Comment thread src/modelscope_hub/agent/_commands.py
Comment thread src/modelscope_hub/agent/_merge.py
Comment thread src/modelscope_hub/agent/default_configs/hermes/memories/USER.md
Comment thread tests/agent/test_cli_download_convert.py Outdated
Comment thread tests/agent/test_client_integration.py Outdated
Comment thread tests/agent/test_commands.py Outdated
Comment thread tests/agent/test_agent_frameworks.py
@tastelikefeet tastelikefeet changed the title [WIP]agent cli Agent cli Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants