- 新增 plugins/code_editor.py: 精准代码编辑(搜索替换、批量编辑、diff对比) - 新增 plugins/code_search.py: 代码搜索与理解(跨文件搜索、符号提取、依赖分析) - 新增 plugins/git_tools.py: Git 版本控制(status/diff/log/commit/branch) - 新增 core/ 模块: 配置管理、引擎管理、对话处理、显示输出、代码沙箱 - 修复 requirements.txt: 使用正确的 pip 包名(Pillow、opencv-python 等) - 更新 unified_tool_manager.py: 兼容 Plugin 和 Liugin 两种类名 - 更新系统提示词: 增强编程工作流指导 本次更新由 mimo 自动化执行,与开发者无关。
174 lines
6.7 KiB
Python
174 lines
6.7 KiB
Python
import subprocess
|
|
import json
|
|
from urllib.parse import quote
|
|
import requests
|
|
|
|
|
|
class Liugin:
|
|
"""AI搜索插件 - 使用jina.ai进行智能搜索"""
|
|
|
|
def __init__(self):
|
|
self.usage = """AI搜索工具使用方法:/r
|
|
ai_search <操作> <参数>/r
|
|
例如:/r
|
|
- ai_search url https://www.example.com - 搜索网址内容/r
|
|
- ai_search search Python教程 - 普通搜索/r
|
|
- ai_search web 什么是人工智能 - 搜索网络内容/r
|
|
/r
|
|
详细说明:/r
|
|
- url操作: ai_search url <网址> - 提取并搜索指定网址的内容/r
|
|
- search操作: ai_search search <搜索词> - 使用必应搜索指定内容/r
|
|
- web操作: ai_search web <搜索词> - 使用必应搜索指定内容(与search相同)/r
|
|
/r
|
|
使用工具的JSON格式示例:/r
|
|
{"action": "use_tool", "tool": "ai_search", "args": "url https://www.example.com"} - 搜索网址内容/r
|
|
{"action": "use_tool", "tool": "ai_search", "args": "search Python教程"} - 普通搜索/r
|
|
{"action": "use_tool", "tool": "ai_search", "args": "web 什么是人工智能"} - 搜索网络内容/r
|
|
"""
|
|
self.cli = None # CLI实例引用
|
|
self.timeout = 30 # 请求超时时间(秒)
|
|
|
|
def set_cli(self, cli):
|
|
"""设置CLI实例引用"""
|
|
self.cli = cli
|
|
# 注册插件命令
|
|
self.cli.register_liugin_command('ai_search', self.command_handler)
|
|
self.cli.register_liugin_command('search', self.search_command_handler)
|
|
self.cli.register_liugin_command('web', self.web_command_handler)
|
|
|
|
def command_handler(self, args):
|
|
"""处理 /ai_search 命令"""
|
|
# 解析参数
|
|
parts = args.strip().split(maxsplit=1)
|
|
if len(parts) < 1:
|
|
return "请提供操作类型: url, search, web"
|
|
|
|
operation = parts[0].lower()
|
|
remaining_args = parts[1] if len(parts) > 1 else ""
|
|
|
|
# 调用实际的AI搜索功能
|
|
return self.handle(f"{operation} {remaining_args}")
|
|
|
|
def search_command_handler(self, args):
|
|
"""处理 /search 命令"""
|
|
return self.handle(f"search {args}")
|
|
|
|
def web_command_handler(self, args):
|
|
"""处理 /web 命令"""
|
|
return self.handle(f"search {args}")
|
|
|
|
def get_tool_info(self):
|
|
return {
|
|
"name": "ai_search",
|
|
"description": "AI搜索工具,使用jina.ai服务进行智能搜索,支持网址内容提取和网络搜索。当用户询问天气、新闻、汇率、股票、航班、实时信息、网络内容搜索等问题时,应该直接使用此工具。使用格式:ai_search search <搜索词> 或 ai_search url <网址>",
|
|
"keywords": ["搜索", "search", "网址", "url", "web", "AI搜索", "网络搜索", "内容提取", "天气", "新闻", "实时信息"],
|
|
"usage": """ai_search 工具使用说明:
|
|
JSON格式示例:
|
|
{\"action\": \"use_tool\", \"tool\": \"ai_search\", \"args\": \"url https://www.example.com\"} - 搜索网址内容
|
|
{\"action\": \"use_tool\", \"tool\": \"ai_search\", \"args\": \"search Python教程\"} - 普通搜索
|
|
{\"action\": \"use_tool\", \"tool\": \"ai_search\", \"args\": \"web 什么是人工智能\"} - 搜索网络内容"""
|
|
}
|
|
|
|
def handle(self, args):
|
|
"""处理AI搜索请求"""
|
|
try:
|
|
# 解析参数
|
|
parts = args.strip().split(maxsplit=1)
|
|
if len(parts) < 1:
|
|
return "错误:参数不足。请提供操作类型。\n可用操作: url, search, web"
|
|
|
|
operation = parts[0].lower()
|
|
|
|
if operation == "url":
|
|
# 搜索网址内容
|
|
if len(parts) < 2:
|
|
return "错误:请提供URL。格式: url <网址>"
|
|
|
|
url = parts[1].strip()
|
|
return self._search_url(url)
|
|
|
|
elif operation in ["search", "web"]:
|
|
# 普通搜索
|
|
if len(parts) < 2:
|
|
return "错误:请提供搜索词。格式: search <搜索词>"
|
|
|
|
query = parts[1].strip()
|
|
return self._search_web(query)
|
|
|
|
else:
|
|
return f"错误:不支持的操作 '{operation}'。支持的操作有: url, search, web。"
|
|
|
|
except Exception as e:
|
|
return f"AI搜索操作错误: {str(e)}"
|
|
|
|
def _search_url(self, url):
|
|
"""搜索网址内容(使用jina.ai提取)"""
|
|
try:
|
|
# 构建jina.ai的URL - 直接使用URL
|
|
jina_url = f"https://r.jina.ai/{url}"
|
|
|
|
result = self._execute_curl(jina_url)
|
|
|
|
if result.startswith("错误:"):
|
|
return result
|
|
|
|
return f"📄 网址内容 (来自 {url}):\n\n{result}"
|
|
|
|
except Exception as e:
|
|
return f"网址搜索错误: {str(e)}"
|
|
|
|
def _search_web(self, query):
|
|
"""普通搜索(使用jina.ai + 必应搜索)"""
|
|
try:
|
|
# 对搜索词进行URL编码,确保中文等特殊字符正确编码
|
|
# 使用safe=''确保所有非字母数字字符都被编码
|
|
encoded_query = quote(query, safe='')
|
|
|
|
# 构建必应搜索URL
|
|
bing_url = f"https://cn.bing.com/search?q={encoded_query}"
|
|
|
|
# 构建jina.ai的URL - 直接使用必应URL,不需要二次编码
|
|
jina_url = f"https://r.jina.ai/{bing_url}"
|
|
|
|
result = self._execute_curl(jina_url)
|
|
|
|
if result.startswith("错误:"):
|
|
return result
|
|
|
|
return f"🔍 搜索结果 (搜索词: {query}):\n\n{result}"
|
|
|
|
except Exception as e:
|
|
return f"网络搜索错误: {str(e)}"
|
|
|
|
def _execute_curl(self, url):
|
|
"""使用 requests 库获取内容(替代 curl 命令)"""
|
|
try:
|
|
# 使用 requests 库发送请求
|
|
response = requests.get(
|
|
url,
|
|
timeout=self.timeout,
|
|
headers={'User-Agent': 'Mozilla/5.0 (compatible; AI-Search-Bot)'}
|
|
)
|
|
|
|
# 检查状态码
|
|
if response.status_code != 200:
|
|
return f"错误:HTTP请求失败,状态码: {response.status_code}"
|
|
|
|
# 获取内容
|
|
content = response.text.strip()
|
|
|
|
if not content:
|
|
return "错误:未获取到任何内容"
|
|
|
|
# 限制输出长度以避免过长输出
|
|
if len(content) > 5000:
|
|
content = content[:5000] + f"\n\n... (内容已截断,完整内容共{len(content)}字符)"
|
|
|
|
return content
|
|
|
|
except requests.Timeout:
|
|
return f"错误:请求超时 (>{self.timeout}秒)"
|
|
except requests.ConnectionError:
|
|
return "错误:网络连接失败,请检查网络"
|
|
except Exception as e:
|
|
return f"错误:请求时发生错误: {str(e)}" |