Add 39 shared skills from local agent inventory

Sources: ~/.openclaw/skills, ~/.agents/skills, workshop-skills, workspace/skills
This commit is contained in:
2026-09-10 16:54:57 +08:00
parent f3388c50e2
commit 3d3dd79df0
110 changed files with 18722 additions and 0 deletions
+369
View File
@@ -0,0 +1,369 @@
"""
行业热榜垂直(增强版) - Industry Hot Module
功能:
- 十大行业分类:科技互联网、游戏、汽车、金融财经、数码消费、娱乐影视、房产家居、医疗健康、旅游出行、餐饮消费
- 用户自主选择行业
- 行业描述和平台标注
"""
from typing import List, Dict, Optional, Any
from dataclasses import dataclass
from enum import Enum
import asyncio
# 十大行业映射
INDUSTRIES: Dict[str, Dict[str, Any]] = {
"科技互联网": {
"platforms": ["ithome", "36kr", "csdn", "juejin", "oschina", "infoq"],
"description": "IT之家、36氪、CSDN、稀土掘金、开源中国、InfoQ"
},
"游戏行业": {
"platforms": ["genshin", "miyoushe", "lol", "bilibili", "douyu", "huya", "netease-game"],
"description": "原神、米游社、英雄联盟、B站、斗鱼、虎牙、网易游戏"
},
"汽车行业": {
"platforms": ["autohome", "car", "懂车帝", "bitauto", "soufun-auto"],
"description": "汽车之家、懂车帝、易车网、苏宁汽车"
},
"金融财经": {
"platforms": ["sina-money", "eastmoney", "xueqiu", "jrj", "cnstock", "wallstreetcn", "money163"],
"description": "新浪财经、东方财富、雪球、金融界、中国财经网、华尔街见闻、网易财经"
},
"数码消费": {
"platforms": ["coolapk", "ithome", "sspai", "geekpark", "少数派", "smzdm"],
"description": "酷安、IT之家、少数派、什么值得买"
},
"娱乐影视": {
"platforms": ["weibo", "douban-group", "douban-movie", "mtime", "movie", "bilibili"],
"description": "微博、豆瓣、豆瓣电影、时光网、B站"
},
"房产家居": {
"platforms": ["lfang", "soufunianjia", "anjuke", "house", "lianjia"],
"description": "链家、安居客、房天下、贝壳找房"
},
"医疗健康": {
"platforms": ["zhihu", "知乎", "sina-health", "health", "baikemy", "丁香园"],
"description": "知乎、新浪健康、丁香园、百度健康"
},
"旅游出行": {
"platforms": ["mafengwo", "ctrip", "qunar", "飞猪", "马蜂窝", "携程"],
"description": "马蜂窝、携程、去哪儿、飞猪"
},
"餐饮消费": {
"platforms": ["dianping", "xiaohongshu", "大众点评", "ele.me", "meituan"],
"description": "大众点评、美团、饿了么、小红书"
}
}
# 所有行业名称
ALL_INDUSTRIES = list(INDUSTRIES.keys())
class IndustryMode(Enum):
"""行业模式"""
SINGLE = "single" # 单行业
MULTI = "multi" # 多行业
@dataclass
class IndustryConfig:
"""行业配置"""
industries: List[str] # 选择的行业列表
mode: IndustryMode = IndustryMode.SINGLE
items_per_platform: int = 10 # 每个平台显示的条目数
total_items: int = 50 # 总条目数限制
include_description: bool = True # 是否包含行业描述
class IndustryHot:
"""行业热榜类"""
def __init__(self, api_client=None, formatter=None):
"""
初始化行业热榜
Args:
api_client: API客户端实例(可选)
formatter: 格式化器实例(可选)
"""
self.api_client = api_client
self.formatter = formatter
self._all_platforms = self._get_all_platforms()
def _get_all_platforms(self) -> List[str]:
"""获取所有行业相关的平台"""
platforms = set()
for industry_info in INDUSTRIES.values():
platforms.update(industry_info.get("platforms", []))
return list(platforms)
async def fetch_all_hot_data(self, limit_per_platform: int = 10) -> List[Dict[str, Any]]:
"""
一次性获取全部平台的热榜数据
Args:
limit_per_platform: 每个平台获取的条目数
Returns:
全部平台的热榜数据列表
"""
all_items = []
if self.api_client:
for platform in self._all_platforms:
try:
items = await self.api_client.get_hot榜单(platform, limit=limit_per_platform)
if items:
for item in items:
item["source_platform"] = platform
all_items.extend(items)
except Exception as e:
print(f"Error fetching {platform}: {e}")
continue
return all_items
async def get_industry_options(self) -> str:
"""
获取行业选择选项(AI引导话术)
Returns:
格式化的行业选择文本
"""
options_text = "🏭 **请选择您关注的行业**\n\n"
for i, (industry, info) in enumerate(INDUSTRIES.items(), 1):
platforms_count = len(info["platforms"])
options_text += f"{i}. **{industry}**\n"
options_text += f" 📋 包含 {platforms_count} 个平台\n"
options_text += f" 🔗 {info['description']}\n\n"
options_text += "-" * 50 + "\n"
options_text += "💡 您可以输入行业名称或数字编号,支持多选(如:1,3或汽车+金融)"
return options_text
def parse_industries_from_input(self, user_input: str) -> List[str]:
"""
解析用户输入的行业
Args:
user_input: 用户输入的文本
Returns:
匹配的行业列表
"""
user_input = user_input.strip().lower()
matched_industries = []
# 处理数字选择
import re
number_pattern = re.findall(r'\d+', user_input)
for num in number_pattern:
idx = int(num) - 1
if 0 <= idx < len(ALL_INDUSTRIES):
matched_industries.append(ALL_INDUSTRIES[idx])
# 行业关键词映射(行业名称 -> 包含的关键词)
industry_keywords = {
"科技互联网": ["科技", "互联网", "IT", "技术"],
"游戏行业": ["游戏", "手游", "网游"],
"汽车行业": ["汽车", "车", "车企", "新能源车"],
"金融财经": ["金融", "财经", "投资", "理财", "股票"],
"数码消费": ["数码", "手机", "电脑", "电子"],
"娱乐影视": ["娱乐", "影视", "电影", "综艺", "明星"],
"房产家居": ["房产", "房", "家居", "装修", "买房"],
"医疗健康": ["医疗", "健康", "医药", "养生"],
"旅游出行": ["旅游", "出行", "旅行", "机票", "酒店"],
"餐饮消费": ["餐饮", "美食", "外卖", "餐厅", "消费"]
}
# 处理行业关键词
for industry, keywords in industry_keywords.items():
for keyword in keywords:
if keyword in user_input:
if industry not in matched_industries:
matched_industries.append(industry)
break
# 处理完整行业名称(向后兼容)
for industry in ALL_INDUSTRIES:
if industry.lower() in user_input or industry in user_input:
if industry not in matched_industries:
matched_industries.append(industry)
return matched_industries if matched_industries else []
async def get_industry_hot(self, industries: List[str], config: Optional[IndustryConfig] = None) -> Dict[str, Any]:
"""
获取行业热榜(新版:先全部获取,再按行业筛选)
Args:
industries: 行业列表
config: 配置对象(可选)
Returns:
行业热榜数据
"""
if config is None:
config = IndustryConfig(industries=industries)
# 步骤1:全部获取
all_items = await self.fetch_all_hot_data(limit_per_platform=config.items_per_platform)
# 步骤2:按行业筛选
# 获取所有相关平台
target_platforms = set()
for industry in industries:
if industry in INDUSTRIES:
target_platforms.update(INDUSTRIES[industry]["platforms"])
filtered_items = []
for item in all_items:
platform = item.get("source_platform", "")
if platform in target_platforms:
item["source_industry"] = next((ind for ind in industries if ind in INDUSTRIES and platform in INDUSTRIES[ind]["platforms"]), industries[0])
filtered_items.append(item)
# 去重和排序
merged_items = self._merge_items(filtered_items)
# 限制总数
merged_items = merged_items[:config.total_items]
return {
"industries": industries,
"industry_descriptions": {ind: INDUSTRIES[ind]["description"] for ind in industries},
"total_items": len(merged_items),
"items": merged_items
}
def _merge_items(self, items: List[Dict]) -> List[Dict]:
"""
合并和去重条目
Args:
items: 条目列表
Returns:
合并后的条目列表
"""
if not items:
return []
# 按标题去重
seen_titles = set()
unique_items = []
for item in items:
title = item.get("title", "").strip().lower()
if title and title not in seen_titles:
seen_titles.add(title)
unique_items.append(item)
# 按热度排序
unique_items.sort(key=lambda x: x.get("hot", 0) or x.get("score", 0), reverse=True)
return unique_items
def format_industry_response(self, hot_data: Dict[str, Any]) -> str:
"""
格式化行业热榜响应
Args:
hot_data: 热榜数据
Returns:
格式化的响应文本
"""
if not hot_data.get("items"):
return "❌ 暂无行业热榜数据"
industries = hot_data["industries"]
items = hot_data["items"]
response = f"🏭 **行业热榜 - {', '.join(industries)}**\n\n"
# 显示行业描述
for industry in industries:
desc = hot_data["industry_descriptions"].get(industry, "")
response += f"📌 **{industry}**: {desc}\n"
response += "-" * 50 + "\n"
response += f"共 {hot_data['total_items']} 条热榜\n\n"
# 按行业分组显示
items_by_industry = {}
for item in items:
industry = item.get("source_industry", "其他")
if industry not in items_by_industry:
items_by_industry[industry] = []
items_by_industry[industry].append(item)
for industry, ind_items in items_by_industry.items():
response += f"\n📊 **{industry}**\n"
for i, item in enumerate(ind_items[:5], 1): # 每个行业显示5条
title = item.get("title", "无标题")
hot = item.get("hot", item.get("score", ""))
platform = item.get("source_platform", "")
response += f"{i}. {title}\n"
if hot:
response += f" 🔥 {hot}"
if platform:
response += f" | 📱 {platform}"
response += "\n"
return response
async def process_user_request(self, user_input: str) -> Dict[str, Any]:
"""
处理用户请求
Args:
user_input: 用户输入
Returns:
处理结果
"""
# 解析行业
industries = self.parse_industries_from_input(user_input)
if not industries:
# 返回引导信息
return {
"action": "ask_industry",
"message": await self.get_industry_options()
}
# 获取热榜
hot_data = await self.get_industry_hot(industries)
# 格式化响应
response_text = self.format_industry_response(hot_data)
return {
"action": "show_industry_hot",
"data": hot_data,
"message": response_text
}
# 便捷函数
async def create_industry_hot(api_client=None, formatter=None) -> IndustryHot:
"""创建行业热榜实例"""
return IndustryHot(api_client=api_client, formatter=formatter)
if __name__ == "__main__":
# 测试代码
async def test():
industry_hot = await create_industry_hot()
print(await industry_hot.get_industry_options())
print("\n" + "="*50 + "\n")
result = await industry_hot.process_user_request("汽车和金融")
print(result["message"])
asyncio.run(test())