mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-16 20:10:45 +08:00
统一技能安装与 Skills 市场接入链路。
新增公开安装工具与多来源 provider 支持,补齐管理端与目录加载逻辑,并同步更新相关测试与文档以保证可见性和路径安全。 Made-with: Cursor
This commit is contained in:
parent
d5e30542aa
commit
4d9232f3b3
66 changed files with 7369 additions and 1099 deletions
|
|
@ -4,6 +4,16 @@ from dataclasses import dataclass
|
|||
from typing import Any, Protocol
|
||||
|
||||
from oclaw.runtime.tools.skills.clawhub_client import get_skill_detail, search_skills
|
||||
from oclaw.runtime.tools.skills.cocoloop_client import get_skill_detail_by_slug as cocoloop_get_skill_detail
|
||||
from oclaw.runtime.tools.skills.cocoloop_client import search_store_skills as cocoloop_search_skills
|
||||
|
||||
|
||||
def normalize_skill_market_provider_setting(raw: str | None) -> str:
|
||||
"""Tenant setting value for ``AIA_SKILL_MARKET_PROVIDER``: ``clawhub`` or ``cocoloop``."""
|
||||
p = str(raw or "").strip().lower()
|
||||
if p in {"cocoloop", "cocoloop-cn", "cocoloop_cn"}:
|
||||
return "cocoloop"
|
||||
return "clawhub"
|
||||
|
||||
|
||||
class SkillMarketAdapter(Protocol):
|
||||
|
|
@ -42,12 +52,45 @@ class ClawHubMarketAdapter:
|
|||
return str(detail.get("archiveUrl") or "").strip(), latest
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class CocoloopMarketAdapter:
|
||||
provider: str = "cocoloop"
|
||||
|
||||
def search(self, query: str, *, limit: int = 20) -> list[dict[str, Any]]:
|
||||
return cocoloop_search_skills(query, limit=limit)
|
||||
|
||||
def detail(self, slug: str) -> dict[str, Any]:
|
||||
return cocoloop_get_skill_detail(slug)
|
||||
|
||||
def resolve_archive_url(self, *, slug: str, version: str | None = None) -> tuple[str, str]:
|
||||
detail = self.detail(slug)
|
||||
requested = str(version or "").strip().lstrip("vV")
|
||||
if requested:
|
||||
for row in detail.get("versions") or []:
|
||||
if not isinstance(row, dict):
|
||||
continue
|
||||
ver = str(row.get("version") or "").strip().lstrip("vV")
|
||||
if ver != requested:
|
||||
continue
|
||||
return str(row.get("archiveUrl") or "").strip(), str(row.get("version") or requested)
|
||||
latest = str(detail.get("latestVersion") or "").strip()
|
||||
return str(detail.get("archiveUrl") or "").strip(), latest
|
||||
|
||||
|
||||
def get_market_adapter(provider: str | None) -> SkillMarketAdapter:
|
||||
p = str(provider or "clawhub").strip().lower()
|
||||
p = normalize_skill_market_provider_setting(provider)
|
||||
if p in {"clawhub", "openclaw"}:
|
||||
return ClawHubMarketAdapter(provider="clawhub")
|
||||
if p in {"cocoloop", "cocoloop-cn", "cocoloop_cn"}:
|
||||
return CocoloopMarketAdapter(provider="cocoloop")
|
||||
raise ValueError(f"unsupported_market_provider:{p}")
|
||||
|
||||
|
||||
__all__ = ["SkillMarketAdapter", "ClawHubMarketAdapter", "get_market_adapter"]
|
||||
__all__ = [
|
||||
"SkillMarketAdapter",
|
||||
"ClawHubMarketAdapter",
|
||||
"CocoloopMarketAdapter",
|
||||
"get_market_adapter",
|
||||
"normalize_skill_market_provider_setting",
|
||||
]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue