diff --git a/console/src/api/modules/pluginMarket.ts b/console/src/api/modules/pluginMarket.ts index 5278a59..a47c936 100644 --- a/console/src/api/modules/pluginMarket.ts +++ b/console/src/api/modules/pluginMarket.ts @@ -94,7 +94,10 @@ export function buildMarketDownloadUrl( source?: string, ): string { const id = entry.id.startsWith("@") ? entry.id.slice(1) : entry.id; - const [owner, name] = id.split("/"); + const parts = id.split("/"); + // 单段 id(历史数据未补 owner 前缀):统一按 pineagents/ 处理,避免 owner/undefined + const owner = parts[0] || "pineagents"; + const name = parts[1] || parts[0]; // 云超服市场源:下载指向本端代理(带登录态转发到 server-core bundle)。 if (source === "pineagents") { return getApiUrl(`/plugins/market/download/${owner}/${name}`); diff --git a/src/pineagents/app/routers/plugins.py b/src/pineagents/app/routers/plugins.py index 530c69f..2ee560b 100644 --- a/src/pineagents/app/routers/plugins.py +++ b/src/pineagents/app/routers/plugins.py @@ -1232,6 +1232,23 @@ async def _fetch_market_bundle_bytes( (it["id"] for it in items2 if it.get("slug") == slug), None, ) + if item_id is None: + # 兼容历史单段 slug(未补 owner 前缀,如 "creator"、"公众号爆款封面生成"): + # 按 name 单独精确匹配,覆盖 owner/name 与 name 两种存储形态。 + for it_type in ("plugin", "app"): + find3 = await client.get( + "/market/items", + params={"q": name, "item_type": it_type, "page_size": 20}, + headers=headers, + ) + find3.raise_for_status() + items3 = (find3.json().get("items") or []) + item_id = next( + (it["id"] for it in items3 if it.get("slug") in (name, f"{owner}/{name}")), + None, + ) + if item_id is not None: + break if item_id is None: raise HTTPException(status_code=404, detail=f"云超服市场未找到商品 {slug}")