diff --git "a/tools/tool_mem0_add/1.0.0/Mem0\350\256\260\345\277\206\346\267\273\345\212\240.tool" "b/tools/tool_mem0_add/1.0.0/Mem0\350\256\260\345\277\206\346\267\273\345\212\240.tool" new file mode 100644 index 0000000..f305fad Binary files /dev/null and "b/tools/tool_mem0_add/1.0.0/Mem0\350\256\260\345\277\206\346\267\273\345\212\240.tool" differ diff --git a/tools/tool_mem0_add/README.md b/tools/tool_mem0_add/README.md new file mode 100644 index 0000000..fb86e3a --- /dev/null +++ b/tools/tool_mem0_add/README.md @@ -0,0 +1,26 @@ +# Mem0 记忆添加工具 + +基于 mem0 API 的单入口工具,用于向指定用户写入一条记忆。 + +## 功能说明 +- 添加一条用户或助手消息到 Mem0 +- 支持 metadata +- 支持可选 agent_id +- 使用官方 `POST /v1/memories/` 接口 +- 注意:Mem0 默认异步处理,写入后可能需要等待 2-3 秒再检索 + +## 参数说明 +### 启动参数 +| 参数 | 组件类型 | 必填 | 说明 | +| :--- | :--- | :--- | :--- | +| `api_key` | 密码框 | 是 | Mem0 API Key | +| `base_url` | 文本框 | 否 | API 地址,默认 `https://api.mem0.ai/v1` | + +### 输入参数 +| 参数名 | 数据类型 | 必填 | 来源 | 说明 | +| :--- | :--- | :--- | :--- | :--- | +| `user_id` | string | 是 | 引用参数 | 用户唯一标识 | +| `content` | string | 是 | 引用参数 | 要写入的记忆内容 | +| `role` | string | 否 | 引用参数 | 角色,默认 `user` | +| `agent_id` | string | 否 | 引用参数 | agent 唯一标识 | +| `metadata` | string | 否 | 引用参数 | JSON 字符串格式的元数据 | diff --git a/tools/tool_mem0_add/add_memory.py b/tools/tool_mem0_add/add_memory.py new file mode 100644 index 0000000..6d3e870 --- /dev/null +++ b/tools/tool_mem0_add/add_memory.py @@ -0,0 +1,57 @@ +import json +import requests + + +def add_memory(user_id: str, content: str, role: str = "user", agent_id: str = "", metadata: str = "", api_key: str = "", base_url: str = "https://api.mem0.ai/v1"): + try: + if not user_id: + return json.dumps({"success": False, "message": "user_id 不能为空", "error": "missing_user_id"}, ensure_ascii=False) + if not content: + return json.dumps({"success": False, "message": "content 不能为空", "error": "missing_content"}, ensure_ascii=False) + if not api_key: + return json.dumps({"success": False, "message": "api_key 不能为空", "error": "missing_api_key"}, ensure_ascii=False) + + payload = { + "messages": [{"role": role or "user", "content": content}], + "user_id": user_id, + "infer": True, + "version": "v2" + } + if agent_id: + payload["agent_id"] = agent_id + if metadata: + try: + payload["metadata"] = json.loads(metadata) + except Exception: + return json.dumps({"success": False, "message": "metadata 必须是合法 JSON 字符串", "error": "invalid_metadata_json"}, ensure_ascii=False) + + rep = requests.post( + url=f"{base_url.rstrip('/')}/memories/", + headers={ + "Content-Type": "application/json", + "Authorization": f"Token {api_key}", + "Accept": "application/json" + }, + json=payload, + timeout=30 + ) + rep.raise_for_status() + data = rep.json() + return json.dumps({"success": True, "message": "记忆添加成功", "data": data}, ensure_ascii=False) + except requests.exceptions.HTTPError as e: + detail = None + try: + detail = e.response.json() + except Exception: + detail = e.response.text if e.response is not None else str(e) + return json.dumps({ + "success": False, + "message": "添加记忆失败", + "error": str(e), + "status_code": e.response.status_code if e.response is not None else None, + "details": detail + }, ensure_ascii=False) + except requests.exceptions.RequestException as e: + return json.dumps({"success": False, "message": "添加记忆请求失败", "error": str(e)}, ensure_ascii=False) + except Exception as e: + return json.dumps({"success": False, "message": "处理添加记忆响应时发生错误", "error": str(e)}, ensure_ascii=False) diff --git a/tools/tool_mem0_add/data.yaml b/tools/tool_mem0_add/data.yaml new file mode 100644 index 0000000..a4b1981 --- /dev/null +++ b/tools/tool_mem0_add/data.yaml @@ -0,0 +1,5 @@ +name: Mem0记忆添加 +tags: + - 模型记忆 +title: 添加内容到 Mem0 记忆库 +description: 添加内容到 Mem0 记忆库,支持附带 metadata 和 agent_id diff --git a/tools/tool_mem0_add/logo.png b/tools/tool_mem0_add/logo.png new file mode 100644 index 0000000..e05a01f Binary files /dev/null and b/tools/tool_mem0_add/logo.png differ diff --git "a/tools/tool_mem0_get/1.0.0/Mem0\350\256\260\345\277\206\350\216\267\345\217\226.tool" "b/tools/tool_mem0_get/1.0.0/Mem0\350\256\260\345\277\206\350\216\267\345\217\226.tool" new file mode 100644 index 0000000..7c2ce58 Binary files /dev/null and "b/tools/tool_mem0_get/1.0.0/Mem0\350\256\260\345\277\206\350\216\267\345\217\226.tool" differ diff --git a/tools/tool_mem0_get/README.md b/tools/tool_mem0_get/README.md new file mode 100644 index 0000000..7d6ed9d --- /dev/null +++ b/tools/tool_mem0_get/README.md @@ -0,0 +1,25 @@ +# Mem0 记忆获取工具 + +基于 mem0 API 的单入口工具,用于获取指定范围内的记忆列表。 + +## 功能说明 +- 获取记忆列表 +- 支持 user_id / agent_id / app_id / run_id 作用域过滤 +- 至少需要提供一个范围参数 +- 当提供多个范围参数时,内部使用 `OR` 过滤 +- 使用官方 `POST /v2/memories/` 接口 + +## 参数说明 +### 启动参数 +| 参数 | 组件类型 | 必填 | 说明 | +| :--- | :--- | :--- | :--- | +| `api_key` | 密码框 | 是 | Mem0 API Key | +| `base_url` | 文本框 | 否 | API 地址,默认 `https://api.mem0.ai` | + +### 输入参数 +| 参数名 | 数据类型 | 必填 | 来源 | 说明 | +| :--- | :--- | :--- | :--- | :--- | +| `user_id` | string | 否 | 引用参数 | 用户唯一标识 | +| `agent_id` | string | 否 | 引用参数 | agent 唯一标识 | +| `app_id` | string | 否 | 引用参数 | 应用唯一标识 | +| `run_id` | string | 否 | 引用参数 | 运行/会话唯一标识 | diff --git a/tools/tool_mem0_get/data.yaml b/tools/tool_mem0_get/data.yaml new file mode 100644 index 0000000..2c03e05 --- /dev/null +++ b/tools/tool_mem0_get/data.yaml @@ -0,0 +1,5 @@ +name: Mem0记忆获取 +tags: + - 模型记忆 +title: 获取用户在 Mem0 中的记忆列表 +description: 获取指定用户在 Mem0 中的记忆列表,可按关键词过滤 diff --git a/tools/tool_mem0_get/get_memories.py b/tools/tool_mem0_get/get_memories.py new file mode 100644 index 0000000..ec43e8c --- /dev/null +++ b/tools/tool_mem0_get/get_memories.py @@ -0,0 +1,63 @@ +import json +import requests + + +def get_memories(user_id: str = "", agent_id: str = "", app_id: str = "", run_id: str = "", api_key: str = "", base_url: str = "https://api.mem0.ai"): + try: + if not api_key: + return json.dumps({"success": False, "message": "api_key 不能为空", "error": "missing_api_key"}, ensure_ascii=False) + if not any([user_id, agent_id, app_id, run_id]): + return json.dumps({ + "success": False, + "message": "user_id、agent_id、app_id、run_id 至少需要提供一个", + "error": "missing_scope_filter" + }, ensure_ascii=False) + + filters = [] + if user_id: + filters.append({"user_id": user_id}) + if agent_id: + filters.append({"agent_id": agent_id}) + if app_id: + filters.append({"app_id": app_id}) + if run_id: + filters.append({"run_id": run_id}) + + payload = { + "version": "v2" + } + if len(filters) == 1: + payload["filters"] = filters[0] + else: + payload["filters"] = {"OR": filters} + + rep = requests.post( + url=f"{base_url.rstrip('/')}/v2/memories/", + headers={ + "Content-Type": "application/json", + "Authorization": f"Token {api_key}", + "Accept": "application/json" + }, + json=payload, + timeout=30 + ) + rep.raise_for_status() + data = rep.json() + return json.dumps({"success": True, "message": "记忆获取成功", "data": data}, ensure_ascii=False) + except requests.exceptions.HTTPError as e: + detail = None + try: + detail = e.response.json() + except Exception: + detail = e.response.text if e.response is not None else str(e) + return json.dumps({ + "success": False, + "message": "获取记忆失败", + "error": str(e), + "status_code": e.response.status_code if e.response is not None else None, + "details": detail + }, ensure_ascii=False) + except requests.exceptions.RequestException as e: + return json.dumps({"success": False, "message": "获取记忆请求失败", "error": str(e)}, ensure_ascii=False) + except Exception as e: + return json.dumps({"success": False, "message": "处理获取记忆响应时发生错误", "error": str(e)}, ensure_ascii=False) diff --git a/tools/tool_mem0_get/logo.png b/tools/tool_mem0_get/logo.png new file mode 100644 index 0000000..e05a01f Binary files /dev/null and b/tools/tool_mem0_get/logo.png differ diff --git "a/tools/tool_mem0_search/1.0.0/Mem0\350\256\260\345\277\206\346\243\200\347\264\242.tool" "b/tools/tool_mem0_search/1.0.0/Mem0\350\256\260\345\277\206\346\243\200\347\264\242.tool" new file mode 100644 index 0000000..c8cdf20 Binary files /dev/null and "b/tools/tool_mem0_search/1.0.0/Mem0\350\256\260\345\277\206\346\243\200\347\264\242.tool" differ diff --git a/tools/tool_mem0_search/README.md b/tools/tool_mem0_search/README.md new file mode 100644 index 0000000..2997f60 --- /dev/null +++ b/tools/tool_mem0_search/README.md @@ -0,0 +1,24 @@ +# Mem0 记忆检索工具 + +基于 mem0 API 的单入口工具,用于按语义搜索指定范围内的相关记忆。 + +## 功能说明 +- 基于 query 搜索相关记忆 +- 支持 user_id / agent_id 范围限制 +- 当同时提供 user_id 和 agent_id 时,内部使用 `OR` 过滤,避免官方文档提到的空结果问题 +- 使用官方 `POST /v2/memories/search/` 接口 + +## 参数说明 +### 启动参数 +| 参数 | 组件类型 | 必填 | 说明 | +| :--- | :--- | :--- | :--- | +| `api_key` | 密码框 | 是 | Mem0 API Key | +| `base_url` | 文本框 | 否 | API 地址,默认 `https://api.mem0.ai` | + +### 输入参数 +| 参数名 | 数据类型 | 必填 | 来源 | 说明 | +| :--- | :--- | :--- | :--- | :--- | +| `query` | string | 是 | 引用参数 | 搜索语句 | +| `user_id` | string | 否 | 引用参数 | 用户唯一标识 | +| `agent_id` | string | 否 | 引用参数 | agent 唯一标识 | +| `top_k` | int | 否 | 自定义参数 | 返回数量,默认 5 | diff --git a/tools/tool_mem0_search/data.yaml b/tools/tool_mem0_search/data.yaml new file mode 100644 index 0000000..7f1e8c6 --- /dev/null +++ b/tools/tool_mem0_search/data.yaml @@ -0,0 +1,5 @@ +name: Mem0记忆检索 +tags: + - 模型记忆 +title: 语义检索 Mem0 记忆 +description: 根据查询语句在 Mem0 中检索指定用户的相关记忆 diff --git a/tools/tool_mem0_search/logo.png b/tools/tool_mem0_search/logo.png new file mode 100644 index 0000000..e05a01f Binary files /dev/null and b/tools/tool_mem0_search/logo.png differ diff --git a/tools/tool_mem0_search/search_memory.py b/tools/tool_mem0_search/search_memory.py new file mode 100644 index 0000000..8989e6d --- /dev/null +++ b/tools/tool_mem0_search/search_memory.py @@ -0,0 +1,58 @@ +import json +import requests + + +def search_memory(query: str, user_id: str = "", agent_id: str = "", top_k: int = 5, api_key: str = "", base_url: str = "https://api.mem0.ai"): + try: + if not query: + return json.dumps({"success": False, "message": "query 不能为空", "error": "missing_query"}, ensure_ascii=False) + if not api_key: + return json.dumps({"success": False, "message": "api_key 不能为空", "error": "missing_api_key"}, ensure_ascii=False) + + payload = { + "query": query, + "version": "v2", + "top_k": top_k + } + + filters = [] + if user_id: + filters.append({"user_id": user_id}) + if agent_id: + filters.append({"agent_id": agent_id}) + + if len(filters) == 1: + payload["filters"] = filters[0] + elif len(filters) > 1: + payload["filters"] = {"OR": filters} + + rep = requests.post( + url=f"{base_url.rstrip('/')}/v2/memories/search/", + headers={ + "Content-Type": "application/json", + "Authorization": f"Token {api_key}", + "Accept": "application/json" + }, + json=payload, + timeout=30 + ) + rep.raise_for_status() + data = rep.json() + return json.dumps({"success": True, "message": "记忆检索成功", "data": data}, ensure_ascii=False) + except requests.exceptions.HTTPError as e: + detail = None + try: + detail = e.response.json() + except Exception: + detail = e.response.text if e.response is not None else str(e) + return json.dumps({ + "success": False, + "message": "记忆检索失败", + "error": str(e), + "status_code": e.response.status_code if e.response is not None else None, + "details": detail + }, ensure_ascii=False) + except requests.exceptions.RequestException as e: + return json.dumps({"success": False, "message": "记忆检索请求失败", "error": str(e)}, ensure_ascii=False) + except Exception as e: + return json.dumps({"success": False, "message": "处理记忆检索响应时发生错误", "error": str(e)}, ensure_ascii=False) diff --git "a/tools/tool_tavily_search/1.0.0/Tavily\346\220\234\347\264\242.tool" "b/tools/tool_tavily_search/1.0.0/Tavily\346\220\234\347\264\242.tool" new file mode 100644 index 0000000..6bd89e4 Binary files /dev/null and "b/tools/tool_tavily_search/1.0.0/Tavily\346\220\234\347\264\242.tool" differ diff --git a/tools/tool_tavily_search/README.md b/tools/tool_tavily_search/README.md new file mode 100644 index 0000000..daae4ee --- /dev/null +++ b/tools/tool_tavily_search/README.md @@ -0,0 +1,116 @@ +# Tavily 搜索工具 + +基于 Tavily Search API 封装的联网搜索工具,执行搜索查询并返回原始 JSON 结果,适合在工作流中继续处理。 + +## 一、功能说明 + +- 使用 Tavily Search API 执行联网搜索 +- 返回原始 JSON 结果,包含标题、链接、摘要、相关性评分等字段 +- 支持主题分类(general / news / finance) +- 支持搜索深度控制(basic / advanced / fast / ultra-fast) +- 支持返回数量、LLM 答案、正文内容等可选增强 + +## 二、参数说明 + +### 2.1 启动参数 + +| 参数 | 组件类型 | 必填 | 说明 | +| :--- | :--- | :--- | :--- | +| `tavily_api_key` | 密码框 | 是 | Tavily API Key,在 https://app.tavily.com 获取 | + +### 2.2 输入参数 + +| 参数名 | 数据类型 | 必填 | 来源 | 说明 | +| :--- | :--- | :--- | :--- | :--- | +| `query` | string | 是 | 引用参数 | 搜索关键词 | +| `topic` | string | 否 | 引用参数 | 搜索主题,支持 `general`(默认)/ `news` / `finance` | +| `search_depth` | string | 否 | 引用参数 | 搜索深度,支持 `basic`(默认)/ `advanced` / `fast` / `ultra-fast` | +| `max_results` | int | 否 | 自定义参数 | 最大返回结果数,默认 5,范围 0-20 | +| `include_answer` | string | 否 | 引用参数 | 是否包含 LLM 生成的答案,支持 `false`(默认)/ `true` / `basic` / `advanced` | +| `include_raw_content` | string | 否 | 引用参数 | 是否包含正文内容,支持 `false`(默认)/ `true` / `markdown` / `text` | + +> **参数获取说明**: +> - `query`:直接输入搜索关键词,或使用 MaxKB 系统变量如 `{{query}}` +> - `max_results`:建议使用自定义参数,设置为 5-10 之间 + +## 三、工具内容(Python) + +```python +import json +import requests + + +def tavily_search(query: str, topic: str = "general", search_depth: str = "basic", max_results: int = 5, include_answer: str = "false", include_raw_content: str = "false", tavily_api_key: str = ""): + """ + Tavily 搜索 + + 参数类型: + - query: string, 必填,搜索关键词 + - topic: string, 可选,搜索主题(general/news/finance),默认 general + - search_depth: string, 可选,搜索深度(basic/advanced/fast/ultra-fast),默认 basic + - max_results: int, 可选,最大返回结果数,默认 5,范围 0-20 + - include_answer: string/bool, 可选,是否包含 LLM 生成的答案 + - include_raw_content: string/bool, 可选,是否包含正文内容 + - tavily_api_key: string, 必填,Tavily API Key + """ + try: + if not query: + return json.dumps({"success": False, "message": "query 不能为空", "error": "missing_query"}, ensure_ascii=False) + if not tavily_api_key: + return json.dumps({"success": False, "message": "tavily_api_key 不能为空", "error": "missing_tavily_api_key"}, ensure_ascii=False) + + def normalize_bool_or_mode(value): + if isinstance(value, bool): + return value + text = str(value).strip().lower() + if text in ["true", "basic", "advanced", "markdown", "text"]: + if text == "true": + return True + return text + return False + + payload = { + "query": query, + "topic": topic or "general", + "search_depth": search_depth or "basic", + "max_results": max_results + } + + answer_value = normalize_bool_or_mode(include_answer) + raw_value = normalize_bool_or_mode(include_raw_content) + if answer_value is not False: + payload["include_answer"] = answer_value + if raw_value is not False: + payload["include_raw_content"] = raw_value + + rep = requests.post( + url="https://api.tavily.com/search", + headers={ + "Content-Type": "application/json" + }, + json={**payload, "api_key": tavily_api_key}, + timeout=30 + ) + rep.raise_for_status() + data = rep.json() + return json.dumps({"success": True, "message": "Tavily 搜索成功", "data": data}, ensure_ascii=False) + except requests.exceptions.HTTPError as e: + detail = None + try: + detail = e.response.json() + except Exception: + detail = e.response.text if e.response is not None else str(e) + return json.dumps({ + "success": False, + "message": "Tavily 搜索失败", + "error": str(e), + "status_code": e.response.status_code if e.response is not None else None, + "details": detail + }, ensure_ascii=False) + except requests.exceptions.RequestException as e: + return json.dumps({"success": False, "message": "Tavily 搜索请求失败", "error": str(e)}, ensure_ascii=False) + except Exception as e: + return json.dumps({"success": False, "message": "处理 Tavily 搜索响应时发生错误", "error": str(e)}, ensure_ascii=False) +``` + +--- diff --git a/tools/tool_tavily_search/data.yaml b/tools/tool_tavily_search/data.yaml new file mode 100644 index 0000000..a357129 --- /dev/null +++ b/tools/tool_tavily_search/data.yaml @@ -0,0 +1,5 @@ +name: Tavily 搜索 +tags: + - 联网搜索 +title: 使用 Tavily Search API 执行联网搜索 +description: 基于 Tavily Search API 的单入口搜索工具,用于执行联网搜索并返回原始 JSON 结果。 diff --git a/tools/tool_tavily_search/logo.png b/tools/tool_tavily_search/logo.png new file mode 100644 index 0000000..e61bfe1 Binary files /dev/null and b/tools/tool_tavily_search/logo.png differ diff --git a/tools/tool_tavily_search/tavily_search.py b/tools/tool_tavily_search/tavily_search.py new file mode 100644 index 0000000..698e339 --- /dev/null +++ b/tools/tool_tavily_search/tavily_search.py @@ -0,0 +1,63 @@ +import json +import requests + + +def tavily_search(query: str, topic: str = "general", search_depth: str = "basic", max_results: int = 5, include_answer: str = "false", include_raw_content: str = "false", tavily_api_key: str = ""): + try: + if not query: + return json.dumps({"success": False, "message": "query 不能为空", "error": "missing_query"}, ensure_ascii=False) + if not tavily_api_key: + return json.dumps({"success": False, "message": "tavily_api_key 不能为空", "error": "missing_tavily_api_key"}, ensure_ascii=False) + + def normalize_bool_or_mode(value): + if isinstance(value, bool): + return value + text = str(value).strip().lower() + if text in ["true", "basic", "advanced", "markdown", "text"]: + if text == "true": + return True + return text + return False + + payload = { + "query": query, + "topic": topic or "general", + "search_depth": search_depth or "basic", + "max_results": max_results + } + + answer_value = normalize_bool_or_mode(include_answer) + raw_value = normalize_bool_or_mode(include_raw_content) + if answer_value is not False: + payload["include_answer"] = answer_value + if raw_value is not False: + payload["include_raw_content"] = raw_value + + rep = requests.post( + url="https://api.tavily.com/search", + headers={ + "Content-Type": "application/json" + }, + json={**payload, "api_key": tavily_api_key}, + timeout=30 + ) + rep.raise_for_status() + data = rep.json() + return json.dumps({"success": True, "message": "Tavily 搜索成功", "data": data}, ensure_ascii=False) + except requests.exceptions.HTTPError as e: + detail = None + try: + detail = e.response.json() + except Exception: + detail = e.response.text if e.response is not None else str(e) + return json.dumps({ + "success": False, + "message": "Tavily 搜索失败", + "error": str(e), + "status_code": e.response.status_code if e.response is not None else None, + "details": detail + }, ensure_ascii=False) + except requests.exceptions.RequestException as e: + return json.dumps({"success": False, "message": "Tavily 搜索请求失败", "error": str(e)}, ensure_ascii=False) + except Exception as e: + return json.dumps({"success": False, "message": "处理 Tavily 搜索响应时发生错误", "error": str(e)}, ensure_ascii=False)