update:简化新闻源配置

This commit is contained in:
hrz
2025-06-30 14:24:46 +08:00
parent 54ccae8665
commit 7619979046
5 changed files with 151 additions and 88 deletions
+54 -33
View File
@@ -13,7 +13,7 @@
3. 选择要配置的智能体 3. 选择要配置的智能体
4. 点击"编辑功能"按钮 4. 点击"编辑功能"按钮
5. 在右侧参数配置区域找到"newsnow新闻聚合"插件 5. 在右侧参数配置区域找到"newsnow新闻聚合"插件
6. 在"新闻源配置"字段中输入JSON格式的新闻源配置 6. 在"新闻源配置"字段中输入分号分隔的中文名称
### 2. 配置文件方式 ### 2. 配置文件方式
@@ -23,62 +23,83 @@
plugins: plugins:
get_news_from_newsnow: get_news_from_newsnow:
url: "https://newsnow.busiyi.world/api/s?id=" url: "https://newsnow.busiyi.world/api/s?id="
news_sources: news_sources: "澎湃新闻;百度热搜;财联社;微博;抖音"
thepaper: "澎湃新闻"
baidu: "百度热搜"
cls-depth: "财联社"
# 可以添加更多新闻源
weibo: "微博头条"
douyin: "抖音热搜"
solidot: "奇客Solidot"
``` ```
## 新闻源配置格式 ## 新闻源配置格式
新闻源配置使用JSON格式,格式为: 新闻源配置使用分号分隔的中文名称,格式为:
```json ```
{ 中文名称1;中文名称2;中文名称3
"source_id": "显示名称",
"source_id2": "显示名称2"
}
``` ```
### 配置示例 ### 配置示例
```json
{
"thepaper": "澎湃新闻",
"baidu": "百度热搜",
"cls-depth": "财联社",
"weibo": "微博头条",
"douyin": "抖音热搜",
"solidot": "奇客Solidot"
}
``` ```
澎湃新闻;百度热搜;财联社;微博;抖音;知乎;36氪
```
## 支持的新闻源
插件支持以下新闻源的中文名称:
- 澎湃新闻
- 百度热搜
- 财联社
- 微博
- 抖音
- 知乎
- 36氪
- 华尔街见闻
- IT之家
- 今日头条
- 虎扑
- 哔哩哔哩
- 快手
- 雪球
- 格隆汇
- 法布财经
- 金十数据
- 牛客
- 少数派
- 稀土掘金
- 凤凰网
- 虫部落
- 联合早报
- 酷安
- 远景论坛
- 参考消息
- 卫星通讯社
- 百度贴吧
- 靠谱新闻
- 以及更多...
## 默认配置 ## 默认配置
如果未配置新闻源,插件将使用以下默认配置: 如果未配置新闻源,插件将使用以下默认配置:
```json ```
{ 澎湃新闻;百度热搜;财联社
"thepaper": "澎湃新闻",
"baidu": "百度热搜",
"cls-depth": "财联社"
}
``` ```
## 使用说明 ## 使用说明
1. **配置新闻源**:在Web界面或配置文件中设置新闻源 1. **配置新闻源**:在Web界面或配置文件中设置新闻源的中文名称,用分号分隔
2. **调用插件**:用户可以说"播报新闻"或"获取新闻" 2. **调用插件**:用户可以说"播报新闻"或"获取新闻"
3. **指定新闻源**:用户可以说"播报澎湃新闻"或"获取百度热搜" 3. **指定新闻源**:用户可以说"播报澎湃新闻"或"获取百度热搜"
4. **获取详情**:用户可以说"详细介绍这条新闻" 4. **获取详情**:用户可以说"详细介绍这条新闻"
## 工作原理
1. 插件接受中文名称作为参数(如"澎湃新闻")
2. 根据配置的新闻源列表,将中文名称转换为对应的英文ID(如"thepaper"
3. 使用英文ID调用API获取新闻数据
4. 返回新闻内容给用户
## 注意事项 ## 注意事项
1. 新闻源的 `source_id` 必须与API接口支持的ID一致 1. 配置的中文名称必须与 CHANNEL_MAP 中定义的名称完全一致
2. 配置更改后需要重启服务或重新加载配置 2. 配置更改后需要重启服务或重新加载配置
3. 如果配置的新闻源无效,插件会自动使用默认新闻源 3. 如果配置的新闻源无效,插件会自动使用默认新闻源
4. JSON格式必须正确,否则会使用默认配置 4. 多个新闻源之间使用英文分号(;)分隔,不要使用中文分号(;)
@@ -1,6 +1,3 @@
-- 更新 get_news_from_newsnow 插件配置,添加新闻源配置字段
-- 执行时间:2025-06-25
-- 更新现有的 get_news_from_newsnow 插件配置 -- 更新现有的 get_news_from_newsnow 插件配置
UPDATE ai_model_provider UPDATE ai_model_provider
SET fields = JSON_ARRAY( SET fields = JSON_ARRAY(
@@ -12,10 +9,10 @@ SET fields = JSON_ARRAY(
), ),
JSON_OBJECT( JSON_OBJECT(
'key', 'news_sources', 'key', 'news_sources',
'type', 'json', 'type', 'string',
'label', '新闻源配置', 'label', '新闻源配置',
'default', '{"thepaper":"澎湃新闻","baidu":"百度热搜","cls-depth":"财联社"}' 'default', '澎湃新闻;百度热搜;财联社'
) )
) )
WHERE provider_code = 'get_news_from_newsnow' WHERE provider_code = 'get_news_from_newsnow'
AND model_type = 'Plugin'; AND model_type = 'Plugin';
@@ -227,12 +227,12 @@ databaseChangeLog:
encoding: utf8 encoding: utf8
path: classpath:db/changelog/202506191643.sql path: classpath:db/changelog/202506191643.sql
- changeSet: - changeSet:
id: 202506251619 id: 202506251620
author: Tink author: Tink
changes: changes:
- sqlFile: - sqlFile:
encoding: utf8 encoding: utf8
path: classpath:db/changelog/202506251619.sql path: classpath:db/changelog/202506251620.sql
- changeSet: - changeSet:
id: 202506261637 id: 202506261637
author: hrz author: hrz
+4 -7
View File
@@ -123,10 +123,7 @@ plugins:
finance_rss_url: "https://www.chinanews.com.cn/rss/finance.xml" finance_rss_url: "https://www.chinanews.com.cn/rss/finance.xml"
get_news_from_newsnow: get_news_from_newsnow:
url: "https://newsnow.busiyi.world/api/s?id=" url: "https://newsnow.busiyi.world/api/s?id="
news_sources: news_sources: "澎湃新闻;百度热搜;财联社"
thepaper: "澎湃新闻"
baidu: "百度热搜"
cls-depth: "财联社"
home_assistant: home_assistant:
devices: devices:
- 客厅,玩具灯,switch.cuco_cn_460494544_cp1_on_p_2_1 - 客厅,玩具灯,switch.cuco_cn_460494544_cp1_on_p_2_1
@@ -164,7 +161,7 @@ end_prompt:
enable: true # 是否开启结束语 enable: true # 是否开启结束语
# 结束语 # 结束语
prompt: | prompt: |
请你以时间过得真快未来头,用富有感情、依依不舍的话来结束这场对话吧! 请你以"时间过得真快"未来头,用富有感情、依依不舍的话来结束这场对话吧!
# 具体处理时选择的模块(The module selected for specific processing) # 具体处理时选择的模块(The module selected for specific processing)
selected_module: selected_module:
@@ -201,7 +198,7 @@ Intent:
# 如果你的不想使用selected_module.LLM意图识别,这里最好使用独立的LLM作为意图识别,例如使用免费的ChatGLMLLM # 如果你的不想使用selected_module.LLM意图识别,这里最好使用独立的LLM作为意图识别,例如使用免费的ChatGLMLLM
llm: ChatGLMLLM llm: ChatGLMLLM
# plugins_func/functions下的模块,可以通过配置,选择加载哪个模块,加载后对话支持相应的function调用 # plugins_func/functions下的模块,可以通过配置,选择加载哪个模块,加载后对话支持相应的function调用
# 系统默认已经记载handle_exit_intent(退出识别)”、“play_music(音乐播放)插件,请勿重复加载 # 系统默认已经记载"handle_exit_intent(退出识别)"、"play_music(音乐播放)"插件,请勿重复加载
# 下面是加载查天气、角色切换、加载查新闻的插件示例 # 下面是加载查天气、角色切换、加载查新闻的插件示例
functions: functions:
- get_weather - get_weather
@@ -211,7 +208,7 @@ Intent:
# 不需要动type # 不需要动type
type: function_call type: function_call
# plugins_func/functions下的模块,可以通过配置,选择加载哪个模块,加载后对话支持相应的function调用 # plugins_func/functions下的模块,可以通过配置,选择加载哪个模块,加载后对话支持相应的function调用
# 系统默认已经记载handle_exit_intent(退出识别)”、“play_music(音乐播放)插件,请勿重复加载 # 系统默认已经记载"handle_exit_intent(退出识别)"、"play_music(音乐播放)"插件,请勿重复加载
# 下面是加载查天气、角色切换、加载查新闻的插件示例 # 下面是加载查天气、角色切换、加载查新闻的插件示例
functions: functions:
- change_role - change_role
@@ -8,61 +8,98 @@ from markitdown import MarkItDown
TAG = __name__ TAG = __name__
logger = setup_logging() logger = setup_logging()
# 默认新闻来源字典,当配置中没有指定时使用 CHANNEL_MAP = {
DEFAULT_NEWS_SOURCES = { "V2EX": "v2ex-share",
"thepaper": "澎湃新闻", "知乎": "zhihu",
"baidu": "百度热搜", "微博": "weibo",
"cls-depth": "财联社", "联合早报": "zaobao",
"酷安": "coolapk",
"MKTNews": "mktnews-flash",
"华尔街见闻": "wallstreetcn-quick",
"36氪": "36kr-quick",
"抖音": "douyin",
"虎扑": "hupu",
"百度贴吧": "tieba",
"今日头条": "toutiao",
"IT之家": "ithome",
"澎湃新闻": "thepaper",
"卫星通讯社": "sputniknewscn",
"参考消息": "cankaoxiaoxi",
"远景论坛": "pcbeta-windows11",
"财联社": "cls-depth",
"雪球": "xueqiu-hotstock",
"格隆汇": "gelonghui",
"法布财经": "fastbull-express",
"Solidot": "solidot",
"Hacker News": "hackernews",
"Product Hunt": "producthunt",
"Github": "github-trending-today",
"哔哩哔哩": "bilibili-hot-search",
"快手": "kuaishou",
"靠谱新闻": "kaopu",
"金十数据": "jin10",
"百度热搜": "baidu",
"牛客": "nowcoder",
"少数派": "sspai",
"稀土掘金": "juejin",
"凤凰网": "ifeng",
"虫部落": "chongbuluo-latest",
} }
# 默认新闻来源字典,当配置中没有指定时使用
DEFAULT_NEWS_SOURCES = "澎湃新闻;百度热搜;财联社"
def get_news_sources_from_config(conn): def get_news_sources_from_config(conn):
"""从配置中获取新闻源字""" """从配置中获取新闻源字符串"""
try: try:
# 尝试从插件配置中获取新闻源 # 尝试从插件配置中获取新闻源
if (conn.config.get("plugins") and if (
conn.config["plugins"].get("get_news_from_newsnow") and conn.config.get("plugins")
conn.config["plugins"]["get_news_from_newsnow"].get("news_sources")): and conn.config["plugins"].get("get_news_from_newsnow")
and conn.config["plugins"]["get_news_from_newsnow"].get("news_sources")
# 如果配置中是字符串,尝试解析JSON ):
news_sources_config = conn.config["plugins"]["get_news_from_newsnow"]["news_sources"] # 获取配置的新闻源字符串
if isinstance(news_sources_config, str): news_sources_config = conn.config["plugins"]["get_news_from_newsnow"][
try: "news_sources"
return json.loads(news_sources_config) ]
except json.JSONDecodeError:
logger.bind(tag=TAG).warning("新闻源配置JSON格式错误,使用默认配置") if isinstance(news_sources_config, str) and news_sources_config.strip():
return DEFAULT_NEWS_SOURCES logger.bind(tag=TAG).debug(f"使用配置的新闻源: {news_sources_config}")
elif isinstance(news_sources_config, dict):
return news_sources_config return news_sources_config
else: else:
logger.bind(tag=TAG).warning("新闻源配置格式错误,使用默认配置") logger.bind(tag=TAG).warning("新闻源配置为空或格式错误,使用默认配置")
return DEFAULT_NEWS_SOURCES
else: else:
logger.bind(tag=TAG).debug("未找到新闻源配置,使用默认配置") logger.bind(tag=TAG).debug("未找到新闻源配置,使用默认配置")
return DEFAULT_NEWS_SOURCES
return DEFAULT_NEWS_SOURCES
except Exception as e: except Exception as e:
logger.bind(tag=TAG).error(f"获取新闻源配置失败: {e},使用默认配置") logger.bind(tag=TAG).error(f"获取新闻源配置失败: {e},使用默认配置")
return DEFAULT_NEWS_SOURCES return DEFAULT_NEWS_SOURCES
# 静态函数描述,使用默认新闻源生成描述 # 从CHANNEL_MAP获取所有可用的新闻源名称
available_sources = list(CHANNEL_MAP.keys())
example_sources_str = "".join(available_sources)
GET_NEWS_FROM_NEWSNOW_FUNCTION_DESC = { GET_NEWS_FROM_NEWSNOW_FUNCTION_DESC = {
"type": "function", "type": "function",
"function": { "function": {
"name": "get_news_from_newsnow", "name": "get_news_from_newsnow",
"description": ( "description": (
"获取最新新闻,随机选择一条新闻进行播报。" "获取最新新闻,随机选择一条新闻进行播报。"
"用户可以选择不同的新闻源,如澎湃新闻(thepaper)、百度热搜(baidu)、财联社(cls-depth)等。" f"用户可以选择不同的新闻源,标准的名称是:{example_sources_str}"
"如果没有指定,默认从澎湃新闻获取。" "例如用户要求百度新闻,其实就是百度热搜。如果没有指定,默认从澎湃新闻获取。"
"用户可以要求获取详细内容,此时会获取新闻的详细内容。" "用户可以要求获取详细内容,此时会获取新闻的详细内容。"
"注意:实际可用的新闻源取决于系统配置。"
), ),
"parameters": { "parameters": {
"type": "object", "type": "object",
"properties": { "properties": {
"source": { "source": {
"type": "string", "type": "string",
"description": "新闻源,例如thepaper、baidu、cls-depth等。可选参数,如果不提供则使用默认新闻源", "description": f"新闻源的标准中文名称,例如{example_sources_str}等。可选参数,如果不提供则使用默认新闻源",
}, },
"detail": { "detail": {
"type": "boolean", "type": "boolean",
@@ -134,13 +171,13 @@ def fetch_news_detail(url):
ToolType.SYSTEM_CTL, ToolType.SYSTEM_CTL,
) )
def get_news_from_newsnow( def get_news_from_newsnow(
conn, source: str = "thepaper", detail: bool = False, lang: str = "zh_CN" conn, source: str = "澎湃新闻", detail: bool = False, lang: str = "zh_CN"
): ):
"""获取新闻并随机选择一条进行播报,或获取上一条新闻的详细内容""" """获取新闻并随机选择一条进行播报,或获取上一条新闻的详细内容"""
try: try:
# 获取当前配置的新闻源 # 获取当前配置的新闻源
news_sources = get_news_sources_from_config(conn) news_sources = get_news_sources_from_config(conn)
# 如果detail为True,获取上一条新闻的详细内容 # 如果detail为True,获取上一条新闻的详细内容
detail = str(detail).lower() == "true" detail = str(detail).lower() == "true"
if detail: if detail:
@@ -158,7 +195,7 @@ def get_news_from_newsnow(
url = conn.last_newsnow_link.get("url") url = conn.last_newsnow_link.get("url")
title = conn.last_newsnow_link.get("title", "未知标题") title = conn.last_newsnow_link.get("title", "未知标题")
source_id = conn.last_newsnow_link.get("source_id", "thepaper") source_id = conn.last_newsnow_link.get("source_id", "thepaper")
source_name = news_sources.get(source_id, "未知来源") source_name = CHANNEL_MAP.get(source_id, "未知来源")
if not url or url == "#": if not url or url == "#":
return ActionResponse( return ActionResponse(
@@ -192,21 +229,32 @@ def get_news_from_newsnow(
return ActionResponse(Action.REQLLM, detail_report, None) return ActionResponse(Action.REQLLM, detail_report, None)
# 否则,获取新闻列表并随机选择一条 # 否则,获取新闻列表并随机选择一条
# 验证新闻源是否有效,如果无效则使用默认源 # 将中文名称转换为英文ID
if source not in news_sources: english_source_id = None
logger.bind(tag=TAG).warning(f"无效的新闻源: {source},使用默认源thepaper")
source = "thepaper"
source_name = news_sources.get(source, "澎湃新闻") # 检查输入的中文名称是否在配置的新闻源中
logger.bind(tag=TAG).info(f"获取新闻: 新闻源={source}({source_name})") news_sources_list = [
name.strip() for name in news_sources.split(";") if name.strip()
]
if source in news_sources_list:
# 如果输入的中文名称在配置的新闻源中,在 CHANNEL_MAP 中查找对应的英文ID
english_source_id = CHANNEL_MAP.get(source)
# 如果找不到对应的英文ID,使用默认源
if not english_source_id:
logger.bind(tag=TAG).warning(f"无效的新闻源: {source},使用默认源澎湃新闻")
english_source_id = "thepaper"
source = "澎湃新闻"
logger.bind(tag=TAG).info(f"获取新闻: 新闻源={source}({english_source_id})")
# 获取新闻列表 # 获取新闻列表
news_items = fetch_news_from_api(conn, source) news_items = fetch_news_from_api(conn, english_source_id)
if not news_items: if not news_items:
return ActionResponse( return ActionResponse(
Action.REQLLM, Action.REQLLM,
f"抱歉,未能从{source_name}获取到新闻信息,请稍后再试或尝试其他新闻源。", f"抱歉,未能从{source}获取到新闻信息,请稍后再试或尝试其他新闻源。",
None, None,
) )
@@ -219,14 +267,14 @@ def get_news_from_newsnow(
conn.last_newsnow_link = { conn.last_newsnow_link = {
"url": selected_news.get("url", "#"), "url": selected_news.get("url", "#"),
"title": selected_news.get("title", "未知标题"), "title": selected_news.get("title", "未知标题"),
"source_id": source, "source_id": english_source_id,
} }
# 构建新闻报告 # 构建新闻报告
news_report = ( news_report = (
f"根据下列数据,用{lang}回应用户的新闻查询请求:\n\n" f"根据下列数据,用{lang}回应用户的新闻查询请求:\n\n"
f"新闻标题: {selected_news['title']}\n" f"新闻标题: {selected_news['title']}\n"
# f"新闻来源: {source_name}\n" # f"新闻来源: {source}\n"
f"(请以自然、流畅的方式向用户播报这条新闻标题," f"(请以自然、流畅的方式向用户播报这条新闻标题,"
f"提示用户可以要求获取详细内容,此时会获取新闻的详细内容。)" f"提示用户可以要求获取详细内容,此时会获取新闻的详细内容。)"
) )