Skip to content

feat: support skill version qualifier in download #129

Open
yuyushui66 wants to merge 1 commit into
Serverless-Devs:mainfrom
yuyushui66:main
Open

feat: support skill version qualifier in download #129
yuyushui66 wants to merge 1 commit into
Serverless-Devs:mainfrom
yuyushui66:main

Conversation

@yuyushui66

Copy link
Copy Markdown

Summary

  • Tool.download_skill() / download_skill_async() 新增 qualifier 参数,支持下载指定版本的 Skill(如 "v1.0.0""default""LATEST"
  • skill_tools() 支持 "name@qualifier" 字符串语法和 qualifier= kwarg,列表入参时每个 skill 可独立指定版本
  • 完全向后兼容:所有新增参数均为可选,老代码无需修改

Background

后端 (funagent-core) 已实现 Skill 版本管理控制面 API 和数据面版本化下载端点:

GET {data_endpoint}/tools/{name}/download?qualifier={version}

本 PR 让 Python SDK 暴露这一能力,使 Agent Runtime / 业务代码可以在下载 Skill 时锁定版本,避免因 LATEST 漂移导致行为变化。

Changes

公开 API(新增可选参数,向后兼容)

API 改动
Tool.download_skill() 新增 qualifier: Optional[str] = None
Tool.download_skill_async() 新增 qualifier: Optional[str] = None
skill_tools() 新增 qualifier: Optional[str] = None kwarg;name 入参字符串/列表元素支持 "@qualifier" 语法

用法示例

# 1. 直接下载指定版本
tool.download_skill(qualifier="v1.0.0")

# 2. skill_tools 字符串语法
skill_tools("my-skill@v1.0.0")
skill_tools("my-skill@default")

# 3. 批量混合版本
skill_tools(["skill-a@v1.0.0", "skill-b@latest", "skill-c"])

# 4. ToolResource 入参用 kwarg
skill_tools(tool, qualifier="v1.0.0")
# 5. 环境变量驱动(agent_v2.py 等无需改代码)
export AGENTRUN_SKILL_NAMES="code-review@v1.0.0,doc-gen@default,test-runner"

关键设计决策

  • @ 作分隔符:工具名受后端正则 ^[_a-zA-Z][-_a-zA-Z0-9]*$ 约束不含 @,分隔符无歧义;使用 rsplit('@', 1) 解析
  • 指定 qualifier 时强制重下:避免使用本地旧版本目录
  • URL 编码qualifierurllib.parse.quote(..., safe='') 编码,确保 RAM 签名正确
  • 空 qualifier 容错"name@" 视为不指定版本;"@v1.0.0"ValueError

内部重构

  • SkillLoader.__init__ 参数 remote_skill_names: List[str]remote_skills: List[Tuple[str, Optional[str]]],以承载每个 skill 的独立版本号
  • 经全量代码扫描确认无外部调用方使用 remote_skill_names,所以此变更实际零影响
  • 新增模块私有函数 _parse_skill_qualifier() 用于解析 "name@qualifier" 语法

Compatibility

调用形式 改动前 改动后
tool.download_skill() ✅ 完全兼容
skill_tools("name") ✅ 完全兼容
skill_tools(["a", "b"]) ✅ 完全兼容
skill_tools(tool) ✅ 完全兼容
AGENTRUN_SKILL_NAMES="a,b" ✅ 完全兼容
tool.download_skill(qualifier="v1.0.0") ✅ 新支持
skill_tools("name@v1.0.0") ✅ 新支持
AGENTRUN_SKILL_NAMES="a@v1.0.0,b" ✅ 新支持

Test Plan

  • 单元测试 tests/unittests/integration/test_skill_loader.py:新增 12 个测试覆盖 _parse_skill_qualifierSkillLoader qualifier 处理、skill_tools 各种入参形式
  • 单元测试 tests/unittests/tool/test_tool.py:新增 3 个测试覆盖 _get_skill_download_url 的 qualifier URL 生成与 URL 编码
  • 全量测试通过:323 passed
  • mypy 类型检查通过:375 source files, no issues
  • 同步 make codegen 重新生成 agentrun/tool/tool.py

Related

  • 后端实现:funagent-core Skill 版本管理服务(PublishVersion / ListVersions / GetVersionByQualifier)
  • 数据面下载端点:GET /tools/{name}/download?qualifier={version}
  • 跨仓库消费链路:BFF (Java) → AgentRun Core (Go) → Agent SDK (Python,本 PR)

Add `qualifier` parameter to `Tool.download_skill()` and
`download_skill_async()` so callers can request a specific skill
version (e.g. "v1.0.0", "default", "LATEST") from the data plane
download endpoint.

`skill_tools()` accepts the same version semantics via the
"name@qualifier" string syntax (for str/list inputs) or the
`qualifier=` keyword (for ToolResource inputs); each list element
can specify its own version independently. Specifying a qualifier
forces re-download to avoid serving a stale local copy.

`SkillLoader` is refactored internally to carry (name, qualifier)
tuples; the legacy `remote_skill_names` parameter is replaced by
`remote_skills`. Code scans confirm no external caller used the
legacy parameter, so this is backward compatible in practice.

Signed-off-by: daoxun.yds <daoxun.yds@alibaba-inc.com>
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.

1 participant