mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-06-03 02:27:09 +08:00
Compare commits
21 Commits
feat-multi
...
feat-web-c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f7064575e | ||
|
|
fbe48a4b4e | ||
|
|
4dd497fb6d | ||
|
|
907882c0a7 | ||
|
|
d36d5aee3f | ||
|
|
c6824e5f5e | ||
|
|
199c21eede | ||
|
|
5162da5654 | ||
|
|
a1d82f6193 | ||
|
|
ea78e3d0c6 | ||
|
|
3497f00cb4 | ||
|
|
5355d45031 | ||
|
|
76e9fef3b2 | ||
|
|
c34308cbd4 | ||
|
|
5a10476010 | ||
|
|
46e80dceec | ||
|
|
90d1835353 | ||
|
|
845fadd0aa | ||
|
|
5748ded52c | ||
|
|
6a737fb734 | ||
|
|
54e81aba11 |
64
README.md
64
README.md
@@ -1,13 +1,13 @@
|
||||
<p align="center"><img src= "https://github.com/user-attachments/assets/eca9a9ec-8534-4615-9e0f-96c5ac1d10a3" alt="Chatgpt-on-Wechat" width="550" /></p>
|
||||
<p align="center"><img src= "https://github.com/user-attachments/assets/eca9a9ec-8534-4615-9e0f-96c5ac1d10a3" alt="CowAgent" width="550" /></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/zhayujie/chatgpt-on-wechat/releases/latest"><img src="https://img.shields.io/github/v/release/zhayujie/chatgpt-on-wechat" alt="Latest release"></a>
|
||||
<a href="https://github.com/zhayujie/chatgpt-on-wechat/blob/master/LICENSE"><img src="https://img.shields.io/github/license/zhayujie/chatgpt-on-wechat" alt="License: MIT"></a>
|
||||
<a href="https://github.com/zhayujie/chatgpt-on-wechat"><img src="https://img.shields.io/github/stars/zhayujie/chatgpt-on-wechat?style=flat-square" alt="Stars"></a> <br/>
|
||||
<a href="https://github.com/zhayujie/CowAgent/releases/latest"><img src="https://img.shields.io/github/v/release/zhayujie/CowAgent" alt="Latest release"></a>
|
||||
<a href="https://github.com/zhayujie/CowAgent/blob/master/LICENSE"><img src="https://img.shields.io/github/license/zhayujie/CowAgent" alt="License: MIT"></a>
|
||||
<a href="https://github.com/zhayujie/CowAgent"><img src="https://img.shields.io/github/stars/zhayujie/CowAgent?style=flat-square" alt="Stars"></a> <br/>
|
||||
[中文] | [<a href="docs/en/README.md">English</a>] | [<a href="docs/ja/README.md">日本語</a>]
|
||||
</p>
|
||||
|
||||
**CowAgent** 是基于大模型的超级 AI 助理,能够主动思考和任务规划、操作计算机和外部资源、创造和执行 Skills、拥有长期记忆并不断成长,比 OpenClaw 更轻量和便捷。CowAgent 支持灵活切换多种模型,能处理文本、语音、图片、文件等多模态消息,可接入微信、飞书、钉钉、企微智能机器人、QQ、企微自建应用、微信公众号、网页中使用,7*24小时运行于你的个人电脑或服务器中。
|
||||
**CowAgent** 是基于大模型的超级 AI 助理,能够主动思考和任务规划、操作计算机和外部资源、创造和执行 Skills、拥有长期记忆和知识库并不断成长,比 OpenClaw 更轻量和便捷。CowAgent 支持灵活切换多种模型,能处理文本、语音、图片、文件等多模态消息,可接入微信、飞书、钉钉、企微智能机器人、QQ、企微自建应用、微信公众号、网页中使用,7*24小时运行于你的个人电脑或服务器中。
|
||||
|
||||
<p align="center">
|
||||
<a href="https://cowagent.ai/">🌐 官网</a> ·
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
- ✅ **自主任务规划**:能够理解复杂任务并自主规划执行,持续思考和调用工具直到完成目标
|
||||
- ✅ **长期记忆:** 自动将对话记忆持久化至本地文件和数据库中,包括核心记忆和日级记忆,支持关键词及向量检索
|
||||
- ✅ **个人知识库:** 自动整理结构化知识,通过交叉引用构建知识图谱,支持通过对话管理和可视化浏览知识库
|
||||
- ✅ **技能系统:** Skills 安装和运行的引擎,支持从 [Skill Hub](https://skills.cowagent.ai/)、GitHub 等一键安装技能,或通过对话创造 Skills
|
||||
- ✅ **工具系统:** 内置文件读写、终端执行、浏览器操作、定时任务等工具,Agent 自主调用以完成复杂任务
|
||||
- ✅ **CLI系统:** 提供终端命令和对话命令,支持进程管理、技能安装、配置修改等操作
|
||||
@@ -69,17 +70,17 @@
|
||||
|
||||
# 🏷 更新日志
|
||||
|
||||
>**2026.04.01:** [2.0.5版本](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.5),Cow CLI 命令系统、Skill Hub 开源、浏览器工具、企微扫码创建、多项优化和修复。
|
||||
>**2026.04.01:** [2.0.5版本](https://github.com/zhayujie/CowAgent/releases/tag/2.0.5),Cow CLI 命令系统、Skill Hub 开源、浏览器工具、企微扫码创建、多项优化和修复。
|
||||
|
||||
>**2026.03.22:** [2.0.4版本](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.4),新增个人微信通道(微信扫码即用)、新增 MiniMax-M2.7 和 GLM-5-Turbo 模型、run.sh 脚本重构、日文文档及多项修复。
|
||||
>**2026.03.22:** [2.0.4版本](https://github.com/zhayujie/CowAgent/releases/tag/2.0.4),新增个人微信通道(微信扫码即用)、新增 MiniMax-M2.7 和 GLM-5-Turbo 模型、run.sh 脚本重构、日文文档及多项修复。
|
||||
|
||||
>**2026.03.18:** [2.0.3版本](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.3),新增企微智能机器人和 QQ 通道、支持 Coding Plan、新增多个模型、Web 端文件处理、记忆系统升级。
|
||||
>**2026.03.18:** [2.0.3版本](https://github.com/zhayujie/CowAgent/releases/tag/2.0.3),新增企微智能机器人和 QQ 通道、支持 Coding Plan、新增多个模型、Web 端文件处理、记忆系统升级。
|
||||
|
||||
>**2026.02.27:** [2.0.2版本](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.2),Web 控制台全面升级(流式对话、模型/技能/记忆/通道/定时任务/日志管理)、支持多通道同时运行、会话持久化存储、新增多个模型。
|
||||
>**2026.02.27:** [2.0.2版本](https://github.com/zhayujie/CowAgent/releases/tag/2.0.2),Web 控制台全面升级(流式对话、模型/技能/记忆/通道/定时任务/日志管理)、支持多通道同时运行、会话持久化存储、新增多个模型。
|
||||
|
||||
>**2026.02.13:** [2.0.1版本](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.1),内置 Web Search 工具、智能上下文裁剪策略、运行时信息动态更新、Windows 兼容性适配,修复定时任务记忆丢失、飞书连接等多项问题。
|
||||
>**2026.02.13:** [2.0.1版本](https://github.com/zhayujie/CowAgent/releases/tag/2.0.1),内置 Web Search 工具、智能上下文裁剪策略、运行时信息动态更新、Windows 兼容性适配,修复定时任务记忆丢失、飞书连接等多项问题。
|
||||
|
||||
>**2026.02.03:** [2.0.0版本](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.0),正式升级为超级 Agent 助理,支持多轮任务决策、具备长期记忆、实现多种系统工具、支持 Skills 框架,新增多种模型并优化了接入渠道。
|
||||
>**2026.02.03:** [2.0.0版本](https://github.com/zhayujie/CowAgent/releases/tag/2.0.0),正式升级为超级 Agent 助理,支持多轮任务决策、具备长期记忆、实现多种系统工具、支持 Skills 框架,新增多种模型并优化了接入渠道。
|
||||
|
||||
更多更新历史请查看: [更新日志](https://docs.cowagent.ai/releases)
|
||||
|
||||
@@ -123,11 +124,11 @@ irm https://cdn.link-ai.tech/code/cow/run.ps1 | iex
|
||||
**(1) 克隆项目代码:**
|
||||
|
||||
```bash
|
||||
git clone https://github.com/zhayujie/chatgpt-on-wechat
|
||||
cd chatgpt-on-wechat/
|
||||
git clone https://github.com/zhayujie/CowAgent
|
||||
cd CowAgent/
|
||||
```
|
||||
|
||||
若遇到网络问题可使用国内仓库地址:https://gitee.com/zhayujie/chatgpt-on-wechat
|
||||
若遇到网络问题可使用国内仓库地址:https://gitee.com/zhayujie/CowAgent
|
||||
|
||||
**(2) 安装核心依赖 (必选):**
|
||||
|
||||
@@ -197,11 +198,12 @@ cow install-browser
|
||||
"group_speech_recognition": false, # 是否开启群组语音识别
|
||||
"voice_reply_voice": false, # 是否使用语音回复语音
|
||||
"use_linkai": false, # 是否使用 LinkAI 接口,默认关闭,设置为 true 后可对接 LinkAI 平台模型
|
||||
"web_password": "", # Web 控制台访问密码,留空则不启用密码保护
|
||||
"agent": true, # 是否启用 Agent 模式,启用后拥有多轮工具决策、长期记忆、Skills 能力等
|
||||
"agent_workspace": "~/cow", # Agent 的工作空间路径,用于存储 memory、skills、系统设定等
|
||||
"agent_max_context_tokens": 40000, # Agent 模式下最大上下文 tokens,超出将自动丢弃最早的上下文
|
||||
"agent_max_context_turns": 30, # Agent 模式下最大上下文记忆轮次,每轮包括一次用户提问和 AI 回复
|
||||
"agent_max_steps": 15 # Agent 模式下单次任务的最大决策步数,超出后将停止继续调用工具
|
||||
"agent_max_context_tokens": 50000, # Agent 模式下最大上下文 tokens,超出将自动智能压缩处理
|
||||
"agent_max_context_turns": 20, # Agent 模式下最大上下文记忆轮次,一问一答为一轮,超出后智能压缩处理
|
||||
"agent_max_steps": 20 # Agent 模式下单次任务的最大决策步数,超出后将停止继续调用工具
|
||||
}
|
||||
```
|
||||
|
||||
@@ -213,12 +215,13 @@ cow install-browser
|
||||
+ 添加 `"speech_recognition": true` 将开启语音识别,默认使用 openai 的 whisper 模型识别为文字,同时以文字回复,该参数仅支持私聊 (注意由于语音消息无法匹配前缀,一旦开启将对所有语音自动回复,支持语音触发画图);
|
||||
+ 添加 `"group_speech_recognition": true` 将开启群组语音识别,默认使用 openai 的 whisper 模型识别为文字,同时以文字回复,参数仅支持群聊 (会匹配 group_chat_prefix 和 group_chat_keyword, 支持语音触发画图);
|
||||
+ 添加 `"voice_reply_voice": true` 将开启语音回复语音(同时作用于私聊和群聊)
|
||||
+ 使用 MiniMax TTS:设置 `"text_to_voice": "minimax"`,并配置 `minimax_api_key`;可通过 `"tts_voice_id"` 指定发音人(如 `English_Graceful_Lady`),`"text_to_voice_model"` 指定模型(如 `speech-2.8-hd`、`speech-2.8-turbo`)
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>2. 其他配置</summary>
|
||||
|
||||
+ `model`: 模型名称,Agent 模式下推荐使用 `MiniMax-M2.7`、`glm-5-turbo`、`kimi-k2.5`、`qwen3.6-plus`、`claude-sonnet-4-6`、`gemini-3.1-pro-preview`,全部模型名称参考[common/const.py](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/common/const.py)文件
|
||||
+ `model`: 模型名称,Agent 模式下推荐使用 `MiniMax-M2.7`、`glm-5-turbo`、`kimi-k2.5`、`qwen3.6-plus`、`claude-sonnet-4-6`、`gemini-3.1-pro-preview`,全部模型名称参考[common/const.py](https://github.com/zhayujie/CowAgent/blob/master/common/const.py)文件
|
||||
+ `character_desc`:普通对话模式下的机器人系统提示词。在 Agent 模式下该配置不生效,由工作空间中的文件内容构成。
|
||||
+ `subscribe_msg`:订阅消息,公众号和企业微信 channel 中请填写,当被订阅时会自动回复, 可使用特殊占位符。目前支持的占位符有{trigger_prefix},在程序中它会自动替换成 bot 的触发词。
|
||||
</details>
|
||||
@@ -230,7 +233,7 @@ cow install-browser
|
||||
+ `linkai_api_key`: LinkAI Api Key,可在 [控制台](https://link-ai.tech/console/interface) 创建
|
||||
</details>
|
||||
|
||||
注:全部配置项说明可在 [`config.py`](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/config.py) 文件中查看。
|
||||
注:全部配置项说明可在 [`config.py`](https://github.com/zhayujie/CowAgent/blob/master/config.py) 文件中查看。
|
||||
|
||||
## 三、运行
|
||||
|
||||
@@ -357,7 +360,7 @@ sudo docker logs -f chatgpt-on-wechat
|
||||
"minimax_api_key": ""
|
||||
}
|
||||
```
|
||||
- `model`: 可填写 `MiniMax-M2.7、MiniMax-M2.5、MiniMax-M2.1、MiniMax-M2.1-lightning、MiniMax-M2、abab6.5-chat` 等
|
||||
- `model`: 可填写 `MiniMax-M2.7、MiniMax-M2.7-highspeed、MiniMax-M2.5、MiniMax-M2.1、MiniMax-M2.1-lightning、MiniMax-M2、abab6.5-chat` 等
|
||||
- `minimax_api_key`:MiniMax 平台的 API-KEY,在 [控制台](https://platform.minimaxi.com/user-center/basic-information/interface-key) 创建
|
||||
|
||||
方式二:OpenAI 兼容方式接入,配置如下:
|
||||
@@ -370,7 +373,7 @@ sudo docker logs -f chatgpt-on-wechat
|
||||
}
|
||||
```
|
||||
- `bot_type`: OpenAI 兼容方式
|
||||
- `model`: 可填 `MiniMax-M2.7、MiniMax-M2.5、MiniMax-M2.1、MiniMax-M2.1-lightning、MiniMax-M2`,参考[API文档](https://platform.minimaxi.com/document/%E5%AF%B9%E8%AF%9D?key=66701d281d57f38758d581d0#QklxsNSbaf6kM4j6wjO5eEek)
|
||||
- `model`: 可填 `MiniMax-M2.7、MiniMax-M2.7-highspeed、MiniMax-M2.5、MiniMax-M2.1、MiniMax-M2.1-lightning、MiniMax-M2`,参考[API文档](https://platform.minimaxi.com/document/%E5%AF%B9%E8%AF%9D?key=66701d281d57f38758d581d0#QklxsNSbaf6kM4j6wjO5eEek)
|
||||
- `open_ai_api_base`: MiniMax 平台 API 的 BASE URL
|
||||
- `open_ai_api_key`: MiniMax 平台的 API-KEY
|
||||
</details>
|
||||
@@ -708,6 +711,7 @@ Coding Plan 是各厂商推出的编程包月套餐,所有厂商均可通过 O
|
||||
```
|
||||
|
||||
- `web_port`: 默认为 9899,可按需更改,需要服务器防火墙和安全组放行该端口
|
||||
- `web_password`: 访问密码,留空则不启用密码保护。部署在公网环境时建议设置
|
||||
- 如本地运行,启动后请访问 `http://localhost:9899/chat` ;如服务器运行,请访问 `http://ip:9899/chat`
|
||||
> 注:请将上述 url 中的 ip 或者 port 替换为实际的值
|
||||
</details>
|
||||
@@ -878,18 +882,28 @@ QQ 机器人使用 WebSocket 长连接模式,无需公网 IP 和域名,支
|
||||
|
||||
# 🔎 常见问题
|
||||
|
||||
FAQs: <https://github.com/zhayujie/chatgpt-on-wechat/wiki/FAQs>
|
||||
FAQs: <https://github.com/zhayujie/CowAgent/wiki/FAQs>
|
||||
|
||||
或直接在线咨询 [项目小助手](https://link-ai.tech/app/Kv2fXJcH) (知识库持续完善中,回复供参考)
|
||||
|
||||
# 🛠️ 开发
|
||||
|
||||
欢迎接入更多应用通道,参考 [飞书通道](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/channel/feishu/feishu_channel.py) 新增自定义通道,实现接收和发送消息逻辑即可完成接入。同时欢迎贡献新的 Skills,向 [Skill Hub](https://skills.cowagent.ai/submit) 提交技能。
|
||||
欢迎接入更多应用通道,参考 [飞书通道](https://github.com/zhayujie/CowAgent/blob/master/channel/feishu/feishu_channel.py) 新增自定义通道,实现接收和发送消息逻辑即可完成接入。同时欢迎贡献新的 Skills,向 [Skill Hub](https://skills.cowagent.ai/submit) 提交技能。
|
||||
|
||||
# ✉ 联系
|
||||
|
||||
欢迎提交PR、Issues进行反馈,以及通过 🌟Star 支持并关注项目更新。项目运行遇到问题可以查看 [常见问题列表](https://github.com/zhayujie/chatgpt-on-wechat/wiki/FAQs) ,以及前往 [Issues](https://github.com/zhayujie/chatgpt-on-wechat/issues) 中搜索。个人开发者可加入开源交流群参与更多讨论,企业用户可联系[产品客服](https://cdn.link-ai.tech/portal/linkai-customer-service.png)咨询。
|
||||
欢迎提交PR、Issues进行反馈,以及通过 🌟Star 支持并关注项目更新。项目运行遇到问题可以查看 [常见问题列表](https://github.com/zhayujie/CowAgent/wiki/FAQs) ,以及前往 [Issues](https://github.com/zhayujie/CowAgent/issues) 中搜索。个人开发者可加入开源交流群参与更多讨论,企业用户可联系[产品客服](https://cdn.link-ai.tech/portal/linkai-customer-service.png)咨询。
|
||||
|
||||
# 🌟 贡献者
|
||||
|
||||

|
||||

|
||||
|
||||
# 📌 项目更名说明
|
||||
|
||||
本项目原名 `chatgpt-on-wechat`(GitHub 原地址:https://github.com/zhayujie/chatgpt-on-wechat ),
|
||||
于 2026.04.13 正式更名为 **CowAgent**。GitHub 已自动设置重定向,原有链接仍可正常访问。
|
||||
|
||||
如需更新本地仓库的远程地址(可选):
|
||||
```bash
|
||||
git remote set-url origin https://github.com/zhayujie/CowAgent.git
|
||||
```
|
||||
|
||||
@@ -57,7 +57,16 @@ class ChatService:
|
||||
event_type = event.get("type")
|
||||
data = event.get("data", {})
|
||||
|
||||
if event_type == "message_update":
|
||||
if event_type == "reasoning_update":
|
||||
delta = data.get("delta", "")
|
||||
if delta:
|
||||
send_chunk_fn({
|
||||
"chunk_type": "reasoning",
|
||||
"delta": delta,
|
||||
"segment_id": state.segment_id,
|
||||
})
|
||||
|
||||
elif event_type == "message_update":
|
||||
# Incremental text delta
|
||||
delta = data.get("delta", "")
|
||||
if delta:
|
||||
|
||||
0
agent/knowledge/__init__.py
Normal file
0
agent/knowledge/__init__.py
Normal file
218
agent/knowledge/service.py
Normal file
218
agent/knowledge/service.py
Normal file
@@ -0,0 +1,218 @@
|
||||
"""
|
||||
Knowledge service for handling knowledge base operations.
|
||||
|
||||
Provides a unified interface for listing, reading, and graphing knowledge files,
|
||||
callable from the web console, API, or CLI.
|
||||
|
||||
Knowledge file layout (under workspace_root):
|
||||
knowledge/index.md
|
||||
knowledge/log.md
|
||||
knowledge/<category>/<slug>.md
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from common.log import logger
|
||||
from config import conf
|
||||
|
||||
|
||||
class KnowledgeService:
|
||||
"""
|
||||
High-level service for knowledge base queries.
|
||||
Operates directly on the filesystem.
|
||||
"""
|
||||
|
||||
def __init__(self, workspace_root: str):
|
||||
self.workspace_root = workspace_root
|
||||
self.knowledge_dir = os.path.join(workspace_root, "knowledge")
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# list — directory tree with stats
|
||||
# ------------------------------------------------------------------
|
||||
def list_tree(self) -> dict:
|
||||
"""
|
||||
Return the knowledge directory tree grouped by category.
|
||||
|
||||
Returns::
|
||||
|
||||
{
|
||||
"tree": [
|
||||
{
|
||||
"dir": "concepts",
|
||||
"files": [
|
||||
{"name": "moe.md", "title": "MoE", "size": 1234},
|
||||
...
|
||||
]
|
||||
},
|
||||
...
|
||||
],
|
||||
"stats": {"pages": 15, "size": 32768},
|
||||
"enabled": true
|
||||
}
|
||||
"""
|
||||
if not os.path.isdir(self.knowledge_dir):
|
||||
return {"tree": [], "stats": {"pages": 0, "size": 0}, "enabled": conf().get("knowledge", True)}
|
||||
|
||||
tree = []
|
||||
total_files = 0
|
||||
total_bytes = 0
|
||||
for name in sorted(os.listdir(self.knowledge_dir)):
|
||||
full = os.path.join(self.knowledge_dir, name)
|
||||
if not os.path.isdir(full) or name.startswith("."):
|
||||
continue
|
||||
files = []
|
||||
for fname in sorted(os.listdir(full)):
|
||||
if fname.endswith(".md") and not fname.startswith("."):
|
||||
fpath = os.path.join(full, fname)
|
||||
size = os.path.getsize(fpath)
|
||||
total_files += 1
|
||||
total_bytes += size
|
||||
title = fname.replace(".md", "")
|
||||
try:
|
||||
with open(fpath, "r", encoding="utf-8") as f:
|
||||
first_line = f.readline().strip()
|
||||
if first_line.startswith("# "):
|
||||
title = first_line[2:].strip()
|
||||
except Exception:
|
||||
pass
|
||||
files.append({"name": fname, "title": title, "size": size})
|
||||
tree.append({"dir": name, "files": files})
|
||||
|
||||
return {
|
||||
"tree": tree,
|
||||
"stats": {"pages": total_files, "size": total_bytes},
|
||||
"enabled": conf().get("knowledge", True),
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# read — single file content
|
||||
# ------------------------------------------------------------------
|
||||
def read_file(self, rel_path: str) -> dict:
|
||||
"""
|
||||
Read a single knowledge markdown file.
|
||||
|
||||
:param rel_path: Relative path within knowledge/, e.g. ``concepts/moe.md``
|
||||
:return: dict with ``content`` and ``path``
|
||||
:raises ValueError: if path is invalid or escapes knowledge dir
|
||||
:raises FileNotFoundError: if file does not exist
|
||||
"""
|
||||
if not rel_path or ".." in rel_path:
|
||||
raise ValueError("invalid path")
|
||||
|
||||
full_path = os.path.normpath(os.path.join(self.knowledge_dir, rel_path))
|
||||
allowed = os.path.normpath(self.knowledge_dir)
|
||||
if not full_path.startswith(allowed + os.sep) and full_path != allowed:
|
||||
raise ValueError("path outside knowledge dir")
|
||||
|
||||
if not os.path.isfile(full_path):
|
||||
raise FileNotFoundError(f"file not found: {rel_path}")
|
||||
|
||||
with open(full_path, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
return {"content": content, "path": rel_path}
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# graph — nodes and links for visualization
|
||||
# ------------------------------------------------------------------
|
||||
def build_graph(self) -> dict:
|
||||
"""
|
||||
Parse all knowledge pages and extract cross-reference links.
|
||||
|
||||
Returns::
|
||||
|
||||
{
|
||||
"nodes": [
|
||||
{"id": "concepts/moe.md", "label": "MoE", "category": "concepts"},
|
||||
...
|
||||
],
|
||||
"links": [
|
||||
{"source": "concepts/moe.md", "target": "entities/deepseek.md"},
|
||||
...
|
||||
]
|
||||
}
|
||||
"""
|
||||
knowledge_path = Path(self.knowledge_dir)
|
||||
if not knowledge_path.is_dir():
|
||||
return {"nodes": [], "links": []}
|
||||
|
||||
nodes = {}
|
||||
links = []
|
||||
link_re = re.compile(r'\[([^\]]*)\]\(([^)]+\.md)\)')
|
||||
|
||||
for md_file in knowledge_path.rglob("*.md"):
|
||||
rel = str(md_file.relative_to(knowledge_path))
|
||||
if rel in ("index.md", "log.md"):
|
||||
continue
|
||||
parts = rel.split("/")
|
||||
category = parts[0] if len(parts) > 1 else "root"
|
||||
title = md_file.stem.replace("-", " ").title()
|
||||
try:
|
||||
content = md_file.read_text(encoding="utf-8")
|
||||
first_line = content.strip().split("\n")[0]
|
||||
if first_line.startswith("# "):
|
||||
title = first_line[2:].strip()
|
||||
for _, link_target in link_re.findall(content):
|
||||
resolved = (md_file.parent / link_target).resolve()
|
||||
try:
|
||||
target_rel = str(resolved.relative_to(knowledge_path))
|
||||
except ValueError:
|
||||
continue
|
||||
if target_rel != rel:
|
||||
links.append({"source": rel, "target": target_rel})
|
||||
except Exception:
|
||||
pass
|
||||
nodes[rel] = {"id": rel, "label": title, "category": category}
|
||||
|
||||
valid_ids = set(nodes.keys())
|
||||
links = [l for l in links if l["source"] in valid_ids and l["target"] in valid_ids]
|
||||
seen = set()
|
||||
deduped = []
|
||||
for l in links:
|
||||
key = tuple(sorted([l["source"], l["target"]]))
|
||||
if key not in seen:
|
||||
seen.add(key)
|
||||
deduped.append(l)
|
||||
|
||||
return {"nodes": list(nodes.values()), "links": deduped}
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# dispatch — single entry point for protocol messages
|
||||
# ------------------------------------------------------------------
|
||||
def dispatch(self, action: str, payload: Optional[dict] = None) -> dict:
|
||||
"""
|
||||
Dispatch a knowledge management action.
|
||||
|
||||
:param action: ``list``, ``read``, or ``graph``
|
||||
:param payload: action-specific payload
|
||||
:return: protocol-compatible response dict
|
||||
"""
|
||||
payload = payload or {}
|
||||
try:
|
||||
if action == "list":
|
||||
result = self.list_tree()
|
||||
return {"action": action, "code": 200, "message": "success", "payload": result}
|
||||
|
||||
elif action == "read":
|
||||
path = payload.get("path")
|
||||
if not path:
|
||||
return {"action": action, "code": 400, "message": "path is required", "payload": None}
|
||||
result = self.read_file(path)
|
||||
return {"action": action, "code": 200, "message": "success", "payload": result}
|
||||
|
||||
elif action == "graph":
|
||||
result = self.build_graph()
|
||||
return {"action": action, "code": 200, "message": "success", "payload": result}
|
||||
|
||||
else:
|
||||
return {"action": action, "code": 400, "message": f"unknown action: {action}", "payload": None}
|
||||
|
||||
except ValueError as e:
|
||||
return {"action": action, "code": 403, "message": str(e), "payload": None}
|
||||
except FileNotFoundError as e:
|
||||
return {"action": action, "code": 404, "message": str(e), "payload": None}
|
||||
except Exception as e:
|
||||
logger.error(f"[KnowledgeService] dispatch error: action={action}, error={e}")
|
||||
return {"action": action, "code": 500, "message": str(e), "payload": None}
|
||||
@@ -188,8 +188,9 @@ def _group_into_display_turns(
|
||||
if text:
|
||||
turns.append({"role": "user", "content": text, "created_at": created_at})
|
||||
|
||||
# Collect all tool_calls and tool_results from the rest of the group
|
||||
all_tool_calls: List[Dict[str, Any]] = []
|
||||
# Build an ordered list of steps preserving the original sequence:
|
||||
# thinking → content → tool_call → content → ...
|
||||
steps: List[Dict[str, Any]] = []
|
||||
tool_results: Dict[str, str] = {}
|
||||
final_text = ""
|
||||
final_ts: Optional[int] = None
|
||||
@@ -198,24 +199,46 @@ def _group_into_display_turns(
|
||||
if role == "user":
|
||||
tool_results.update(_extract_tool_results(content))
|
||||
elif role == "assistant":
|
||||
tcs = _extract_tool_calls(content)
|
||||
all_tool_calls.extend(tcs)
|
||||
t = _extract_display_text(content)
|
||||
if t:
|
||||
final_text = t
|
||||
# Walk content blocks in order to preserve interleaving
|
||||
if isinstance(content, list):
|
||||
for block in content:
|
||||
if not isinstance(block, dict):
|
||||
continue
|
||||
btype = block.get("type")
|
||||
if btype == "thinking":
|
||||
txt = block.get("thinking", "").strip()
|
||||
if txt:
|
||||
steps.append({"type": "thinking", "content": txt})
|
||||
elif btype == "text":
|
||||
txt = block.get("text", "").strip()
|
||||
if txt:
|
||||
steps.append({"type": "content", "content": txt})
|
||||
final_text = txt
|
||||
elif btype == "tool_use":
|
||||
steps.append({
|
||||
"type": "tool",
|
||||
"id": block.get("id", ""),
|
||||
"name": block.get("name", ""),
|
||||
"arguments": block.get("input", {}),
|
||||
})
|
||||
elif isinstance(content, str) and content.strip():
|
||||
steps.append({"type": "content", "content": content.strip()})
|
||||
final_text = content.strip()
|
||||
final_ts = created_at
|
||||
|
||||
# Attach tool results to their matching tool_call entries
|
||||
for tc in all_tool_calls:
|
||||
tc["result"] = tool_results.get(tc.get("id", ""), "")
|
||||
# Attach tool results to tool steps
|
||||
for step in steps:
|
||||
if step["type"] == "tool":
|
||||
step["result"] = tool_results.get(step.get("id", ""), "")
|
||||
|
||||
if final_text or all_tool_calls:
|
||||
turns.append({
|
||||
if steps or final_text:
|
||||
turn = {
|
||||
"role": "assistant",
|
||||
"content": final_text,
|
||||
"tool_calls": all_tool_calls,
|
||||
"steps": steps,
|
||||
"created_at": final_ts or (user_row[1] if user_row else 0),
|
||||
})
|
||||
}
|
||||
turns.append(turn)
|
||||
|
||||
return turns
|
||||
|
||||
@@ -312,6 +335,9 @@ class ConversationStore:
|
||||
content = json.loads(raw_content)
|
||||
except Exception:
|
||||
content = raw_content
|
||||
# Strip thinking blocks — they are stored for UI display only
|
||||
if role == "assistant" and isinstance(content, list):
|
||||
content = [b for b in content if b.get("type") != "thinking"]
|
||||
result.append({"role": role, "content": content})
|
||||
return result
|
||||
|
||||
|
||||
@@ -285,6 +285,10 @@ class MemoryManager:
|
||||
# Scan memory directory (including daily summaries)
|
||||
if memory_dir.exists():
|
||||
for file_path in memory_dir.rglob("*.md"):
|
||||
# Skip hidden directories (e.g. .dreams/)
|
||||
if any(part.startswith('.') for part in file_path.relative_to(workspace_dir).parts):
|
||||
continue
|
||||
|
||||
# Determine scope and user_id from path
|
||||
rel_path = file_path.relative_to(workspace_dir)
|
||||
parts = rel_path.parts
|
||||
@@ -312,6 +316,14 @@ class MemoryManager:
|
||||
scope = "shared"
|
||||
|
||||
await self._sync_file(file_path, "memory", scope, user_id)
|
||||
|
||||
# Scan knowledge directory (structured knowledge wiki)
|
||||
from config import conf
|
||||
if conf().get("knowledge", True):
|
||||
knowledge_dir = Path(workspace_dir) / "knowledge"
|
||||
if knowledge_dir.exists():
|
||||
for file_path in knowledge_dir.rglob("*.md"):
|
||||
await self._sync_file(file_path, "knowledge", "shared", None)
|
||||
|
||||
self._dirty = False
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
"""
|
||||
Memory flush manager
|
||||
Memory flush manager (with Light Dream)
|
||||
|
||||
Handles memory persistence when conversation context is trimmed or overflows:
|
||||
- Uses LLM to summarize discarded messages into concise key-information entries
|
||||
- Writes to daily memory files (lazy creation)
|
||||
- Light Dream: extracts long-term memories to MEMORY.md in the same LLM call
|
||||
- Deduplicates trim flushes to avoid repeated writes
|
||||
- Runs summarization asynchronously to avoid blocking normal replies
|
||||
- Provides daily summary interface for scheduler
|
||||
@@ -16,26 +17,41 @@ from datetime import datetime
|
||||
from common.log import logger
|
||||
|
||||
|
||||
SUMMARIZE_SYSTEM_PROMPT = """你是一个记忆提取助手。你的任务是从对话记录中提炼出值得长期记住的关键事件和核心信息。
|
||||
SUMMARIZE_SYSTEM_PROMPT = """你是一个记忆提取助手。你的任务是从对话记录中提炼出两种记忆:
|
||||
|
||||
核心原则:
|
||||
- 按「事件」维度归纳,而不是按对话轮次逐条记录
|
||||
- 多轮对话如果围绕同一件事,合并为一条摘要
|
||||
- 只记录有长期价值的信息,忽略闲聊、问候、无意义的短消息
|
||||
## 第一部分:日常记录([DAILY])
|
||||
|
||||
输出要求:
|
||||
1. 每条一行,用 "- " 开头,格式为:事件/主题 + 关键结论或结果
|
||||
2. 值得记录的信息类型:用户提出的需求及最终解决方案、重要的事实信息、用户的偏好或决策、关键技术方案或配置变更
|
||||
3. 不值得记录的信息:简单问候、闲聊、无实质内容的短消息、重复的中间过程
|
||||
4. 每条摘要应当简明扼要,一句话概括事件的核心内容和结果
|
||||
5. 直接输出摘要内容,不要加任何前缀说明
|
||||
6. 当对话没有任何记录价值(仅含问候或无意义内容),回复"无"
|
||||
按「事件」维度归纳当天发生的事,不要按对话轮次逐条记录:
|
||||
- 每条一行,用 "- " 开头
|
||||
- 合并同一件事的多轮对话
|
||||
- 只记录有意义的事件,忽略闲聊和问候
|
||||
|
||||
示例(仅供参考格式):
|
||||
- 用户配置了 XX 功能,设置参数为 YY,已生效
|
||||
- 用户反馈了 XX 问题,原因是 YY,通过 ZZ 方式解决"""
|
||||
## 第二部分:长期记忆([MEMORY])
|
||||
|
||||
SUMMARIZE_USER_PROMPT = """请从以下对话记录中,按关键事件维度提炼记忆摘要(合并同一事件的多轮对话,不要逐条列出):
|
||||
提取值得**永久记住**的关键信息,这些信息在未来的对话中仍然有价值:
|
||||
- 用户的偏好、习惯、风格(如"用户偏好中文回复"、"用户喜欢简洁风格")
|
||||
- 重要的决策或约定(如"项目决定使用 PostgreSQL")
|
||||
- 关键人物信息(如"张总是用户的上级")
|
||||
- 用户明确要求记住的内容
|
||||
- 重要的教训或经验总结
|
||||
|
||||
**如果没有值得永久记住的信息,[MEMORY] 部分留空即可。**
|
||||
|
||||
## 输出格式(严格遵守)
|
||||
|
||||
```
|
||||
[DAILY]
|
||||
- 事件1的摘要
|
||||
- 事件2的摘要
|
||||
|
||||
[MEMORY]
|
||||
- 值得永久记住的信息1
|
||||
- 值得永久记住的信息2
|
||||
```
|
||||
|
||||
当对话没有任何记录价值(仅含问候或无意义内容),直接回复"无"。"""
|
||||
|
||||
SUMMARIZE_USER_PROMPT = """请从以下对话记录中提取记忆(按 [DAILY] 和 [MEMORY] 两部分输出):
|
||||
|
||||
{conversation}"""
|
||||
|
||||
@@ -160,40 +176,111 @@ class MemoryFlushManager:
|
||||
reason: str,
|
||||
max_messages: int,
|
||||
):
|
||||
"""Background worker: summarize with LLM and write to daily file."""
|
||||
"""Background worker: summarize with LLM, write daily file + MEMORY.md (Light Dream)."""
|
||||
try:
|
||||
summary = self._summarize_messages(messages, max_messages)
|
||||
if not summary or not summary.strip() or summary.strip() == "无":
|
||||
raw_summary = self._summarize_messages(messages, max_messages)
|
||||
if not raw_summary or not raw_summary.strip() or raw_summary.strip() == "无":
|
||||
logger.info(f"[MemoryFlush] No valuable content to flush (reason={reason})")
|
||||
return
|
||||
|
||||
daily_file = ensure_daily_memory_file(self.workspace_dir, user_id)
|
||||
|
||||
if reason == "overflow":
|
||||
header = f"## Context Overflow Recovery ({datetime.now().strftime('%H:%M')})"
|
||||
note = "The following conversation was trimmed due to context overflow:\n"
|
||||
elif reason == "trim":
|
||||
header = f"## Trimmed Context ({datetime.now().strftime('%H:%M')})"
|
||||
note = ""
|
||||
elif reason == "daily_summary":
|
||||
header = f"## Daily Summary ({datetime.now().strftime('%H:%M')})"
|
||||
note = ""
|
||||
else:
|
||||
header = f"## Session Notes ({datetime.now().strftime('%H:%M')})"
|
||||
note = ""
|
||||
|
||||
flush_entry = f"\n{header}\n\n{note}{summary}\n"
|
||||
|
||||
with open(daily_file, "a", encoding="utf-8") as f:
|
||||
f.write(flush_entry)
|
||||
|
||||
|
||||
daily_part, memory_part = self._parse_dual_output(raw_summary)
|
||||
|
||||
# --- Write daily memory ---
|
||||
if daily_part:
|
||||
daily_file = ensure_daily_memory_file(self.workspace_dir, user_id)
|
||||
|
||||
if reason == "overflow":
|
||||
header = f"## Context Overflow Recovery ({datetime.now().strftime('%H:%M')})"
|
||||
note = "The following conversation was trimmed due to context overflow:\n"
|
||||
elif reason == "trim":
|
||||
header = f"## Trimmed Context ({datetime.now().strftime('%H:%M')})"
|
||||
note = ""
|
||||
elif reason == "daily_summary":
|
||||
header = f"## Daily Summary ({datetime.now().strftime('%H:%M')})"
|
||||
note = ""
|
||||
else:
|
||||
header = f"## Session Notes ({datetime.now().strftime('%H:%M')})"
|
||||
note = ""
|
||||
|
||||
flush_entry = f"\n{header}\n\n{note}{daily_part}\n"
|
||||
|
||||
with open(daily_file, "a", encoding="utf-8") as f:
|
||||
f.write(flush_entry)
|
||||
|
||||
logger.info(f"[MemoryFlush] Wrote daily memory to {daily_file.name} (reason={reason}, chars={len(daily_part)})")
|
||||
|
||||
# --- Light Dream: write long-term memory to MEMORY.md ---
|
||||
if memory_part:
|
||||
self._append_to_main_memory(memory_part, user_id)
|
||||
|
||||
self.last_flush_timestamp = datetime.now()
|
||||
|
||||
logger.info(f"[MemoryFlush] Wrote to {daily_file.name} (reason={reason}, chars={len(summary)})")
|
||||
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"[MemoryFlush] Async flush failed (reason={reason}): {e}")
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _parse_dual_output(raw: str) -> tuple:
|
||||
"""
|
||||
Parse LLM output into (daily_part, memory_part).
|
||||
Handles both new [DAILY]/[MEMORY] format and legacy single-section format.
|
||||
"""
|
||||
raw = raw.strip()
|
||||
|
||||
if "[DAILY]" in raw or "[MEMORY]" in raw:
|
||||
daily_part = ""
|
||||
memory_part = ""
|
||||
|
||||
# Extract [DAILY] section
|
||||
if "[DAILY]" in raw:
|
||||
start = raw.index("[DAILY]") + len("[DAILY]")
|
||||
end = raw.index("[MEMORY]") if "[MEMORY]" in raw else len(raw)
|
||||
daily_part = raw[start:end].strip()
|
||||
|
||||
# Extract [MEMORY] section
|
||||
if "[MEMORY]" in raw:
|
||||
start = raw.index("[MEMORY]") + len("[MEMORY]")
|
||||
memory_part = raw[start:].strip()
|
||||
|
||||
# Filter out empty markers
|
||||
if memory_part and all(
|
||||
not line.strip() or line.strip() == "-"
|
||||
for line in memory_part.split("\n")
|
||||
):
|
||||
memory_part = ""
|
||||
|
||||
return daily_part, memory_part
|
||||
|
||||
# Legacy format: treat entire output as daily, no memory extraction
|
||||
return raw, ""
|
||||
|
||||
def _append_to_main_memory(self, memory_entries: str, user_id: Optional[str] = None):
|
||||
"""Append extracted long-term memories to MEMORY.md with date stamp."""
|
||||
try:
|
||||
main_file = self.get_main_memory_file(user_id)
|
||||
today = datetime.now().strftime("%Y-%m-%d")
|
||||
|
||||
# Add date prefix to each entry line
|
||||
stamped_lines = []
|
||||
for line in memory_entries.strip().split("\n"):
|
||||
line = line.strip()
|
||||
if line.startswith("- "):
|
||||
stamped_lines.append(f"- ({today}) {line[2:]}")
|
||||
elif line:
|
||||
stamped_lines.append(f"- ({today}) {line}")
|
||||
|
||||
if not stamped_lines:
|
||||
return
|
||||
|
||||
stamped_text = "\n".join(stamped_lines)
|
||||
|
||||
with open(main_file, "a", encoding="utf-8") as f:
|
||||
f.write(f"\n{stamped_text}\n")
|
||||
|
||||
logger.info(f"[LightDream] Appended {len(stamped_lines)} entries to MEMORY.md")
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"[LightDream] Failed to append to MEMORY.md: {e}")
|
||||
|
||||
def create_daily_summary(
|
||||
self,
|
||||
messages: List[Dict],
|
||||
|
||||
@@ -10,6 +10,7 @@ from typing import List, Dict, Optional, Any
|
||||
from dataclasses import dataclass
|
||||
|
||||
from common.log import logger
|
||||
from config import conf
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -92,10 +93,11 @@ def build_agent_system_prompt(
|
||||
顺序说明(按重要性和逻辑关系排列):
|
||||
1. 工具系统 - 核心能力,最先介绍
|
||||
2. 技能系统 - 紧跟工具,因为技能需要用 read 工具读取
|
||||
3. 记忆系统 - 独立的记忆能力
|
||||
3. 记忆系统 - 记忆检索与写入引导
|
||||
3.5 知识系统 - 结构化知识库(knowledge/index.md 注入)
|
||||
4. 工作空间 - 工作环境说明
|
||||
5. 用户身份 - 用户信息(可选)
|
||||
6. 项目上下文 - AGENT.md, USER.md, RULE.md, BOOTSTRAP.md(定义人格、身份、规则、初始化引导)
|
||||
6. 项目上下文 - AGENT.md, USER.md, RULE.md, MEMORY.md, BOOTSTRAP.md
|
||||
7. 运行时信息 - 元信息(时间、模型等)
|
||||
|
||||
Args:
|
||||
@@ -126,6 +128,10 @@ def build_agent_system_prompt(
|
||||
# 3. 记忆系统(独立的记忆能力)
|
||||
if memory_manager:
|
||||
sections.extend(_build_memory_section(memory_manager, tools, language))
|
||||
|
||||
# 3.5 知识系统(结构化知识库)
|
||||
if conf().get("knowledge", True):
|
||||
sections.extend(_build_knowledge_section(workspace_dir, language))
|
||||
|
||||
# 4. 工作空间(工作环境说明)
|
||||
sections.extend(_build_workspace_section(workspace_dir, language))
|
||||
@@ -268,55 +274,105 @@ def _build_memory_section(memory_manager: Any, tools: Optional[List[Any]], langu
|
||||
"""构建记忆系统section"""
|
||||
if not memory_manager:
|
||||
return []
|
||||
|
||||
# 检查是否有memory工具
|
||||
|
||||
has_memory_tools = False
|
||||
if tools:
|
||||
tool_names = [tool.name if hasattr(tool, 'name') else str(tool) for tool in tools]
|
||||
has_memory_tools = any(name in ['memory_search', 'memory_get'] for name in tool_names)
|
||||
|
||||
|
||||
if not has_memory_tools:
|
||||
return []
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
today_file = datetime.now().strftime("%Y-%m-%d") + ".md"
|
||||
|
||||
|
||||
lines = [
|
||||
"## 🧠 记忆系统",
|
||||
"",
|
||||
"### 检索记忆",
|
||||
"### Memory Recall(mandatory)",
|
||||
"",
|
||||
"在回答关于以前的工作、决定、日期、人物、偏好或待办事项的任何问题之前:",
|
||||
"在回答任何关于过往工作、决策、日期、人物、偏好或待办事项的问题之前,**必须**先检索记忆。",
|
||||
"MEMORY.md 已自动加载在项目上下文中(可能被截断),完整内容和每日记忆需要通过工具检索。",
|
||||
"",
|
||||
"1. 不确定记忆文件位置 → 先用 `memory_search` 通过关键词和语义检索相关内容",
|
||||
"2. 已知文件位置 → 直接用 `memory_get` 读取相应的行 (例如:MEMORY.md, memory/YYYY-MM-DD.md)",
|
||||
"3. search 无结果 → 尝试用 `memory_get` 读取MEMORY.md及最近两天记忆文件",
|
||||
"1. 不确定位置 → `memory_search` 关键词/语义检索",
|
||||
"2. 已知位置 → `memory_get` 直接读取对应行",
|
||||
"3. search 无结果 → `memory_get` 读最近两天记忆",
|
||||
"",
|
||||
"**记忆文件结构**:",
|
||||
f"- `MEMORY.md`: 长期记忆(核心信息、偏好、决策等)",
|
||||
"- `MEMORY.md`: 长期记忆索引(已自动加载到上下文,核心信息、偏好、决策等)",
|
||||
f"- `memory/YYYY-MM-DD.md`: 每日记忆,今天是 `memory/{today_file}`",
|
||||
"- `knowledge/`: 结构化知识库(见下方知识系统)",
|
||||
"",
|
||||
"### 写入记忆",
|
||||
"",
|
||||
"**主动存储**:遇到以下情况时,应主动将信息写入记忆文件(无需告知用户):",
|
||||
"遇到以下情况时,**主动**将信息写入记忆文件(无需告知用户):",
|
||||
"",
|
||||
"- 用户明确要求你记住某些信息",
|
||||
"- 用户要求记住某些信息",
|
||||
"- 用户分享了重要的个人偏好、习惯、决策",
|
||||
"- 对话中产生了重要的结论、方案、约定",
|
||||
"- 完成了复杂任务,值得记录关键步骤和结果",
|
||||
"- 发现了用户经常遇到的问题或解决方案",
|
||||
"",
|
||||
"**存储规则**:",
|
||||
f"- 长期有效的核心信息 → `MEMORY.md`(文件保持精简,< 2000 tokens)",
|
||||
f"- 当天的事件、进展、笔记 → `memory/{today_file}`",
|
||||
"- 追加内容 → `edit` 工具,oldText 留空",
|
||||
"- 修改内容 → `edit` 工具,oldText 填写要替换的文本",
|
||||
"- **禁止写入敏感信息**:API密钥、令牌等敏感信息严禁写入记忆文件",
|
||||
f"- 长期核心信息 → `MEMORY.md`",
|
||||
f"- 当天事件/进展 → `memory/{today_file}`",
|
||||
"- 结构化知识 → `knowledge/`(见知识系统)",
|
||||
"- 追加 → `edit` 工具,oldText 留空",
|
||||
"- 修改 → `edit` 工具,oldText 填写要替换的文本",
|
||||
"- **禁止写入敏感信息**(API密钥、令牌等)",
|
||||
"",
|
||||
"**使用原则**: 自然使用记忆,就像你本来就知道;不用刻意提起,除非用户问起。",
|
||||
"",
|
||||
]
|
||||
|
||||
|
||||
return lines
|
||||
|
||||
|
||||
def _build_knowledge_section(workspace_dir: str, language: str) -> List[str]:
|
||||
"""Build knowledge wiki section. Injects knowledge/index.md when present."""
|
||||
index_path = os.path.join(workspace_dir, "knowledge", "index.md")
|
||||
if not os.path.exists(index_path):
|
||||
return []
|
||||
|
||||
try:
|
||||
with open(index_path, 'r', encoding='utf-8') as f:
|
||||
index_content = f.read().strip()
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
lines = [
|
||||
"## 📚 知识系统",
|
||||
"",
|
||||
"你拥有一个持续积累的个人知识库 `knowledge/`,这是你的长期结构化知识存储。",
|
||||
"",
|
||||
"### 自动写入规则(mandatory)",
|
||||
"",
|
||||
"以下场景**必须**在回复的同时写入知识库,**直接写入,不要询问用户是否需要**:",
|
||||
"",
|
||||
"1. **用户分享了文章/链接/文档** → 阅读理解后,在同一轮回复中将要点写入 `knowledge/sources/<slug>.md`",
|
||||
"2. **深度讨论产生了结论/方案** → 整理为 `knowledge/analysis/<slug>.md`",
|
||||
"3. **对话涉及重要实体**(人物/公司/项目)→ 创建或更新 `knowledge/entities/<name>.md`",
|
||||
"4. **讨论了技术概念/方法论** → 整理为 `knowledge/concepts/<topic>.md`",
|
||||
"",
|
||||
"每次写入知识页面后,**必须同步更新** `knowledge/index.md` 添加一行索引。",
|
||||
"详细的页面格式和操作规范,请读取技能 `knowledge-wiki` 的 SKILL.md。",
|
||||
"",
|
||||
"⚠️ 不要问「要不要存到知识库」——符合上述场景就直接写入,这是你的本能行为。",
|
||||
"",
|
||||
]
|
||||
|
||||
if index_content:
|
||||
lines.extend([
|
||||
"### 当前知识索引",
|
||||
"",
|
||||
index_content,
|
||||
"",
|
||||
])
|
||||
|
||||
lines.extend([
|
||||
"**查询方式**:用 `read` 读取知识页面,或用 `memory_search` 检索(知识已纳入向量索引)。",
|
||||
"",
|
||||
])
|
||||
|
||||
return lines
|
||||
|
||||
|
||||
@@ -375,11 +431,12 @@ def _build_workspace_section(workspace_dir: str, language: str) -> List[str]:
|
||||
"",
|
||||
"**重要说明 - 文件已自动加载**:",
|
||||
"",
|
||||
"以下文件在会话启动时**已经自动加载**到系统提示词的「项目上下文」section 中,你**无需再用 read 工具读取它们**:",
|
||||
"以下文件在会话启动时**已经自动加载**到系统提示词中,你**无需再用 read 工具读取**:",
|
||||
"",
|
||||
"- ✅ `AGENT.md`: 已加载 - 你的人格和灵魂设定,请严格遵循。当你的名字、性格或交流风格发生变化时,主动用 `edit` 更新此文件",
|
||||
"- ✅ `USER.md`: 已加载 - 用户的身份信息。当用户修改称呼、姓名等身份信息时,用 `edit` 更新此文件",
|
||||
"- ✅ `RULE.md`: 已加载 - 工作空间使用指南和规则,请严格遵循",
|
||||
"- ✅ `MEMORY.md`: 已加载 - 长期记忆索引",
|
||||
"",
|
||||
"**💬 交流规范**:",
|
||||
"",
|
||||
|
||||
@@ -67,6 +67,12 @@ def ensure_workspace(workspace_dir: str, create_templates: bool = True) -> Works
|
||||
# 创建websites子目录 (for web pages / sites generated by agent)
|
||||
websites_dir = os.path.join(workspace_dir, "websites")
|
||||
os.makedirs(websites_dir, exist_ok=True)
|
||||
|
||||
from config import conf
|
||||
knowledge_enabled = conf().get("knowledge", True)
|
||||
if knowledge_enabled:
|
||||
knowledge_dir = os.path.join(workspace_dir, "knowledge")
|
||||
os.makedirs(knowledge_dir, exist_ok=True)
|
||||
|
||||
# 如果需要,创建模板文件
|
||||
if create_templates:
|
||||
@@ -74,6 +80,15 @@ def ensure_workspace(workspace_dir: str, create_templates: bool = True) -> Works
|
||||
_create_template_if_missing(user_path, _get_user_template())
|
||||
_create_template_if_missing(rule_path, _get_rule_template())
|
||||
_create_template_if_missing(memory_path, _get_memory_template())
|
||||
if knowledge_enabled:
|
||||
_create_template_if_missing(
|
||||
os.path.join(knowledge_dir, "index.md"),
|
||||
_get_knowledge_index_template()
|
||||
)
|
||||
_create_template_if_missing(
|
||||
os.path.join(knowledge_dir, "log.md"),
|
||||
_get_knowledge_log_template()
|
||||
)
|
||||
|
||||
# Only create BOOTSTRAP.md for brand new workspaces;
|
||||
# agent deletes it after completing onboarding
|
||||
@@ -109,6 +124,7 @@ def load_context_files(workspace_dir: str, files_to_load: Optional[List[str]] =
|
||||
DEFAULT_AGENT_FILENAME,
|
||||
DEFAULT_USER_FILENAME,
|
||||
DEFAULT_RULE_FILENAME,
|
||||
DEFAULT_MEMORY_FILENAME, # Long-term memory (frozen snapshot)
|
||||
DEFAULT_BOOTSTRAP_FILENAME, # Only exists when onboarding is incomplete
|
||||
]
|
||||
|
||||
@@ -138,6 +154,10 @@ def load_context_files(workspace_dir: str, files_to_load: Optional[List[str]] =
|
||||
# 跳过空文件或只包含模板占位符的文件
|
||||
if not content or _is_template_placeholder(content):
|
||||
continue
|
||||
|
||||
# Truncate MEMORY.md to protect context window (frozen snapshot)
|
||||
if filename == DEFAULT_MEMORY_FILENAME:
|
||||
content = _truncate_memory_content(content)
|
||||
|
||||
context_files.append(ContextFile(
|
||||
path=filename,
|
||||
@@ -163,6 +183,36 @@ def _create_template_if_missing(filepath: str, template_content: str):
|
||||
logger.error(f"[Workspace] Failed to create template {filepath}: {e}")
|
||||
|
||||
|
||||
_MEMORY_MAX_LINES = 200
|
||||
_MEMORY_MAX_BYTES = 25000
|
||||
|
||||
|
||||
def _truncate_memory_content(content: str) -> str:
|
||||
"""Truncate MEMORY.md to keep system prompt manageable.
|
||||
|
||||
Takes the **last** N lines (newest entries are appended at the bottom),
|
||||
subject to 200 lines / 25 KB limits (whichever is hit first).
|
||||
Prepends a hint when truncated so the model knows older content exists.
|
||||
"""
|
||||
lines = content.split('\n')
|
||||
truncated = False
|
||||
|
||||
if len(lines) > _MEMORY_MAX_LINES:
|
||||
lines = lines[-_MEMORY_MAX_LINES:]
|
||||
truncated = True
|
||||
|
||||
result = '\n'.join(lines)
|
||||
if len(result.encode('utf-8')) > _MEMORY_MAX_BYTES:
|
||||
while len(result.encode('utf-8')) > _MEMORY_MAX_BYTES and lines:
|
||||
lines.pop(0)
|
||||
truncated = True
|
||||
result = '\n'.join(lines)
|
||||
|
||||
if truncated:
|
||||
result = "...(older entries truncated, use `memory_search` or `memory_get` for full content)\n\n" + result
|
||||
return result
|
||||
|
||||
|
||||
def _is_template_placeholder(content: str) -> bool:
|
||||
"""检查内容是否为模板占位符"""
|
||||
# 常见的占位符模式
|
||||
@@ -287,39 +337,88 @@ def _get_rule_template() -> str:
|
||||
|
||||
这个文件夹是你的家。好好对待它。
|
||||
|
||||
## 工作空间目录结构
|
||||
|
||||
```
|
||||
~/cow/
|
||||
├── AGENT.md # 你的身份和灵魂设定
|
||||
├── USER.md # 用户基本信息(静态)
|
||||
├── RULE.md # 工作空间规则(本文件)
|
||||
├── MEMORY.md # 长期记忆索引(会话启动时自动加载)
|
||||
│
|
||||
├── memory/ # 每日对话记忆
|
||||
│ └── YYYY-MM-DD.md # 当天事件、进展、笔记
|
||||
│
|
||||
├── knowledge/ # 结构化知识库(持续积累的知识)
|
||||
│ ├── index.md # 知识目录索引(必须维护)
|
||||
│ ├── log.md # 知识操作日志
|
||||
│ └── <子目录>/ # 按需创建,参考 index.md 已有分类
|
||||
│
|
||||
├── skills/ # 技能
|
||||
├── websites/ # 网页产物
|
||||
└── tmp/ # 系统临时文件(自动管理,勿手动存放重要文件)
|
||||
```
|
||||
|
||||
## 记忆系统
|
||||
|
||||
你每次会话都是全新的,记忆文件让你保持连续性:
|
||||
|
||||
### 📝 每日记忆:`memory/YYYY-MM-DD.md`
|
||||
- 原始的对话日志
|
||||
- 记录当天发生的事情
|
||||
- 如果 `memory/` 目录不存在,创建它
|
||||
|
||||
### 🧠 长期记忆:`MEMORY.md`
|
||||
- 你精选的记忆,就像人类的长期记忆
|
||||
- **仅在主会话中加载**(与用户的直接聊天)
|
||||
- **不要在共享上下文中加载**(群聊、与其他人的会话)
|
||||
- 这是为了**安全** - 包含不应泄露给陌生人的个人上下文
|
||||
- 记录重要事件、想法、决定、观点、经验教训
|
||||
- 这是你精选的记忆 - 精华,而不是原始日志
|
||||
- 用 `edit` 工具追加新的记忆内容
|
||||
- 你精选的记忆索引,每次会话启动时**自动加载**到上下文中
|
||||
- 记录核心事实、偏好、决策、重要人物、教训
|
||||
- 保持精简(< 200 行),是精华索引而非原始日志
|
||||
- 用 `edit` 工具追加或修改
|
||||
|
||||
### 📝 每日记忆:`memory/YYYY-MM-DD.md`
|
||||
- 当天的事件、进展、笔记
|
||||
- 原始对话日志的沉淀
|
||||
|
||||
### 📝 写下来 - 不要"记在心里"!
|
||||
- **记忆是有限的** - 如果你想记住某事,写入文件
|
||||
- **记忆是有限的** - 想记住的事就写入文件
|
||||
- "记在心里"不会在会话重启后保留,文件才会
|
||||
- 当有人说"记住这个" → 更新 `MEMORY.md` 或 `memory/YYYY-MM-DD.md`
|
||||
- 当你学到教训 → 更新 RULE.md 或相关技能
|
||||
- 当你犯错 → 记录下来,这样未来的你不会重复,**文字 > 大脑** 📝
|
||||
- 当你犯错 → 记录下来,**文字 > 大脑** 📝
|
||||
|
||||
### 存储规则
|
||||
|
||||
当用户分享信息时,根据类型选择存储位置:
|
||||
|
||||
1. **你的身份设定 → AGENT.md**(你的名字、角色、性格、交流风格——用户修改时必须用 `edit` 更新)
|
||||
2. **用户静态身份 → USER.md**(姓名、称呼、职业、时区、联系方式、生日——用户修改时必须用 `edit` 更新)
|
||||
3. **动态记忆 → MEMORY.md**(爱好、偏好、决策、目标、项目、教训、待办事项)
|
||||
1. **你的身份设定 → AGENT.md**(名字、角色、性格、风格)
|
||||
2. **用户静态身份 → USER.md**(姓名、称呼、职业、联系方式、生日)
|
||||
3. **动态记忆 → MEMORY.md**(偏好、决策、目标、教训、待办)
|
||||
4. **当天对话 → memory/YYYY-MM-DD.md**(今天聊的内容)
|
||||
5. **结构化知识 → knowledge/**(见下方知识系统)
|
||||
|
||||
## 知识系统
|
||||
|
||||
知识库 `knowledge/` 是你持续积累的结构化知识。与记忆不同,知识是经过整理和编译的,有明确的主题和交叉引用。
|
||||
|
||||
### 自动写入(不要询问,直接写入)
|
||||
|
||||
当对话中产生了有沉淀价值的知识——无论是用户分享的资料、讨论的结论、学到的概念、还是重要的决策——你**必须**在回复的同时主动写入知识库,**无需问用户"要不要存到知识库"**。
|
||||
|
||||
**关键原则**:学完就记是你的本能,不要征求确认。回复中可以顺带告知"已存入知识库"。
|
||||
|
||||
### 目录组织
|
||||
|
||||
子目录结构**不是固定的**,由你根据实际内容自主决定:
|
||||
- **首次写入时**:先读 `knowledge/index.md`,如果已有分类则延续;如果为空,根据内容选择合适的目录名
|
||||
- **默认建议**:按信息类型组织(例如sources/、concepts/、entities/、analysis/),如果用户有明确的分类偏好(例如按领域 work/、life/、tech/ 等),则按用户要求调整
|
||||
- **保持一致性**:同一用户的知识库应保持统一的组织风格
|
||||
|
||||
### 交叉引用
|
||||
|
||||
知识的核心价值在于**关联**。每个页面都应通过 markdown 链接引用相关页面,构建知识网络:
|
||||
- 提到已有页面的概念时,添加 `[概念名](../category/page.md)` 链接
|
||||
- 新建页面时,检查是否有已有页面应该反向链接到新页面
|
||||
- **只链接已存在的页面**——不要引用尚未创建的页面。如果某个概念值得单独建页,先创建该页面再添加链接
|
||||
|
||||
### 索引维护
|
||||
|
||||
每次创建或更新知识页面后,**必须同步更新** `knowledge/index.md`。
|
||||
索引格式:每行一个 `[标题](路径) — 一句话摘要`,按分类分组,不要用表格。
|
||||
详细操作规范见技能 `knowledge-wiki`。
|
||||
|
||||
## 安全
|
||||
|
||||
@@ -381,4 +480,12 @@ _你刚刚启动,这是你的第一次对话。_ ✨
|
||||
"""
|
||||
|
||||
|
||||
def _get_knowledge_index_template() -> str:
|
||||
"""Knowledge wiki index template — empty file, agent fills it."""
|
||||
return ""
|
||||
|
||||
|
||||
def _get_knowledge_log_template() -> str:
|
||||
"""Knowledge wiki operation log template — empty file, agent fills it."""
|
||||
return ""
|
||||
|
||||
|
||||
@@ -527,6 +527,7 @@ class AgentStreamExecutor:
|
||||
|
||||
# Streaming response
|
||||
full_content = ""
|
||||
full_reasoning = ""
|
||||
tool_calls_buffer = {} # {index: {id, name, arguments}}
|
||||
gemini_raw_parts = None # Preserve Gemini thoughtSignature for round-trip
|
||||
stop_reason = None # Track why the stream stopped
|
||||
@@ -584,10 +585,10 @@ class AgentStreamExecutor:
|
||||
if finish_reason:
|
||||
stop_reason = finish_reason
|
||||
|
||||
# Skip reasoning_content (internal thinking from models like GLM-5)
|
||||
reasoning_delta = delta.get("reasoning_content") or ""
|
||||
# if reasoning_delta:
|
||||
# logger.debug(f"🧠 [thinking] {reasoning_delta[:100]}...")
|
||||
if reasoning_delta:
|
||||
full_reasoning += reasoning_delta
|
||||
self._emit_event("reasoning_update", {"delta": reasoning_delta})
|
||||
|
||||
# Handle text content
|
||||
content_delta = delta.get("content") or ""
|
||||
@@ -788,7 +789,12 @@ class AgentStreamExecutor:
|
||||
# Add assistant message to history (Claude format uses content blocks)
|
||||
assistant_msg = {"role": "assistant", "content": []}
|
||||
|
||||
# Add text content block if present
|
||||
if full_reasoning:
|
||||
assistant_msg["content"].append({
|
||||
"type": "thinking",
|
||||
"thinking": full_reasoning
|
||||
})
|
||||
|
||||
if full_content:
|
||||
assistant_msg["content"].append({
|
||||
"type": "text",
|
||||
|
||||
@@ -210,6 +210,10 @@ class SkillManager:
|
||||
if not include_disabled:
|
||||
entries = [e for e in entries if self.is_skill_enabled(e.skill.name)]
|
||||
|
||||
from config import conf
|
||||
if not conf().get("knowledge", True):
|
||||
entries = [e for e in entries if e.skill.name != "knowledge-wiki"]
|
||||
|
||||
return entries
|
||||
|
||||
def filter_unavailable_skills(
|
||||
|
||||
@@ -44,6 +44,19 @@ class MemoryGetTool(BaseTool):
|
||||
"""
|
||||
super().__init__()
|
||||
self.memory_manager = memory_manager
|
||||
|
||||
from config import conf
|
||||
if conf().get("knowledge", True):
|
||||
self.description = (
|
||||
"Read specific content from memory or knowledge files. "
|
||||
"Use this to get full context from a memory file, knowledge page, or specific line range."
|
||||
)
|
||||
self.params = {**self.params}
|
||||
self.params["properties"] = {**self.params["properties"]}
|
||||
self.params["properties"]["path"] = {
|
||||
"type": "string",
|
||||
"description": "Relative path to the memory or knowledge file (e.g. 'MEMORY.md', 'memory/2026-01-01.md', 'knowledge/concepts/moe.md')"
|
||||
}
|
||||
|
||||
def execute(self, args: dict):
|
||||
"""
|
||||
@@ -68,11 +81,15 @@ class MemoryGetTool(BaseTool):
|
||||
workspace_dir = self.memory_manager.config.get_workspace()
|
||||
|
||||
# Auto-prepend memory/ if not present and not absolute path
|
||||
# Exception: MEMORY.md is in the root directory
|
||||
if not path.startswith('memory/') and not path.startswith('/') and path != 'MEMORY.md':
|
||||
# Exceptions: MEMORY.md in root, knowledge/ files at workspace root
|
||||
if not path.startswith('memory/') and not path.startswith('knowledge/') and not path.startswith('/') and path != 'MEMORY.md':
|
||||
path = f'memory/{path}'
|
||||
|
||||
file_path = workspace_dir / path
|
||||
file_path = (workspace_dir / path).resolve()
|
||||
workspace_resolved = workspace_dir.resolve()
|
||||
|
||||
if not str(file_path).startswith(str(workspace_resolved) + '/') and file_path != workspace_resolved:
|
||||
return ToolResult.fail(f"Error: Access denied: path outside workspace")
|
||||
|
||||
if not file_path.exists():
|
||||
return ToolResult.fail(f"Error: File not found: {path}")
|
||||
|
||||
@@ -48,6 +48,13 @@ class MemorySearchTool(BaseTool):
|
||||
super().__init__()
|
||||
self.memory_manager = memory_manager
|
||||
self.user_id = user_id
|
||||
|
||||
from config import conf
|
||||
if conf().get("knowledge", True):
|
||||
self.description = (
|
||||
"Search agent's long-term memory and knowledge base using semantic and keyword search. "
|
||||
"Use this to recall past conversations, preferences, and knowledge pages."
|
||||
)
|
||||
|
||||
def execute(self, args: dict):
|
||||
"""
|
||||
|
||||
@@ -499,10 +499,14 @@ class AgentBridge:
|
||||
reply.text_content = text_response
|
||||
return reply
|
||||
|
||||
# For other unknown file types, return text with file info
|
||||
message = text_response or file_info.get("message", "文件已准备")
|
||||
message += f"\n\n[文件: {file_info.get('file_name', file_path)}]"
|
||||
return Reply(ReplyType.TEXT, message)
|
||||
# For all other file types (tar.gz, zip, etc.), also use FILE type
|
||||
file_url = f"file://{file_path}"
|
||||
logger.info(f"[AgentBridge] Sending generic file: {file_url}")
|
||||
reply = Reply(ReplyType.FILE, file_url)
|
||||
reply.file_name = file_info.get("file_name", os.path.basename(file_path))
|
||||
if text_response:
|
||||
reply.text_content = text_response
|
||||
return reply
|
||||
|
||||
def _migrate_config_to_env(self, workspace_root: str):
|
||||
"""
|
||||
|
||||
@@ -26,8 +26,7 @@ class AgentEventHandler:
|
||||
if context:
|
||||
self.channel = context.kwargs.get("channel") if hasattr(context, "kwargs") else None
|
||||
|
||||
# Track current thinking for channel output
|
||||
self.current_thinking = ""
|
||||
self.current_content = ""
|
||||
self.turn_number = 0
|
||||
|
||||
def handle_event(self, event):
|
||||
@@ -47,6 +46,8 @@ class AgentEventHandler:
|
||||
self._handle_message_update(data)
|
||||
elif event_type == "message_end":
|
||||
self._handle_message_end(data)
|
||||
elif event_type == "reasoning_update":
|
||||
pass
|
||||
elif event_type == "tool_execution_start":
|
||||
self._handle_tool_execution_start(data)
|
||||
elif event_type == "tool_execution_end":
|
||||
@@ -59,30 +60,26 @@ class AgentEventHandler:
|
||||
def _handle_turn_start(self, data):
|
||||
"""Handle turn start event"""
|
||||
self.turn_number = data.get("turn", 0)
|
||||
self.has_tool_calls_in_turn = False
|
||||
self.current_thinking = ""
|
||||
self.current_content = ""
|
||||
|
||||
def _handle_message_update(self, data):
|
||||
"""Handle message update event (streaming text)"""
|
||||
"""Handle message update event (streaming content text)"""
|
||||
delta = data.get("delta", "")
|
||||
self.current_thinking += delta
|
||||
self.current_content += delta
|
||||
|
||||
def _handle_message_end(self, data):
|
||||
"""Handle message end event"""
|
||||
tool_calls = data.get("tool_calls", [])
|
||||
|
||||
# Only send thinking process if followed by tool calls
|
||||
if tool_calls:
|
||||
if self.current_thinking.strip():
|
||||
logger.info(f"💭 {self.current_thinking.strip()[:200]}{'...' if len(self.current_thinking) > 200 else ''}")
|
||||
# Send thinking process to channel
|
||||
self._send_to_channel(f"{self.current_thinking.strip()}")
|
||||
if self.current_content.strip():
|
||||
logger.info(f"💭 {self.current_content.strip()[:200]}{'...' if len(self.current_content) > 200 else ''}")
|
||||
self._send_to_channel(self.current_content.strip())
|
||||
else:
|
||||
# No tool calls = final response (logged at agent_stream level)
|
||||
if self.current_thinking.strip():
|
||||
logger.debug(f"💬 {self.current_thinking.strip()[:200]}{'...' if len(self.current_thinking) > 200 else ''}")
|
||||
if self.current_content.strip():
|
||||
logger.debug(f"💬 {self.current_content.strip()[:200]}{'...' if len(self.current_content) > 200 else ''}")
|
||||
|
||||
self.current_thinking = ""
|
||||
self.current_content = ""
|
||||
|
||||
def _handle_tool_execution_start(self, data):
|
||||
"""Handle tool execution start event - logged by agent_stream.py"""
|
||||
|
||||
@@ -54,6 +54,41 @@
|
||||
</script>
|
||||
</head>
|
||||
<body class="h-screen overflow-hidden bg-gray-50 dark:bg-[#111111] text-slate-800 dark:text-slate-200 font-sans">
|
||||
|
||||
<!-- Login Overlay -->
|
||||
<div id="login-overlay" class="fixed inset-0 z-[200] bg-gray-50 dark:bg-[#111111] flex items-center justify-center hidden">
|
||||
<div class="w-full max-w-sm mx-4">
|
||||
<div class="flex flex-col items-center mb-8">
|
||||
<img src="assets/logo.jpg" alt="CowAgent" class="w-16 h-16 rounded-2xl mb-4 shadow-lg">
|
||||
<h1 class="text-xl font-bold text-slate-800 dark:text-slate-100">CowAgent</h1>
|
||||
<p class="text-sm text-slate-500 dark:text-slate-400 mt-1" id="login-subtitle">请输入密码以访问控制台</p>
|
||||
</div>
|
||||
<form id="login-form" class="space-y-4" onsubmit="return false;">
|
||||
<div class="relative">
|
||||
<input id="login-password" type="password" autocomplete="current-password"
|
||||
placeholder="Password"
|
||||
class="w-full px-4 py-3 rounded-xl border border-slate-200 dark:border-white/10
|
||||
bg-white dark:bg-[#1A1A1A] text-slate-800 dark:text-slate-200
|
||||
placeholder-slate-400 dark:placeholder-slate-500
|
||||
focus:outline-none focus:ring-2 focus:ring-primary-400/50 focus:border-primary-400
|
||||
transition-all duration-150 text-sm">
|
||||
<button type="button" id="login-toggle-pwd"
|
||||
class="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 hover:text-slate-600
|
||||
dark:hover:text-slate-300 cursor-pointer transition-colors"
|
||||
onclick="toggleLoginPassword()">
|
||||
<i class="fas fa-eye text-sm"></i>
|
||||
</button>
|
||||
</div>
|
||||
<p id="login-error" class="text-sm text-red-500 hidden"></p>
|
||||
<button id="login-btn" type="submit"
|
||||
class="w-full py-3 rounded-xl bg-primary-500 hover:bg-primary-600 text-white font-medium
|
||||
text-sm cursor-pointer transition-colors duration-150 disabled:opacity-50 disabled:cursor-not-allowed">
|
||||
登录
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="app" class="flex h-screen">
|
||||
|
||||
<!-- ================================================================ -->
|
||||
@@ -110,6 +145,11 @@
|
||||
<i class="fas fa-brain item-icon text-xs w-5 text-center"></i>
|
||||
<span data-i18n="menu_memory">Memory</span>
|
||||
</a>
|
||||
<a class="sidebar-item flex items-center gap-3 px-3 py-2 rounded-lg cursor-pointer transition-all duration-150 hover:bg-white/5 hover:text-neutral-200 text-[14px]"
|
||||
data-view="knowledge">
|
||||
<i class="fas fa-book item-icon text-xs w-5 text-center"></i>
|
||||
<span data-i18n="menu_knowledge">Knowledge</span>
|
||||
</a>
|
||||
<a class="sidebar-item flex items-center gap-3 px-3 py-2 rounded-lg cursor-pointer transition-all duration-150 hover:bg-white/5 hover:text-neutral-200 text-[14px]"
|
||||
data-view="channels">
|
||||
<i class="fas fa-tower-broadcast item-icon text-xs w-5 text-center"></i>
|
||||
@@ -224,13 +264,13 @@
|
||||
<!-- Messages -->
|
||||
<div id="chat-messages" class="flex-1 overflow-y-auto">
|
||||
<!-- Welcome Screen -->
|
||||
<div id="welcome-screen" class="flex flex-col items-center justify-center h-full px-6 py-12">
|
||||
<div id="welcome-screen" class="flex flex-col items-center justify-center h-full px-6 pb-16" style="padding-top: 6vh">
|
||||
<img src="assets/logo.jpg" alt="CowAgent" class="w-16 h-16 rounded-2xl mb-6 shadow-lg shadow-primary-500/20">
|
||||
<h1 id="welcome-title" class="text-2xl font-bold text-slate-800 dark:text-slate-100 mb-3">CowAgent</h1>
|
||||
<p id="welcome-subtitle" class="text-slate-500 dark:text-slate-400 text-center max-w-lg mb-10 leading-relaxed"
|
||||
data-i18n-html="welcome_subtitle">I can help you answer questions, manage your computer, create and execute skills,<br>and keep growing through long-term memory.</p>
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-3 gap-4 w-full max-w-2xl">
|
||||
<div class="grid grid-cols-2 sm:grid-cols-3 gap-3 w-full max-w-2xl">
|
||||
<div class="example-card group bg-white dark:bg-[#1A1A1A] border border-slate-200 dark:border-white/10 rounded-xl p-4
|
||||
cursor-pointer hover:border-primary-300 dark:hover:border-primary-600 hover:shadow-md transition-all duration-200">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
@@ -247,7 +287,7 @@
|
||||
<div class="w-7 h-7 rounded-lg bg-amber-50 dark:bg-amber-900/30 flex items-center justify-center">
|
||||
<i class="fas fa-clock text-amber-500 text-xs"></i>
|
||||
</div>
|
||||
<span class="font-medium text-sm text-slate-700 dark:text-slate-200" data-i18n="example_task_title">Smart Task</span>
|
||||
<span class="font-medium text-sm text-slate-700 dark:text-slate-200" data-i18n="example_task_title">定时任务</span>
|
||||
</div>
|
||||
<p class="text-sm text-slate-500 dark:text-slate-400 leading-relaxed" data-i18n="example_task_text">Remind me to check the server in 5 minutes</p>
|
||||
</div>
|
||||
@@ -261,6 +301,37 @@
|
||||
</div>
|
||||
<p class="text-sm text-slate-500 dark:text-slate-400 leading-relaxed" data-i18n="example_code_text">Write a Python web scraper script</p>
|
||||
</div>
|
||||
<div class="example-card group bg-white dark:bg-[#1A1A1A] border border-slate-200 dark:border-white/10 rounded-xl p-4
|
||||
cursor-pointer hover:border-primary-300 dark:hover:border-primary-600 hover:shadow-md transition-all duration-200">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<div class="w-7 h-7 rounded-lg bg-violet-50 dark:bg-violet-900/30 flex items-center justify-center">
|
||||
<i class="fas fa-book text-violet-500 text-xs"></i>
|
||||
</div>
|
||||
<span class="font-medium text-sm text-slate-700 dark:text-slate-200" data-i18n="example_knowledge_title">知识库</span>
|
||||
</div>
|
||||
<p class="text-sm text-slate-500 dark:text-slate-400 leading-relaxed" data-i18n="example_knowledge_text">帮我把这篇文章整理到知识库</p>
|
||||
</div>
|
||||
<div class="example-card group bg-white dark:bg-[#1A1A1A] border border-slate-200 dark:border-white/10 rounded-xl p-4
|
||||
cursor-pointer hover:border-primary-300 dark:hover:border-primary-600 hover:shadow-md transition-all duration-200">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<div class="w-7 h-7 rounded-lg bg-rose-50 dark:bg-rose-900/30 flex items-center justify-center">
|
||||
<i class="fas fa-puzzle-piece text-rose-500 text-xs"></i>
|
||||
</div>
|
||||
<span class="font-medium text-sm text-slate-700 dark:text-slate-200" data-i18n="example_skill_title">技能系统</span>
|
||||
</div>
|
||||
<p class="text-sm text-slate-500 dark:text-slate-400 leading-relaxed" data-i18n="example_skill_text">查看所有支持的工具和技能</p>
|
||||
</div>
|
||||
<div class="example-card group bg-white dark:bg-[#1A1A1A] border border-slate-200 dark:border-white/10 rounded-xl p-4
|
||||
cursor-pointer hover:border-primary-300 dark:hover:border-primary-600 hover:shadow-md transition-all duration-200"
|
||||
data-send="/help">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<div class="w-7 h-7 rounded-lg bg-slate-100 dark:bg-slate-800 flex items-center justify-center">
|
||||
<i class="fas fa-terminal text-slate-500 text-xs"></i>
|
||||
</div>
|
||||
<span class="font-medium text-sm text-slate-700 dark:text-slate-200" data-i18n="example_web_title">指令中心</span>
|
||||
</div>
|
||||
<p class="text-sm text-slate-500 dark:text-slate-400 leading-relaxed" data-i18n="example_web_text">查看全部命令</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -409,21 +480,30 @@
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-600 dark:text-slate-400 mb-1.5" data-i18n="config_max_tokens">Max Context Tokens</label>
|
||||
<label class="flex items-center gap-1.5 text-sm font-medium text-slate-600 dark:text-slate-400 mb-1.5">
|
||||
<span data-i18n="config_max_tokens">Max Context Tokens</span>
|
||||
<span class="cfg-tip" data-tip-key="config_max_tokens_hint"><i class="fas fa-circle-question"></i></span>
|
||||
</label>
|
||||
<input id="cfg-max-tokens" type="number" min="1000" max="200000" step="1000"
|
||||
class="w-full px-3 py-2 rounded-lg border border-slate-200 dark:border-slate-600
|
||||
bg-slate-50 dark:bg-white/5 text-sm text-slate-800 dark:text-slate-100
|
||||
focus:outline-none focus:border-primary-500 font-mono transition-colors">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-600 dark:text-slate-400 mb-1.5" data-i18n="config_max_turns">Max Context Turns</label>
|
||||
<label class="flex items-center gap-1.5 text-sm font-medium text-slate-600 dark:text-slate-400 mb-1.5">
|
||||
<span data-i18n="config_max_turns">Max Memory Turns</span>
|
||||
<span class="cfg-tip" data-tip-key="config_max_turns_hint"><i class="fas fa-circle-question"></i></span>
|
||||
</label>
|
||||
<input id="cfg-max-turns" type="number" min="1" max="100" step="1"
|
||||
class="w-full px-3 py-2 rounded-lg border border-slate-200 dark:border-slate-600
|
||||
bg-slate-50 dark:bg-white/5 text-sm text-slate-800 dark:text-slate-100
|
||||
focus:outline-none focus:border-primary-500 font-mono transition-colors">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-600 dark:text-slate-400 mb-1.5" data-i18n="config_max_steps">Max Steps</label>
|
||||
<label class="flex items-center gap-1.5 text-sm font-medium text-slate-600 dark:text-slate-400 mb-1.5">
|
||||
<span data-i18n="config_max_steps">Max Steps</span>
|
||||
<span class="cfg-tip" data-tip-key="config_max_steps_hint"><i class="fas fa-circle-question"></i></span>
|
||||
</label>
|
||||
<input id="cfg-max-steps" type="number" min="1" max="50" step="1"
|
||||
class="w-full px-3 py-2 rounded-lg border border-slate-200 dark:border-slate-600
|
||||
bg-slate-50 dark:bg-white/5 text-sm text-slate-800 dark:text-slate-100
|
||||
@@ -439,6 +519,35 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Security Config Card -->
|
||||
<div class="bg-white dark:bg-[#1A1A1A] rounded-xl border border-slate-200 dark:border-white/10 p-6">
|
||||
<div class="flex items-center gap-3 mb-5">
|
||||
<div class="w-9 h-9 rounded-lg bg-amber-50 dark:bg-amber-900/30 flex items-center justify-center">
|
||||
<i class="fas fa-lock text-amber-500 text-sm"></i>
|
||||
</div>
|
||||
<h3 class="font-semibold text-slate-800 dark:text-slate-100" data-i18n="config_security">Security</h3>
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-600 dark:text-slate-400 mb-1.5" data-i18n="config_password">Password</label>
|
||||
<input id="cfg-password" type="password" autocomplete="new-password"
|
||||
class="w-full px-3 py-2 rounded-lg border border-slate-200 dark:border-slate-600
|
||||
bg-slate-50 dark:bg-white/5 text-sm text-slate-800 dark:text-slate-100
|
||||
focus:outline-none focus:border-primary-500 font-mono transition-colors
|
||||
cfg-key-masked"
|
||||
data-masked="1">
|
||||
<p class="text-xs text-slate-400 dark:text-slate-500 mt-1.5" data-i18n="config_password_hint">Leave empty to disable password protection</p>
|
||||
</div>
|
||||
<div class="flex items-center justify-end gap-3 pt-1">
|
||||
<span id="cfg-password-status" class="text-xs text-primary-500 opacity-0 transition-opacity duration-300"></span>
|
||||
<button id="cfg-password-save"
|
||||
class="px-4 py-2 rounded-lg bg-primary-500 hover:bg-primary-600 text-white text-sm font-medium
|
||||
cursor-pointer transition-colors duration-150 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
onclick="savePasswordConfig()" data-i18n="config_save">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -558,6 +667,106 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ====================================================== -->
|
||||
<!-- VIEW: Knowledge -->
|
||||
<!-- ====================================================== -->
|
||||
<div id="view-knowledge" class="view">
|
||||
<div class="flex-1 overflow-y-auto p-4 md:p-8 lg:p-10">
|
||||
<div class="w-full max-w-[1600px] mx-auto">
|
||||
|
||||
<!-- Header -->
|
||||
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-4 md:mb-6">
|
||||
<div>
|
||||
<h2 class="text-xl font-bold text-slate-800 dark:text-slate-100" data-i18n="knowledge_title">Knowledge</h2>
|
||||
<p class="text-sm text-slate-500 dark:text-slate-400 mt-1" data-i18n="knowledge_desc">Browse and explore your knowledge base</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span id="knowledge-stats" class="text-xs text-slate-400 dark:text-slate-500 hidden sm:inline"></span>
|
||||
<div class="flex items-center bg-slate-100 dark:bg-white/10 rounded-lg p-0.5">
|
||||
<button id="knowledge-tab-docs" onclick="switchKnowledgeTab('docs')"
|
||||
class="knowledge-tab px-3 py-1.5 rounded-md text-xs font-medium cursor-pointer transition-colors duration-150 active">
|
||||
<i class="fas fa-folder-tree mr-1.5"></i><span data-i18n="knowledge_tab_docs">Documents</span>
|
||||
</button>
|
||||
<button id="knowledge-tab-graph" onclick="switchKnowledgeTab('graph')"
|
||||
class="knowledge-tab px-3 py-1.5 rounded-md text-xs font-medium cursor-pointer transition-colors duration-150">
|
||||
<i class="fas fa-diagram-project mr-1.5"></i><span data-i18n="knowledge_tab_graph">Graph</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Empty state -->
|
||||
<div id="knowledge-empty" class="flex flex-col items-center justify-center py-20">
|
||||
<div class="w-16 h-16 rounded-2xl bg-emerald-50 dark:bg-emerald-900/20 flex items-center justify-center mb-4">
|
||||
<i class="fas fa-book text-emerald-400 text-xl"></i>
|
||||
</div>
|
||||
<p class="text-slate-500 dark:text-slate-400 font-medium" data-i18n="knowledge_loading">Loading knowledge base...</p>
|
||||
<p class="text-sm text-slate-400 dark:text-slate-500 mt-1" data-i18n="knowledge_loading_desc">Knowledge pages will be displayed here</p>
|
||||
<div id="knowledge-empty-guide" class="hidden mt-6 max-w-sm text-center">
|
||||
<p class="text-sm text-slate-500 dark:text-slate-400 mb-4" data-i18n="knowledge_empty_guide">Send documents, links or topics to the agent in chat, and it will automatically organize them into your knowledge base.</p>
|
||||
<button onclick="navigateTo('chat')"
|
||||
class="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-primary-500 hover:bg-primary-600
|
||||
text-white text-sm font-medium cursor-pointer transition-colors duration-150">
|
||||
<i class="fas fa-message text-xs"></i>
|
||||
<span data-i18n="knowledge_go_chat">Start a conversation</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Documents panel -->
|
||||
<div id="knowledge-panel-docs" class="hidden">
|
||||
<div class="flex flex-col md:flex-row gap-4 md:gap-6" style="min-height: calc(100vh - 220px)">
|
||||
<!-- File tree -->
|
||||
<div id="knowledge-sidebar" class="w-full md:w-72 lg:w-80 flex-shrink-0">
|
||||
<div class="bg-white dark:bg-[#1A1A1A] rounded-xl border border-slate-200 dark:border-white/10 overflow-hidden">
|
||||
<div class="px-4 py-3 border-b border-slate-200 dark:border-white/10">
|
||||
<div class="relative">
|
||||
<i class="fas fa-search absolute left-3 top-1/2 -translate-y-1/2 text-slate-400 text-xs"></i>
|
||||
<input id="knowledge-search" type="text" placeholder="Search..."
|
||||
class="w-full pl-8 pr-3 py-1.5 text-xs bg-slate-50 dark:bg-white/5 border border-slate-200 dark:border-white/10 rounded-lg text-slate-700 dark:text-slate-200 placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-1 focus:ring-primary-400/50"
|
||||
oninput="filterKnowledgeTree(this.value)">
|
||||
</div>
|
||||
</div>
|
||||
<div id="knowledge-tree" class="p-2 overflow-y-auto max-h-[50vh] md:max-h-[calc(100vh-300px)]"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Content viewer -->
|
||||
<div class="flex-1 min-w-0">
|
||||
<div id="knowledge-content-placeholder"
|
||||
class="flex flex-col items-center justify-center py-20 text-slate-400 dark:text-slate-500"
|
||||
<i class="fas fa-file-lines text-3xl mb-3 opacity-40"></i>
|
||||
<p class="text-sm" data-i18n="knowledge_select_hint">Select a document to view</p>
|
||||
</div>
|
||||
<div id="knowledge-content-viewer" class="hidden">
|
||||
<div class="bg-white dark:bg-[#1A1A1A] rounded-xl border border-slate-200 dark:border-white/10 overflow-hidden">
|
||||
<div class="flex items-center gap-3 px-4 md:px-5 py-3 border-b border-slate-200 dark:border-white/10">
|
||||
<button onclick="knowledgeMobileBack()" class="md:hidden p-1 -ml-1 text-slate-400 hover:text-slate-600 dark:hover:text-slate-300 cursor-pointer">
|
||||
<i class="fas fa-arrow-left text-xs"></i>
|
||||
</button>
|
||||
<i class="fas fa-file-lines text-slate-400 text-sm hidden md:inline"></i>
|
||||
<span id="knowledge-viewer-title" class="text-sm font-medium text-slate-700 dark:text-slate-200 truncate"></span>
|
||||
<span id="knowledge-viewer-path" class="text-xs text-slate-400 dark:text-slate-500 ml-auto font-mono truncate hidden md:inline"></span>
|
||||
</div>
|
||||
<div id="knowledge-viewer-body"
|
||||
class="p-4 md:p-5 overflow-y-auto text-sm msg-content text-slate-700 dark:text-slate-200"
|
||||
style="max-height: calc(100vh - 280px)"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Graph panel -->
|
||||
<div id="knowledge-panel-graph" class="hidden">
|
||||
<div class="bg-white dark:bg-[#1A1A1A] rounded-xl border border-slate-200 dark:border-white/10 overflow-hidden">
|
||||
<div id="knowledge-graph-container" class="w-full h-[60vh] md:h-[calc(100vh-220px)]"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ====================================================== -->
|
||||
<!-- VIEW: Channels -->
|
||||
<!-- ====================================================== -->
|
||||
@@ -670,6 +879,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js"></script>
|
||||
<script src="assets/js/console.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -45,7 +45,8 @@
|
||||
.msg-content h1 { font-size: 1.4em; }
|
||||
.msg-content h2 { font-size: 1.25em; }
|
||||
.msg-content h3 { font-size: 1.1em; }
|
||||
.msg-content ul, .msg-content ol { margin: 0.5em 0; padding-left: 1.8em; }
|
||||
.msg-content ul { margin: 0.5em 0; padding-left: 1.8em; list-style: disc; }
|
||||
.msg-content ol { margin: 0.5em 0; padding-left: 1.8em; list-style: decimal; }
|
||||
.msg-content li { margin: 0.25em 0; }
|
||||
.msg-content pre {
|
||||
border-radius: 8px; overflow-x: auto; margin: 0.8em 0;
|
||||
@@ -146,7 +147,7 @@
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.5;
|
||||
color: #94a3b8;
|
||||
max-height: 200px;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.dark .agent-thinking-step .thinking-full {
|
||||
@@ -158,6 +159,20 @@
|
||||
.agent-thinking-step .thinking-full p:first-child { margin-top: 0; }
|
||||
.agent-thinking-step .thinking-full p:last-child { margin-bottom: 0; }
|
||||
|
||||
/* Content step - real text output frozen before tool calls */
|
||||
.agent-content-step {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.6;
|
||||
color: inherit;
|
||||
margin-bottom: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 1px dashed rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
.dark .agent-content-step { border-bottom-color: rgba(255, 255, 255, 0.06); }
|
||||
.agent-content-step .agent-content-body p { margin: 0.25em 0; }
|
||||
.agent-content-step .agent-content-body p:first-child { margin-top: 0; }
|
||||
.agent-content-step .agent-content-body p:last-child { margin-bottom: 0; }
|
||||
|
||||
/* Tool step - collapsible */
|
||||
.agent-tool-step .tool-header {
|
||||
display: flex;
|
||||
@@ -535,3 +550,195 @@
|
||||
.dark .slash-menu-item .desc {
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
Knowledge View
|
||||
============================================================ */
|
||||
|
||||
/* Tab toggle */
|
||||
.knowledge-tab {
|
||||
color: #64748b;
|
||||
}
|
||||
.knowledge-tab.active {
|
||||
background: #fff;
|
||||
color: #334155;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
|
||||
}
|
||||
.dark .knowledge-tab.active {
|
||||
background: rgba(255,255,255,0.1);
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
/* File tree */
|
||||
.knowledge-tree-group {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.knowledge-tree-group-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
width: 100%;
|
||||
padding: 6px 8px;
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #64748b;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background: none;
|
||||
transition: background 0.15s, color 0.15s;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
.knowledge-tree-group-btn:hover {
|
||||
background: rgba(0,0,0,0.04);
|
||||
color: #334155;
|
||||
}
|
||||
.dark .knowledge-tree-group-btn:hover {
|
||||
background: rgba(255,255,255,0.06);
|
||||
color: #e2e8f0;
|
||||
}
|
||||
.knowledge-tree-group-btn i.chevron {
|
||||
font-size: 8px;
|
||||
transition: transform 0.15s;
|
||||
}
|
||||
.knowledge-tree-group.open .chevron {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
.knowledge-tree-group-items {
|
||||
display: none;
|
||||
}
|
||||
.knowledge-tree-group.open .knowledge-tree-group-items {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.knowledge-tree-file {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 5px 8px 5px 24px;
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
color: #64748b;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background: none;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
transition: background 0.15s, color 0.15s;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.knowledge-tree-file:hover {
|
||||
background: rgba(0,0,0,0.04);
|
||||
color: #334155;
|
||||
}
|
||||
.knowledge-tree-file.active {
|
||||
background: #EDFDF3;
|
||||
color: #228547;
|
||||
}
|
||||
.dark .knowledge-tree-file:hover {
|
||||
background: rgba(255,255,255,0.06);
|
||||
color: #e2e8f0;
|
||||
}
|
||||
.dark .knowledge-tree-file.active {
|
||||
background: rgba(74, 190, 110, 0.1);
|
||||
color: #4ABE6E;
|
||||
}
|
||||
|
||||
/* Graph legend */
|
||||
.knowledge-graph-legend {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
font-size: 11px;
|
||||
color: #64748b;
|
||||
z-index: 10;
|
||||
}
|
||||
.knowledge-graph-legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.knowledge-graph-legend-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/* Graph tooltip */
|
||||
.knowledge-graph-tooltip {
|
||||
position: absolute;
|
||||
padding: 6px 10px;
|
||||
background: #fff;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
color: #334155;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.15s;
|
||||
z-index: 20;
|
||||
}
|
||||
.dark .knowledge-graph-tooltip {
|
||||
background: #1A1A1A;
|
||||
border-color: rgba(255,255,255,0.1);
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
/* Config field tooltip */
|
||||
.cfg-tip {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
color: #94a3b8;
|
||||
cursor: help;
|
||||
font-size: 12px;
|
||||
}
|
||||
.cfg-tip:hover { color: #64748b; }
|
||||
.dark .cfg-tip:hover { color: #cbd5e1; }
|
||||
.cfg-tip::after {
|
||||
content: attr(data-tooltip);
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: calc(100% + 6px);
|
||||
transform: translateX(-50%);
|
||||
padding: 6px 10px;
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
line-height: 1.4;
|
||||
white-space: nowrap;
|
||||
background: #1e293b;
|
||||
color: #e2e8f0;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.15s;
|
||||
z-index: 50;
|
||||
}
|
||||
.dark .cfg-tip::after {
|
||||
background: #334155;
|
||||
color: #f1f5f9;
|
||||
}
|
||||
.cfg-tip:hover::after {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Example cards: equal height via flex stretch + fixed 2-line description area */
|
||||
.example-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.example-card > p {
|
||||
flex: 1;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
min-height: 2.5em; /* ~2 lines at text-sm leading-relaxed */
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,5 @@
|
||||
import hashlib
|
||||
import hmac
|
||||
import time
|
||||
import json
|
||||
import logging
|
||||
@@ -23,6 +25,62 @@ from config import conf
|
||||
IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".svg"}
|
||||
VIDEO_EXTENSIONS = {".mp4", ".webm", ".avi", ".mov", ".mkv"}
|
||||
|
||||
def _is_password_enabled():
|
||||
return bool(conf().get("web_password", ""))
|
||||
|
||||
|
||||
def _session_expire_seconds():
|
||||
return int(conf().get("web_session_expire_days", 30)) * 86400
|
||||
|
||||
|
||||
def _create_auth_token():
|
||||
"""Create a stateless signed token: ``<timestamp_hex>.<hmac_hex>``."""
|
||||
ts = format(int(time.time()), "x")
|
||||
sig = hmac.new(
|
||||
conf().get("web_password", "").encode(),
|
||||
ts.encode(),
|
||||
hashlib.sha256,
|
||||
).hexdigest()
|
||||
return f"{ts}.{sig}"
|
||||
|
||||
|
||||
def _verify_auth_token(token):
|
||||
"""Verify a signed token is valid and not expired.
|
||||
|
||||
The token is derived from the password, so it survives server restarts
|
||||
and automatically invalidates when the password changes.
|
||||
"""
|
||||
if not token or "." not in token:
|
||||
return False
|
||||
ts_hex, sig = token.split(".", 1)
|
||||
try:
|
||||
ts = int(ts_hex, 16)
|
||||
except ValueError:
|
||||
return False
|
||||
if time.time() - ts > _session_expire_seconds():
|
||||
return False
|
||||
expected = hmac.new(
|
||||
conf().get("web_password", "").encode(),
|
||||
ts_hex.encode(),
|
||||
hashlib.sha256,
|
||||
).hexdigest()
|
||||
return hmac.compare_digest(sig, expected)
|
||||
|
||||
|
||||
def _check_auth():
|
||||
"""Return True if request is authenticated or password not enabled."""
|
||||
if not _is_password_enabled():
|
||||
return True
|
||||
return _verify_auth_token(web.cookies().get("cow_auth_token", ""))
|
||||
|
||||
|
||||
def _require_auth():
|
||||
"""Raise 401 if not authenticated. Call at the top of protected handlers."""
|
||||
if not _check_auth():
|
||||
raise web.HTTPError("401 Unauthorized",
|
||||
{"Content-Type": "application/json; charset=utf-8"},
|
||||
json.dumps({"status": "error", "message": "Unauthorized"}))
|
||||
|
||||
|
||||
def _get_upload_dir() -> str:
|
||||
from common.utils import expand_path
|
||||
@@ -168,7 +226,12 @@ class WebChannel(ChatChannel):
|
||||
event_type = event.get("type")
|
||||
data = event.get("data", {})
|
||||
|
||||
if event_type == "message_update":
|
||||
if event_type == "reasoning_update":
|
||||
delta = data.get("delta", "")
|
||||
if delta:
|
||||
q.put({"type": "reasoning", "content": delta})
|
||||
|
||||
elif event_type == "message_update":
|
||||
delta = data.get("delta", "")
|
||||
if delta:
|
||||
q.put({"type": "delta", "content": delta})
|
||||
@@ -195,6 +258,11 @@ class WebChannel(ChatChannel):
|
||||
"execution_time": round(exec_time, 2)
|
||||
})
|
||||
|
||||
elif event_type == "message_end":
|
||||
tool_calls = data.get("tool_calls", [])
|
||||
if tool_calls:
|
||||
q.put({"type": "message_end", "has_tool_calls": True})
|
||||
|
||||
elif event_type == "file_to_send":
|
||||
file_path = data.get("path", "")
|
||||
file_name = data.get("file_name", os.path.basename(file_path))
|
||||
@@ -430,6 +498,9 @@ class WebChannel(ChatChannel):
|
||||
|
||||
urls = (
|
||||
'/', 'RootHandler',
|
||||
'/auth/login', 'AuthLoginHandler',
|
||||
'/auth/check', 'AuthCheckHandler',
|
||||
'/auth/logout', 'AuthLogoutHandler',
|
||||
'/message', 'MessageHandler',
|
||||
'/upload', 'UploadHandler',
|
||||
'/uploads/(.*)', 'UploadsHandler',
|
||||
@@ -444,6 +515,9 @@ class WebChannel(ChatChannel):
|
||||
'/api/skills', 'SkillsHandler',
|
||||
'/api/memory', 'MemoryHandler',
|
||||
'/api/memory/content', 'MemoryContentHandler',
|
||||
'/api/knowledge/list', 'KnowledgeListHandler',
|
||||
'/api/knowledge/read', 'KnowledgeReadHandler',
|
||||
'/api/knowledge/graph', 'KnowledgeGraphHandler',
|
||||
'/api/scheduler', 'SchedulerHandler',
|
||||
'/api/history', 'HistoryHandler',
|
||||
'/api/logs', 'LogsHandler',
|
||||
@@ -489,24 +563,62 @@ class WebChannel(ChatChannel):
|
||||
|
||||
class RootHandler:
|
||||
def GET(self):
|
||||
# 重定向到/chat
|
||||
raise web.seeother('/chat')
|
||||
|
||||
|
||||
class AuthCheckHandler:
|
||||
def GET(self):
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
if not _is_password_enabled():
|
||||
return json.dumps({"status": "success", "auth_required": False})
|
||||
if _check_auth():
|
||||
return json.dumps({"status": "success", "auth_required": True, "authenticated": True})
|
||||
return json.dumps({"status": "success", "auth_required": True, "authenticated": False})
|
||||
|
||||
|
||||
class AuthLoginHandler:
|
||||
def POST(self):
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
if not _is_password_enabled():
|
||||
return json.dumps({"status": "success"})
|
||||
try:
|
||||
data = json.loads(web.data())
|
||||
except Exception:
|
||||
return json.dumps({"status": "error", "message": "Invalid request"})
|
||||
password = data.get("password", "")
|
||||
expected = conf().get("web_password", "")
|
||||
if not hmac.compare_digest(password, expected):
|
||||
logger.warning("[WebChannel] Invalid login attempt")
|
||||
return json.dumps({"status": "error", "message": "Wrong password"})
|
||||
token = _create_auth_token()
|
||||
web.setcookie("cow_auth_token", token, expires=_session_expire_seconds(),
|
||||
path="/", httponly=True, samesite="Lax")
|
||||
return json.dumps({"status": "success"})
|
||||
|
||||
|
||||
class AuthLogoutHandler:
|
||||
def POST(self):
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
web.setcookie("cow_auth_token", "", expires=-1, path="/")
|
||||
return json.dumps({"status": "success"})
|
||||
|
||||
|
||||
class MessageHandler:
|
||||
def POST(self):
|
||||
_require_auth()
|
||||
return WebChannel().post_message()
|
||||
|
||||
|
||||
class UploadHandler:
|
||||
def POST(self):
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
return WebChannel().upload_file()
|
||||
|
||||
|
||||
class UploadsHandler:
|
||||
def GET(self, file_name):
|
||||
"""Serve uploaded files from workspace/tmp/ for preview."""
|
||||
_require_auth()
|
||||
try:
|
||||
upload_dir = _get_upload_dir()
|
||||
full_path = os.path.normpath(os.path.join(upload_dir, file_name))
|
||||
@@ -528,7 +640,7 @@ class UploadsHandler:
|
||||
|
||||
class FileServeHandler:
|
||||
def GET(self):
|
||||
"""Serve a local file by absolute path (for agent send tool)."""
|
||||
_require_auth()
|
||||
try:
|
||||
params = web.input(path="")
|
||||
file_path = params.path
|
||||
@@ -554,11 +666,13 @@ class FileServeHandler:
|
||||
|
||||
class PollHandler:
|
||||
def POST(self):
|
||||
_require_auth()
|
||||
return WebChannel().poll_response()
|
||||
|
||||
|
||||
class StreamHandler:
|
||||
def GET(self):
|
||||
_require_auth()
|
||||
params = web.input(request_id='')
|
||||
request_id = params.request_id
|
||||
if not request_id:
|
||||
@@ -682,6 +796,7 @@ class ConfigHandler:
|
||||
"zhipu_ai_api_key", "dashscope_api_key", "moonshot_api_key",
|
||||
"ark_api_key", "minimax_api_key", "linkai_api_key",
|
||||
"agent_max_context_tokens", "agent_max_context_turns", "agent_max_steps",
|
||||
"web_password",
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
@@ -692,7 +807,7 @@ class ConfigHandler:
|
||||
return value[:4] + "*" * (len(value) - 8) + value[-4:]
|
||||
|
||||
def GET(self):
|
||||
"""Return configuration info and provider/model metadata."""
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
try:
|
||||
local_config = conf()
|
||||
@@ -720,6 +835,9 @@ class ConfigHandler:
|
||||
"api_key_field": p.get("api_key_field"),
|
||||
}
|
||||
|
||||
raw_pwd = local_config.get("web_password", "")
|
||||
masked_pwd = ("*" * len(raw_pwd)) if raw_pwd else ""
|
||||
|
||||
return json.dumps({
|
||||
"status": "success",
|
||||
"use_agent": use_agent,
|
||||
@@ -730,17 +848,18 @@ class ConfigHandler:
|
||||
"channel_type": local_config.get("channel_type", ""),
|
||||
"agent_max_context_tokens": local_config.get("agent_max_context_tokens", 50000),
|
||||
"agent_max_context_turns": local_config.get("agent_max_context_turns", 20),
|
||||
"agent_max_steps": local_config.get("agent_max_steps", 15),
|
||||
"agent_max_steps": local_config.get("agent_max_steps", 20),
|
||||
"api_bases": api_bases,
|
||||
"api_keys": api_keys_masked,
|
||||
"providers": providers,
|
||||
"web_password_masked": masked_pwd,
|
||||
}, ensure_ascii=False)
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting config: {e}")
|
||||
return json.dumps({"status": "error", "message": str(e)})
|
||||
|
||||
def POST(self):
|
||||
"""Update configuration values in memory and persist to config.json."""
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
try:
|
||||
data = json.loads(web.data())
|
||||
@@ -889,6 +1008,7 @@ class ChannelsHandler:
|
||||
return set(cls._parse_channel_list(conf().get("channel_type", "")))
|
||||
|
||||
def GET(self):
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
try:
|
||||
local_config = conf()
|
||||
@@ -926,6 +1046,7 @@ class ChannelsHandler:
|
||||
return json.dumps({"status": "error", "message": str(e)})
|
||||
|
||||
def POST(self):
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
try:
|
||||
body = json.loads(web.data())
|
||||
@@ -1179,6 +1300,7 @@ class WeixinQrHandler:
|
||||
return None
|
||||
|
||||
def GET(self):
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
try:
|
||||
running_ch = self._get_running_channel()
|
||||
@@ -1211,6 +1333,7 @@ class WeixinQrHandler:
|
||||
return json.dumps({"status": "error", "message": str(e)})
|
||||
|
||||
def POST(self):
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
try:
|
||||
body = json.loads(web.data())
|
||||
@@ -1298,6 +1421,7 @@ def _get_workspace_root():
|
||||
|
||||
class ToolsHandler:
|
||||
def GET(self):
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
try:
|
||||
from agent.tools.tool_manager import ToolManager
|
||||
@@ -1322,6 +1446,7 @@ class ToolsHandler:
|
||||
|
||||
class SkillsHandler:
|
||||
def GET(self):
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
try:
|
||||
from agent.skills.service import SkillService
|
||||
@@ -1336,6 +1461,7 @@ class SkillsHandler:
|
||||
return json.dumps({"status": "error", "message": str(e)})
|
||||
|
||||
def POST(self):
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
try:
|
||||
from agent.skills.service import SkillService
|
||||
@@ -1362,6 +1488,7 @@ class SkillsHandler:
|
||||
|
||||
class MemoryHandler:
|
||||
def GET(self):
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
try:
|
||||
from agent.memory.service import MemoryService
|
||||
@@ -1377,6 +1504,7 @@ class MemoryHandler:
|
||||
|
||||
class MemoryContentHandler:
|
||||
def GET(self):
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
try:
|
||||
from agent.memory.service import MemoryService
|
||||
@@ -1398,6 +1526,7 @@ class MemoryContentHandler:
|
||||
|
||||
class SchedulerHandler:
|
||||
def GET(self):
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
try:
|
||||
from agent.tools.scheduler.task_store import TaskStore
|
||||
@@ -1413,14 +1542,7 @@ class SchedulerHandler:
|
||||
|
||||
class HistoryHandler:
|
||||
def GET(self):
|
||||
"""
|
||||
Return paginated conversation history for a session.
|
||||
|
||||
Query params:
|
||||
session_id (required)
|
||||
page int, default 1 (1 = most recent messages)
|
||||
page_size int, default 20
|
||||
"""
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
web.header('Access-Control-Allow-Origin', '*')
|
||||
try:
|
||||
@@ -1444,7 +1566,7 @@ class HistoryHandler:
|
||||
|
||||
class LogsHandler:
|
||||
def GET(self):
|
||||
"""Stream the last N lines of run.log as SSE, then tail new lines."""
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'text/event-stream; charset=utf-8')
|
||||
web.header('Cache-Control', 'no-cache')
|
||||
web.header('X-Accel-Buffering', 'no')
|
||||
@@ -1530,6 +1652,50 @@ class AssetsHandler:
|
||||
raise web.notfound()
|
||||
|
||||
|
||||
class KnowledgeListHandler:
|
||||
def GET(self):
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
try:
|
||||
from agent.knowledge.service import KnowledgeService
|
||||
svc = KnowledgeService(_get_workspace_root())
|
||||
result = svc.list_tree()
|
||||
return json.dumps({"status": "success", **result}, ensure_ascii=False)
|
||||
except Exception as e:
|
||||
logger.error(f"[WebChannel] Knowledge list error: {e}")
|
||||
return json.dumps({"status": "error", "message": str(e)})
|
||||
|
||||
|
||||
class KnowledgeReadHandler:
|
||||
def GET(self):
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
try:
|
||||
from agent.knowledge.service import KnowledgeService
|
||||
params = web.input(path='')
|
||||
svc = KnowledgeService(_get_workspace_root())
|
||||
result = svc.read_file(params.path)
|
||||
return json.dumps({"status": "success", **result}, ensure_ascii=False)
|
||||
except (ValueError, FileNotFoundError) as e:
|
||||
return json.dumps({"status": "error", "message": str(e)})
|
||||
except Exception as e:
|
||||
logger.error(f"[WebChannel] Knowledge read error: {e}")
|
||||
return json.dumps({"status": "error", "message": str(e)})
|
||||
|
||||
|
||||
class KnowledgeGraphHandler:
|
||||
def GET(self):
|
||||
_require_auth()
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
try:
|
||||
from agent.knowledge.service import KnowledgeService
|
||||
svc = KnowledgeService(_get_workspace_root())
|
||||
return json.dumps(svc.build_graph(), ensure_ascii=False)
|
||||
except Exception as e:
|
||||
logger.error(f"[WebChannel] Knowledge graph error: {e}")
|
||||
return json.dumps({"nodes": [], "links": []})
|
||||
|
||||
|
||||
class VersionHandler:
|
||||
def GET(self):
|
||||
web.header('Content-Type', 'application/json; charset=utf-8')
|
||||
|
||||
@@ -6,6 +6,7 @@ from cli.commands.skill import skill
|
||||
from cli.commands.process import start, stop, restart, update, status, logs
|
||||
from cli.commands.context import context
|
||||
from cli.commands.install import install_browser
|
||||
from cli.commands.knowledge import knowledge
|
||||
|
||||
|
||||
HELP_TEXT = """Usage: cow COMMAND [ARGS]...
|
||||
@@ -22,6 +23,7 @@ Commands:
|
||||
status Show CowAgent running status.
|
||||
logs View CowAgent logs.
|
||||
skill Manage CowAgent skills.
|
||||
knowledge Manage knowledge base.
|
||||
install-browser Install browser tool (Playwright + Chromium).
|
||||
|
||||
Tip: You can also send /help, /skill list, etc. in agent chat."""
|
||||
@@ -69,6 +71,7 @@ main.add_command(update)
|
||||
main.add_command(status)
|
||||
main.add_command(logs)
|
||||
main.add_command(context)
|
||||
main.add_command(knowledge)
|
||||
main.add_command(install_browser)
|
||||
|
||||
|
||||
|
||||
121
cli/commands/knowledge.py
Normal file
121
cli/commands/knowledge.py
Normal file
@@ -0,0 +1,121 @@
|
||||
"""cow knowledge - Knowledge base management commands."""
|
||||
|
||||
import os
|
||||
|
||||
import click
|
||||
|
||||
from cli.utils import get_project_root
|
||||
|
||||
|
||||
def _get_knowledge_dir():
|
||||
"""Resolve the knowledge directory path from config or default."""
|
||||
try:
|
||||
import sys
|
||||
sys.path.insert(0, get_project_root())
|
||||
from config import conf
|
||||
from common.utils import expand_path
|
||||
workspace = expand_path(conf().get("agent_workspace", "~/cow"))
|
||||
except Exception:
|
||||
workspace = os.path.expanduser("~/cow")
|
||||
return os.path.join(workspace, "knowledge")
|
||||
|
||||
|
||||
def _get_knowledge_enabled():
|
||||
try:
|
||||
import sys
|
||||
sys.path.insert(0, get_project_root())
|
||||
from config import conf
|
||||
return conf().get("knowledge", True)
|
||||
except Exception:
|
||||
return True
|
||||
|
||||
|
||||
@click.group(invoke_without_command=True)
|
||||
@click.pass_context
|
||||
def knowledge(ctx):
|
||||
"""Manage CowAgent knowledge base."""
|
||||
if ctx.invoked_subcommand is None:
|
||||
click.echo(_stats())
|
||||
|
||||
|
||||
@knowledge.command("list")
|
||||
def knowledge_list():
|
||||
"""Display knowledge base file tree."""
|
||||
click.echo(_tree())
|
||||
|
||||
|
||||
def _stats() -> str:
|
||||
knowledge_dir = _get_knowledge_dir()
|
||||
if not os.path.isdir(knowledge_dir):
|
||||
return "Knowledge base directory not found."
|
||||
|
||||
enabled = _get_knowledge_enabled()
|
||||
total_files = 0
|
||||
total_bytes = 0
|
||||
cat_count = {}
|
||||
|
||||
for root, dirs, files in os.walk(knowledge_dir):
|
||||
dirs[:] = [d for d in dirs if not d.startswith(".")]
|
||||
rel_root = os.path.relpath(root, knowledge_dir)
|
||||
category = rel_root.split(os.sep)[0] if rel_root != "." else "root"
|
||||
for f in files:
|
||||
if f.endswith(".md") and f not in ("index.md", "log.md"):
|
||||
total_files += 1
|
||||
total_bytes += os.path.getsize(os.path.join(root, f))
|
||||
cat_count[category] = cat_count.get(category, 0) + 1
|
||||
|
||||
status_icon = click.style("enabled", fg="green") if enabled else click.style("disabled", fg="red")
|
||||
lines = [
|
||||
f"\n Knowledge Base [{status_icon}]",
|
||||
"",
|
||||
f" Pages: {total_files}",
|
||||
f" Size: {total_bytes / 1024:.1f} KB",
|
||||
"",
|
||||
]
|
||||
if cat_count:
|
||||
lines.append(" Categories:")
|
||||
for cat in sorted(cat_count.keys()):
|
||||
lines.append(f" {cat}/ ({cat_count[cat]} pages)")
|
||||
lines.append("")
|
||||
|
||||
lines.append(f" Path: {knowledge_dir}")
|
||||
lines.append("")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def _tree() -> str:
|
||||
knowledge_dir = _get_knowledge_dir()
|
||||
if not os.path.isdir(knowledge_dir):
|
||||
return "Knowledge base directory not found."
|
||||
|
||||
tree_lines = [" knowledge/"]
|
||||
|
||||
subdirs = sorted([
|
||||
d for d in os.listdir(knowledge_dir)
|
||||
if os.path.isdir(os.path.join(knowledge_dir, d)) and not d.startswith(".")
|
||||
])
|
||||
|
||||
for i, subdir in enumerate(subdirs):
|
||||
is_last_dir = (i == len(subdirs) - 1)
|
||||
branch = "└── " if is_last_dir else "├── "
|
||||
subdir_path = os.path.join(knowledge_dir, subdir)
|
||||
md_files = sorted([
|
||||
f for f in os.listdir(subdir_path)
|
||||
if f.endswith(".md") and not f.startswith(".")
|
||||
])
|
||||
tree_lines.append(f" {branch}{subdir}/ ({len(md_files)})")
|
||||
|
||||
child_prefix = " " if is_last_dir else " │ "
|
||||
max_show = 15
|
||||
for j, fname in enumerate(md_files[:max_show]):
|
||||
is_last_file = (j == len(md_files[:max_show]) - 1) and len(md_files) <= max_show
|
||||
fb = "└── " if is_last_file else "├── "
|
||||
name = fname.replace(".md", "")
|
||||
tree_lines.append(f"{child_prefix}{fb}{name}")
|
||||
if len(md_files) > max_show:
|
||||
tree_lines.append(f"{child_prefix}└── ... +{len(md_files) - max_show} more")
|
||||
|
||||
if not subdirs:
|
||||
tree_lines.append(" (empty)")
|
||||
|
||||
return "\n" + "\n".join(tree_lines) + "\n"
|
||||
@@ -54,6 +54,7 @@ class CloudClient(LinkAIClient):
|
||||
self.channel_mgr = None
|
||||
self._skill_service = None
|
||||
self._memory_service = None
|
||||
self._knowledge_service = None
|
||||
self._chat_service = None
|
||||
|
||||
@property
|
||||
@@ -88,6 +89,21 @@ class CloudClient(LinkAIClient):
|
||||
logger.error(f"[CloudClient] Failed to init MemoryService: {e}")
|
||||
return self._memory_service
|
||||
|
||||
@property
|
||||
def knowledge_service(self):
|
||||
"""Lazy-init KnowledgeService."""
|
||||
if self._knowledge_service is None:
|
||||
try:
|
||||
from agent.knowledge.service import KnowledgeService
|
||||
from config import conf
|
||||
from common.utils import expand_path
|
||||
workspace_root = expand_path(conf().get("agent_workspace", "~/cow"))
|
||||
self._knowledge_service = KnowledgeService(workspace_root)
|
||||
logger.debug("[CloudClient] KnowledgeService initialised")
|
||||
except Exception as e:
|
||||
logger.error(f"[CloudClient] Failed to init KnowledgeService: {e}")
|
||||
return self._knowledge_service
|
||||
|
||||
@property
|
||||
def chat_service(self):
|
||||
"""Lazy-init ChatService (requires AgentBridge via Bridge singleton)."""
|
||||
@@ -468,6 +484,27 @@ class CloudClient(LinkAIClient):
|
||||
|
||||
return svc.dispatch(action, payload)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# knowledge callback
|
||||
# ------------------------------------------------------------------
|
||||
def on_knowledge(self, data: dict) -> dict:
|
||||
"""
|
||||
Handle KNOWLEDGE messages from the cloud console.
|
||||
Delegates to KnowledgeService.dispatch for the actual operations.
|
||||
|
||||
:param data: message data with 'action', 'clientId', 'payload'
|
||||
:return: response dict
|
||||
"""
|
||||
action = data.get("action", "")
|
||||
payload = data.get("payload")
|
||||
logger.info(f"[CloudClient] on_knowledge: action={action}")
|
||||
|
||||
svc = self.knowledge_service
|
||||
if svc is None:
|
||||
return {"action": action, "code": 500, "message": "KnowledgeService not available", "payload": None}
|
||||
|
||||
return svc.dispatch(action, payload)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# chat callback
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
@@ -93,6 +93,7 @@ QWQ_PLUS = "qwq-plus"
|
||||
|
||||
# MiniMax
|
||||
MINIMAX_M2_7 = "MiniMax-M2.7" # MiniMax M2.7 - Latest
|
||||
MINIMAX_M2_7_HIGHSPEED = "MiniMax-M2.7-highspeed" # MiniMax M2.7 highspeed
|
||||
MINIMAX_M2_5 = "MiniMax-M2.5" # MiniMax M2.5
|
||||
MINIMAX_M2_1 = "MiniMax-M2.1" # MiniMax M2.1
|
||||
MINIMAX_M2_1_LIGHTNING = "MiniMax-M2.1-lightning" # MiniMax M2.1 极速版
|
||||
@@ -175,7 +176,7 @@ MODEL_LIST = [
|
||||
QWEN36_PLUS, QWEN35_PLUS, QWEN3_MAX, QWEN_MAX, QWEN_PLUS, QWEN_TURBO, QWEN_LONG,
|
||||
|
||||
# MiniMax
|
||||
MiniMax, MINIMAX_M2_7, MINIMAX_M2_5, MINIMAX_M2_1, MINIMAX_M2_1_LIGHTNING, MINIMAX_M2, MINIMAX_ABAB6_5,
|
||||
MiniMax, MINIMAX_M2_7, MINIMAX_M2_7_HIGHSPEED, MINIMAX_M2_5, MINIMAX_M2_1, MINIMAX_M2_1_LIGHTNING, MINIMAX_M2, MINIMAX_ABAB6_5,
|
||||
|
||||
# GLM
|
||||
ZHIPU_AI, GLM_5_TURBO, GLM_5, GLM_4, GLM_4_PLUS, GLM_4_flash, GLM_4_LONG, GLM_4_ALLTOOLS,
|
||||
|
||||
@@ -26,8 +26,10 @@
|
||||
"dingtalk_client_secret":"",
|
||||
"wecom_bot_id": "",
|
||||
"wecom_bot_secret": "",
|
||||
"web_password": "",
|
||||
"agent": true,
|
||||
"agent_max_context_tokens": 40000,
|
||||
"agent_max_context_tokens": 50000,
|
||||
"agent_max_context_turns": 20,
|
||||
"agent_max_steps": 15
|
||||
"agent_max_steps": 20,
|
||||
"knowledge": true
|
||||
}
|
||||
|
||||
11
config.py
11
config.py
@@ -180,14 +180,14 @@ available_setting = {
|
||||
# 豆包(火山方舟) 平台配置
|
||||
"ark_api_key": "",
|
||||
"ark_base_url": "https://ark.cn-beijing.volces.com/api/v3",
|
||||
#魔搭社区 平台配置
|
||||
# 魔搭社区 平台配置
|
||||
"modelscope_api_key": "",
|
||||
"modelscope_base_url": "https://api-inference.modelscope.cn/v1/chat/completions",
|
||||
# LinkAI平台配置
|
||||
"use_linkai": False,
|
||||
"linkai_api_key": "",
|
||||
"linkai_app_code": "",
|
||||
"linkai_api_base": "https://api.link-ai.tech", # linkAI服务地址
|
||||
"linkai_api_base": "https://api.link-ai.tech",
|
||||
"cloud_host": "client.link-ai.tech",
|
||||
"cloud_port": None,
|
||||
"cloud_deployment_id": "",
|
||||
@@ -195,11 +195,14 @@ available_setting = {
|
||||
"Minimax_group_id": "",
|
||||
"Minimax_base_url": "",
|
||||
"web_port": 9899,
|
||||
"web_password": "", # Web console password; empty means no authentication required
|
||||
"web_session_expire_days": 30, # Auth session expiry in days
|
||||
"agent": True, # 是否开启Agent模式
|
||||
"agent_workspace": "~/cow", # agent工作空间路径,用于存储skills、memory等
|
||||
"agent_max_context_tokens": 50000, # Agent模式下最大上下文tokens
|
||||
"agent_max_context_turns": 30, # Agent模式下最大上下文记忆轮次
|
||||
"agent_max_steps": 15, # Agent模式下单次运行最大决策步数
|
||||
"agent_max_context_turns": 20, # Agent模式下最大上下文记忆轮次
|
||||
"agent_max_steps": 20, # Agent模式下单次运行最大决策步数
|
||||
"knowledge": True, # 是否开启知识库功能
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,9 +35,10 @@ services:
|
||||
DINGTALK_CLIENT_SECRET: ''
|
||||
WECOM_BOT_ID: ''
|
||||
WECOM_BOT_SECRET: ''
|
||||
WEB_PASSWORD: ''
|
||||
AGENT: 'True'
|
||||
AGENT_MAX_CONTEXT_TOKENS: 40000
|
||||
AGENT_MAX_CONTEXT_TOKENS: 50000
|
||||
AGENT_MAX_CONTEXT_TURNS: 20
|
||||
AGENT_MAX_STEPS: 15
|
||||
AGENT_MAX_STEPS: 20
|
||||
volumes:
|
||||
- ./cow:/home/agent/cow
|
||||
|
||||
@@ -30,6 +30,25 @@ Web 控制台是 CowAgent 的默认通道,启动后会自动运行,通过浏
|
||||
请确保服务器防火墙和安全组已放行对应端口。
|
||||
</Note>
|
||||
|
||||
## 密码保护
|
||||
|
||||
Web 控制台默认无需密码即可访问。如果部署在公网环境,建议配置访问密码:
|
||||
|
||||
```json
|
||||
{
|
||||
"web_password": "your_password"
|
||||
}
|
||||
```
|
||||
|
||||
| 参数 | 说明 | 默认值 |
|
||||
| --- | --- | --- |
|
||||
| `web_password` | 访问密码,留空表示不启用密码保护 | `""` |
|
||||
| `web_session_expire_days` | 登录会话有效天数 | `30` |
|
||||
|
||||
配置密码后,访问控制台时需先输入密码完成登录。登录状态默认保持 30 天,期间重启服务也无需重新登录。修改密码后,所有已登录的会话将自动失效。
|
||||
|
||||
密码也支持在控制台的「配置」页面中在线修改。
|
||||
|
||||
## 功能介绍
|
||||
|
||||
### 对话界面
|
||||
|
||||
@@ -106,6 +106,45 @@ Session: 12 messages | 8 skills loaded
|
||||
/logs 50
|
||||
```
|
||||
|
||||
## knowledge
|
||||
|
||||
查看和管理个人知识库。默认显示知识库统计信息。
|
||||
|
||||
```text
|
||||
/knowledge
|
||||
```
|
||||
|
||||
输出示例:
|
||||
|
||||
```
|
||||
📚 知识库
|
||||
|
||||
- 状态:已开启
|
||||
- 页面数:12
|
||||
- 总大小:45.2 KB
|
||||
- 分类明细:
|
||||
- concepts/: 5 篇
|
||||
- entities/: 4 篇
|
||||
- sources/: 3 篇
|
||||
```
|
||||
|
||||
**查看目录结构:**
|
||||
|
||||
```text
|
||||
/knowledge list
|
||||
```
|
||||
|
||||
**开启 / 关闭知识库:**
|
||||
|
||||
```text
|
||||
/knowledge on
|
||||
/knowledge off
|
||||
```
|
||||
|
||||
<Note>
|
||||
终端 CLI 中 `cow knowledge` 和 `cow knowledge list` 可用,但 `on|off` 仅支持在对话中使用(需实时生效)。
|
||||
</Note>
|
||||
|
||||
## version
|
||||
|
||||
显示当前 CowAgent 版本号。
|
||||
|
||||
@@ -40,6 +40,9 @@ Service:
|
||||
Skills:
|
||||
skill Manage skills (list / search / install / uninstall ...)
|
||||
|
||||
Knowledge:
|
||||
knowledge View knowledge base stats and structure
|
||||
|
||||
Others:
|
||||
help Show this help message
|
||||
version Show version
|
||||
@@ -55,6 +58,9 @@ Others:
|
||||
| `/status` | 查看服务状态和配置 |
|
||||
| `/config` | 查看或修改运行时配置 |
|
||||
| `/skill` | 管理技能(安装、卸载、启用、禁用等) |
|
||||
| `/knowledge` | 查看知识库统计信息 |
|
||||
| `/knowledge list` | 查看知识库目录结构 |
|
||||
| `/knowledge on\|off` | 开启或关闭知识库 |
|
||||
| `/context` | 查看当前会话上下文信息 |
|
||||
| `/context clear` | 清空当前会话上下文 |
|
||||
| `/logs` | 查看最近日志 |
|
||||
@@ -76,6 +82,7 @@ Others:
|
||||
| logs | ✓ | ✓ |
|
||||
| config | ✗ | ✓ |
|
||||
| context | — | ✓ |
|
||||
| knowledge (子命令) | ✓ | ✓ |
|
||||
| skill (子命令) | ✓ | ✓ |
|
||||
| start / stop / restart | ✓ | ✗ |
|
||||
| update | ✓ | ✗ |
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
},
|
||||
{
|
||||
"label": "GitHub",
|
||||
"href": "https://github.com/zhayujie/chatgpt-on-wechat"
|
||||
"href": "https://github.com/zhayujie/CowAgent"
|
||||
}
|
||||
]
|
||||
},
|
||||
"footer": {
|
||||
"socials": {
|
||||
"github": "https://github.com/zhayujie/chatgpt-on-wechat"
|
||||
"github": "https://github.com/zhayujie/CowAgent"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
@@ -147,6 +147,17 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tab": "知识",
|
||||
"groups": [
|
||||
{
|
||||
"group": "知识库",
|
||||
"pages": [
|
||||
"knowledge/index"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tab": "通道",
|
||||
"groups": [
|
||||
@@ -308,6 +319,17 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tab": "Knowledge",
|
||||
"groups": [
|
||||
{
|
||||
"group": "Knowledge Base",
|
||||
"pages": [
|
||||
"en/knowledge/index"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tab": "Channels",
|
||||
"groups": [
|
||||
@@ -469,6 +491,17 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tab": "ナレッジ",
|
||||
"groups": [
|
||||
{
|
||||
"group": "ナレッジベース",
|
||||
"pages": [
|
||||
"ja/knowledge/index"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tab": "チャネル",
|
||||
"groups": [
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<p align="center"><img src="https://github.com/user-attachments/assets/eca9a9ec-8534-4615-9e0f-96c5ac1d10a3" alt="CowAgent" width="550" /></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/zhayujie/chatgpt-on-wechat/releases/latest"><img src="https://img.shields.io/github/v/release/zhayujie/chatgpt-on-wechat" alt="Latest release"></a>
|
||||
<a href="https://github.com/zhayujie/chatgpt-on-wechat/blob/master/LICENSE"><img src="https://img.shields.io/github/license/zhayujie/chatgpt-on-wechat" alt="License: MIT"></a>
|
||||
<a href="https://github.com/zhayujie/chatgpt-on-wechat"><img src="https://img.shields.io/github/stars/zhayujie/chatgpt-on-wechat?style=flat-square" alt="Stars"></a> <br/>
|
||||
[<a href="https://github.com/zhayujie/chatgpt-on-wechat/blob/master/README.md">中文</a>] | [English] | [<a href="https://github.com/zhayujie/chatgpt-on-wechat/blob/master/docs/ja/README.md">日本語</a>]
|
||||
<a href="https://github.com/zhayujie/CowAgent/releases/latest"><img src="https://img.shields.io/github/v/release/zhayujie/CowAgent" alt="Latest release"></a>
|
||||
<a href="https://github.com/zhayujie/CowAgent/blob/master/LICENSE"><img src="https://img.shields.io/github/license/zhayujie/CowAgent" alt="License: MIT"></a>
|
||||
<a href="https://github.com/zhayujie/CowAgent"><img src="https://img.shields.io/github/stars/zhayujie/CowAgent?style=flat-square" alt="Stars"></a> <br/>
|
||||
[<a href="https://github.com/zhayujie/CowAgent/blob/master/README.md">中文</a>] | [English] | [<a href="https://github.com/zhayujie/CowAgent/blob/master/docs/ja/README.md">日本語</a>]
|
||||
</p>
|
||||
|
||||
**CowAgent** is an AI super assistant powered by LLMs, capable of autonomous task planning, operating computers and external resources, creating and executing Skills, and continuously growing with long-term memory. It supports flexible model switching, handles text, voice, images, and files, and can be integrated into WeChat, Web, Feishu, DingTalk, WeCom Bot, WeCom App, and WeChat Official Account — running 7×24 hours on your personal computer or server.
|
||||
**CowAgent** is an AI super assistant powered by LLMs, capable of autonomous task planning, operating computers and external resources, creating and executing Skills, and continuously growing with long-term memory and a personal knowledge base. It supports flexible model switching, handles text, voice, images, and files, and can be integrated into WeChat, Web, Feishu, DingTalk, WeCom Bot, WeCom App, and WeChat Official Account — running 7×24 hours on your personal computer or server.
|
||||
|
||||
<p align="center">
|
||||
<a href="https://cowagent.ai/">🌐 Website</a> ·
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
- ✅ **Autonomous Task Planning**: Understands complex tasks and autonomously plans execution, continuously thinking and invoking tools until goals are achieved.
|
||||
- ✅ **Long-term Memory**: Automatically persists conversation memory to local files and databases, including core memory and daily memory, with keyword and vector retrieval support.
|
||||
- ✅ **Personal Knowledge Base**: Automatically organizes structured knowledge with cross-references to build a knowledge graph, with web-based visualization and conversational management.
|
||||
- ✅ **Skills System**: Implements a Skills creation and execution engine, supports installing skills from [Skill Hub](https://skills.cowagent.ai), GitHub, etc., or creating custom Skills through conversation.
|
||||
- ✅ **Tool System**: Built-in tools for file I/O, terminal execution, browser automation, scheduled tasks, messaging, and more — autonomously invoked by the Agent.
|
||||
- ✅ **CLI System**: Provides terminal commands and in-chat commands for process management, skill installation, configuration, and more.
|
||||
@@ -42,19 +43,19 @@ Try online (no deployment needed): [CowAgent](https://link-ai.tech/cowagent/crea
|
||||
|
||||
## Changelog
|
||||
|
||||
> **2026.04.01:** [v2.0.5](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.5) — Cow CLI, Skill Hub open source, Browser tool, WeCom Bot QR scan, and more.
|
||||
> **2026.04.01:** [v2.0.5](https://github.com/zhayujie/CowAgent/releases/tag/2.0.5) — Cow CLI, Skill Hub open source, Browser tool, WeCom Bot QR scan, and more.
|
||||
|
||||
> **2026.02.27:** [v2.0.2](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.2) — Web console overhaul (streaming chat, model/skill/memory/channel/scheduler/log management), multi-channel concurrent running, session persistence, new models including Gemini 3.1 Pro / Claude 4.6 Sonnet / Qwen3.5 Plus.
|
||||
> **2026.02.27:** [v2.0.2](https://github.com/zhayujie/CowAgent/releases/tag/2.0.2) — Web console overhaul (streaming chat, model/skill/memory/channel/scheduler/log management), multi-channel concurrent running, session persistence, new models including Gemini 3.1 Pro / Claude 4.6 Sonnet / Qwen3.5 Plus.
|
||||
|
||||
> **2026.02.13:** [v2.0.1](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.1) — Built-in Web Search tool, smart context trimming, runtime info dynamic update, Windows compatibility, fixes for scheduler memory loss, Feishu connection issues, and more.
|
||||
> **2026.02.13:** [v2.0.1](https://github.com/zhayujie/CowAgent/releases/tag/2.0.1) — Built-in Web Search tool, smart context trimming, runtime info dynamic update, Windows compatibility, fixes for scheduler memory loss, Feishu connection issues, and more.
|
||||
|
||||
> **2026.02.03:** [v2.0.0](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.0) — Full upgrade to AI super assistant with multi-step task planning, long-term memory, built-in tools, Skills framework, new models, and optimized channels.
|
||||
> **2026.02.03:** [v2.0.0](https://github.com/zhayujie/CowAgent/releases/tag/2.0.0) — Full upgrade to AI super assistant with multi-step task planning, long-term memory, built-in tools, Skills framework, new models, and optimized channels.
|
||||
|
||||
> **2025.05.23:** [v1.7.6](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/1.7.6) — Web channel optimization, AgentMesh multi-agent plugin, Baidu TTS, claude-4-sonnet/opus support.
|
||||
> **2025.05.23:** [v1.7.6](https://github.com/zhayujie/CowAgent/releases/tag/1.7.6) — Web channel optimization, AgentMesh multi-agent plugin, Baidu TTS, claude-4-sonnet/opus support.
|
||||
|
||||
> **2025.04.11:** [v1.7.5](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/1.7.5) — wechatferry protocol, DeepSeek model, Tencent Cloud voice, ModelScope and Gitee-AI support.
|
||||
> **2025.04.11:** [v1.7.5](https://github.com/zhayujie/CowAgent/releases/tag/1.7.5) — wechatferry protocol, DeepSeek model, Tencent Cloud voice, ModelScope and Gitee-AI support.
|
||||
|
||||
> **2024.12.13:** [v1.7.4](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/1.7.4) — Gemini 2.0 model, Web channel, memory leak fix.
|
||||
> **2024.12.13:** [v1.7.4](https://github.com/zhayujie/CowAgent/releases/tag/1.7.4) — Gemini 2.0 model, Web channel, memory leak fix.
|
||||
|
||||
Full changelog: [Release Notes](https://docs.cowagent.ai/en/releases/overview)
|
||||
|
||||
@@ -83,8 +84,8 @@ Script usage: [One-click Install](https://docs.cowagent.ai/en/guide/quick-start)
|
||||
**1. Clone the project**
|
||||
|
||||
```bash
|
||||
git clone https://github.com/zhayujie/chatgpt-on-wechat
|
||||
cd chatgpt-on-wechat/
|
||||
git clone https://github.com/zhayujie/CowAgent
|
||||
cd CowAgent/
|
||||
```
|
||||
|
||||
**2. Install dependencies**
|
||||
@@ -232,16 +233,16 @@ Multiple channels can be enabled simultaneously, separated by commas: `"channel_
|
||||
|
||||
## 🔎 FAQ
|
||||
|
||||
FAQs: <https://github.com/zhayujie/chatgpt-on-wechat/wiki/FAQs>
|
||||
FAQs: <https://github.com/zhayujie/CowAgent/wiki/FAQs>
|
||||
|
||||
## 🛠️ Contributing
|
||||
|
||||
Welcome to add new channels, referring to the [Feishu channel](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/channel/feishu/feishu_channel.py) as an example. Also welcome to contribute new Skills, see the [Skill Creation docs](https://docs.cowagent.ai/en/skills/create), or submit to [Skill Hub](https://skills.cowagent.ai/submit).
|
||||
Welcome to add new channels, referring to the [Feishu channel](https://github.com/zhayujie/CowAgent/blob/master/channel/feishu/feishu_channel.py) as an example. Also welcome to contribute new Skills, see the [Skill Creation docs](https://docs.cowagent.ai/en/skills/create), or submit to [Skill Hub](https://skills.cowagent.ai/submit).
|
||||
|
||||
## ✉ Contact
|
||||
|
||||
Welcome to submit PRs and Issues, and support the project with a 🌟 Star. For questions, check the [FAQ list](https://github.com/zhayujie/chatgpt-on-wechat/wiki/FAQs) or search [Issues](https://github.com/zhayujie/chatgpt-on-wechat/issues).
|
||||
Welcome to submit PRs and Issues, and support the project with a 🌟 Star. For questions, check the [FAQ list](https://github.com/zhayujie/CowAgent/wiki/FAQs) or search [Issues](https://github.com/zhayujie/CowAgent/issues).
|
||||
|
||||
## 🌟 Contributors
|
||||
|
||||

|
||||

|
||||
|
||||
@@ -92,6 +92,31 @@ View recent service logs. Shows the last 20 lines by default, up to 50.
|
||||
/logs 50
|
||||
```
|
||||
|
||||
## knowledge
|
||||
|
||||
View and manage the personal knowledge base. Shows statistics by default.
|
||||
|
||||
```text
|
||||
/knowledge
|
||||
```
|
||||
|
||||
**View directory structure:**
|
||||
|
||||
```text
|
||||
/knowledge list
|
||||
```
|
||||
|
||||
**Enable / disable knowledge base:**
|
||||
|
||||
```text
|
||||
/knowledge on
|
||||
/knowledge off
|
||||
```
|
||||
|
||||
<Note>
|
||||
In the terminal CLI, `cow knowledge` and `cow knowledge list` are available, but `on|off` is only supported in chat (requires runtime effect).
|
||||
</Note>
|
||||
|
||||
## version
|
||||
|
||||
Show the current CowAgent version.
|
||||
|
||||
@@ -40,6 +40,9 @@ Service:
|
||||
Skills:
|
||||
skill Manage skills (list / search / install / uninstall ...)
|
||||
|
||||
Knowledge:
|
||||
knowledge View knowledge base stats and structure
|
||||
|
||||
Others:
|
||||
help Show this help message
|
||||
version Show version
|
||||
@@ -55,6 +58,9 @@ In the Web console or any connected channel, type `/` to see command suggestions
|
||||
| `/status` | View service status and configuration |
|
||||
| `/config` | View or modify runtime configuration |
|
||||
| `/skill` | Manage skills (install, uninstall, enable, disable, etc.) |
|
||||
| `/knowledge` | View knowledge base statistics |
|
||||
| `/knowledge list` | View knowledge base directory structure |
|
||||
| `/knowledge on\|off` | Enable or disable knowledge base |
|
||||
| `/context` | View current session context info |
|
||||
| `/context clear` | Clear current session context |
|
||||
| `/logs` | View recent logs |
|
||||
@@ -74,6 +80,7 @@ In the Web console or any connected channel, type `/` to see command suggestions
|
||||
| logs | ✓ | ✓ |
|
||||
| config | ✗ | ✓ |
|
||||
| context | — | ✓ |
|
||||
| knowledge (subcommands) | ✓ | ✓ |
|
||||
| skill (subcommands) | ✓ | ✓ |
|
||||
| start / stop / restart | ✓ | ✗ |
|
||||
| update | ✓ | ✗ |
|
||||
|
||||
@@ -8,12 +8,12 @@ description: Deploy CowAgent manually (source code / Docker)
|
||||
### 1. Clone the project
|
||||
|
||||
```bash
|
||||
git clone https://github.com/zhayujie/chatgpt-on-wechat
|
||||
cd chatgpt-on-wechat/
|
||||
git clone https://github.com/zhayujie/CowAgent
|
||||
cd CowAgent/
|
||||
```
|
||||
|
||||
<Tip>
|
||||
For network issues, use the mirror: https://gitee.com/zhayujie/chatgpt-on-wechat
|
||||
For network issues, use the mirror: https://gitee.com/zhayujie/CowAgent
|
||||
</Tip>
|
||||
|
||||
### 2. Install dependencies
|
||||
@@ -141,5 +141,5 @@ sudo docker logs -f chatgpt-on-wechat
|
||||
| `agent_max_steps` | Max decision steps per task | `15` |
|
||||
|
||||
<Tip>
|
||||
Full configuration options are in the project [`config.py`](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/config.py).
|
||||
Full configuration options are in the project [`config.py`](https://github.com/zhayujie/CowAgent/blob/master/config.py).
|
||||
</Tip>
|
||||
|
||||
@@ -26,7 +26,7 @@ The script automatically performs these steps:
|
||||
|
||||
1. Check Python environment (requires Python 3.7+)
|
||||
2. Install required tools (git, curl, etc.)
|
||||
3. Clone project to `~/chatgpt-on-wechat`
|
||||
3. Clone project to `~/CowAgent`
|
||||
4. Install Python dependencies and Cow CLI
|
||||
5. Guided configuration for AI model and channel
|
||||
6. Start service
|
||||
|
||||
@@ -11,14 +11,16 @@ CowAgent's architecture consists of the following core modules:
|
||||
|
||||
<img src="https://cdn.link-ai.tech/doc/68ef7b212c6f791e0e74314b912149f9-sz_5847990.png" alt="CowAgent Architecture" />
|
||||
|
||||
### Core Modules
|
||||
|
||||
| Module | Description |
|
||||
| --- | --- |
|
||||
| **Channels** | Message channel layer for receiving and sending messages. Supports Web, Feishu, DingTalk, WeCom, WeChat Official Account, and more |
|
||||
| **Agent Core** | Agent engine including task planning, memory system, and skills engine |
|
||||
| **Tools** | Tool layer for Agent to access OS resources. 10+ built-in tools |
|
||||
| **Models** | Model layer with unified access to mainstream LLMs |
|
||||
| **Plan** | Understands user intent, decomposes complex tasks into multi-step plans, and iteratively invokes tools until the goal is achieved |
|
||||
| **Memory** | Automatically persists important information as core memory and daily memory, with hybrid keyword and vector retrieval for cross-session context continuity |
|
||||
| **Knowledge** | Organizes structured knowledge by topic. The Agent autonomously distills valuable information into Markdown pages, maintaining indexes and cross-references to build a growing knowledge network |
|
||||
| **Tools** | Core capability for Agent to access OS resources. 10+ built-in tools including file read/write, terminal, browser, scheduler, memory search, web search, and more |
|
||||
| **Skills** | Loads and manages Skills. Supports one-click installation from Skill Hub, GitHub, and more, or custom skill creation through conversation |
|
||||
| **Models** | Model layer with unified access to OpenAI, Claude, Gemini, DeepSeek, MiniMax, GLM, Qwen, and other mainstream LLMs |
|
||||
| **Channels** | Message channel layer for receiving and sending messages. Supports Web console, WeChat, Feishu, DingTalk, WeCom, WeChat Official Account, and more with a unified protocol |
|
||||
| **CLI** | Command-line system providing terminal commands (`cow`) and chat commands (`/`) for process management, skill installation, configuration, knowledge base management, and more |
|
||||
|
||||
## Agent Mode Workflow
|
||||
|
||||
@@ -28,7 +30,7 @@ When Agent mode is enabled, CowAgent runs as an autonomous agent with the follow
|
||||
2. **Understand Intent** — Analyze task requirements and context
|
||||
3. **Plan Task** — Break complex tasks into multiple steps
|
||||
4. **Invoke Tools** — Select and execute appropriate tools for each step
|
||||
5. **Update Memory** — Store important information in long-term memory
|
||||
5. **Update Memory & Knowledge** — Store important information in long-term memory and organize structured knowledge into the knowledge base
|
||||
6. **Return Result** — Send execution results back to the user
|
||||
|
||||
## Workspace Directory Structure
|
||||
@@ -39,9 +41,12 @@ The Agent workspace is located at `~/cow` by default and stores system prompts,
|
||||
~/cow/
|
||||
├── system.md # Agent system prompt
|
||||
├── user.md # User profile
|
||||
├── MEMORY.md # Core memory
|
||||
├── memory/ # Long-term memory storage
|
||||
│ ├── core.md # Core memory
|
||||
│ └── daily/ # Daily memory
|
||||
│ └── YYYY-MM-DD.md # Daily memory
|
||||
├── knowledge/ # Personal knowledge base
|
||||
│ ├── index.md # Knowledge index
|
||||
│ └── <category>/ # Topic-based pages
|
||||
└── skills/ # Custom skills
|
||||
├── skill-1/
|
||||
└── skill-2/
|
||||
@@ -75,3 +80,4 @@ Configure Agent mode parameters in `config.json`:
|
||||
| `agent_max_context_tokens` | Max context tokens | `40000` |
|
||||
| `agent_max_context_turns` | Max context turns | `30` |
|
||||
| `agent_max_steps` | Max decision steps per task | `15` |
|
||||
| `knowledge` | Enable personal knowledge base | `true` |
|
||||
|
||||
@@ -15,13 +15,26 @@ In subsequent long-term conversations, the Agent intelligently stores or retriev
|
||||
<img src="https://cdn.link-ai.tech/doc/20260203000455.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
## 2. Task Planning and Tool Use
|
||||
## 2. Personal Knowledge Base
|
||||
|
||||
> The knowledge base system enables the Agent to continuously accumulate and organize structured knowledge. Unlike memory which records along a timeline, the knowledge base is organized by topics, transforming articles, conversation insights, and learning materials into interconnected Markdown pages that form a continuously growing knowledge network.
|
||||
|
||||
The Agent automatically organizes valuable information from conversations into knowledge pages, maintaining cross-references and indexes. The Web console provides document browsing and knowledge graph visualization. Knowledge is stored in `~/cow/knowledge/` within the workspace.
|
||||
|
||||
- **Auto-organization**: The Agent autonomously extracts and organizes structured knowledge during conversations, maintaining indexes and cross-references
|
||||
- **Knowledge graph**: Automatically builds a knowledge graph from cross-references between pages, with interactive graph visualization in the Web console
|
||||
- **Chat integration**: Knowledge document links referenced in Agent replies can be clicked directly in the Web console for viewing
|
||||
- **CLI management**: Use `/knowledge` commands to view stats, browse directory, and toggle the feature with `/knowledge on|off`
|
||||
|
||||
See [Personal Knowledge Base](/en/knowledge) for details.
|
||||
|
||||
## 3. Task Planning and Tool Use
|
||||
|
||||
Tools are the core of how the Agent accesses operating system resources. The Agent intelligently selects and invokes tools based on task requirements, performing file read/write, command execution, scheduled tasks, and more. Built-in tools are implemented in the project's `agent/tools/` directory.
|
||||
|
||||
**Key tools:** file read/write/edit, Bash terminal, browser, file send, scheduler, memory search, web search, environment config, and more.
|
||||
|
||||
### 2.1 Terminal and File Access
|
||||
### 3.1 Terminal and File Access
|
||||
|
||||
Access to the OS terminal and file system is the most fundamental and core capability. Many other tools and skills build on top of this. Users can interact with the Agent from a mobile device to operate resources on their personal computer or server:
|
||||
|
||||
@@ -29,7 +42,7 @@ Access to the OS terminal and file system is the most fundamental and core capab
|
||||
<img src="https://cdn.link-ai.tech/doc/20260202181130.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 2.2 Programming Capability
|
||||
### 3.2 Programming Capability
|
||||
|
||||
Combining programming and system access, the Agent can execute the complete **Vibecoding workflow** — from information search, asset generation, coding, testing, deployment, Nginx configuration, to publishing — all triggered by a single command from your phone:
|
||||
|
||||
@@ -37,7 +50,7 @@ Combining programming and system access, the Agent can execute the complete **Vi
|
||||
<img src="https://cdn.link-ai.tech/doc/20260203121008.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 2.3 Scheduled Tasks
|
||||
### 3.3 Scheduled Tasks
|
||||
|
||||
The `scheduler` tool enables dynamic scheduled tasks, supporting **one-time tasks, fixed intervals, and Cron expressions**. Tasks can be triggered as either a **fixed message send** or an **Agent dynamic task** execution:
|
||||
|
||||
@@ -45,7 +58,7 @@ The `scheduler` tool enables dynamic scheduled tasks, supporting **one-time task
|
||||
<img src="https://cdn.link-ai.tech/doc/20260202195402.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 2.4 Browser
|
||||
### 3.4 Browser
|
||||
|
||||
The built-in `browser` tool allows the Agent to control a Chromium browser to visit web pages, fill forms, click elements, and take screenshots, with support for dynamic JS-rendered pages. Run `cow install-browser` to install with one command, automatically adapting to server (headless) and desktop environments:
|
||||
|
||||
@@ -53,7 +66,7 @@ The built-in `browser` tool allows the Agent to control a Chromium browser to vi
|
||||
<img src="https://cdn.link-ai.tech/doc/20260401110103.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 2.5 Environment Variable Management
|
||||
### 3.5 Environment Variable Management
|
||||
|
||||
Secrets required by skills are stored in an environment variable file, managed by the `env_config` tool. You can update secrets through conversation, with built-in security protection and desensitization:
|
||||
|
||||
@@ -61,7 +74,7 @@ Secrets required by skills are stored in an environment variable file, managed b
|
||||
<img src="https://cdn.link-ai.tech/doc/20260202234939.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
## 3. Skills System
|
||||
## 4. Skills System
|
||||
|
||||
The Skills system provides infinite extensibility for the Agent. Each Skill consists of a description file, execution scripts (optional), and resources (optional), describing how to complete specific types of tasks. Skills allow the Agent to follow instructions for complex workflows, invoke tools, or integrate third-party systems.
|
||||
|
||||
@@ -71,7 +84,7 @@ The Skills system provides infinite extensibility for the Agent. Each Skill cons
|
||||
|
||||
Install skills: `/skill install <name>` or `cow skill install <name>`, supporting Skill Hub, GitHub, ClawHub, URL, and more.
|
||||
|
||||
### 3.1 Creating Skills
|
||||
### 4.1 Creating Skills
|
||||
|
||||
The `skill-creator` skill enables rapid skill creation through conversation. You can ask the Agent to codify a workflow as a skill, or send any API documentation and examples for the Agent to complete the integration directly:
|
||||
|
||||
@@ -79,7 +92,7 @@ The `skill-creator` skill enables rapid skill creation through conversation. You
|
||||
<img src="https://cdn.link-ai.tech/doc/20260202202247.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 3.2 Web Search and Image Recognition
|
||||
### 4.2 Web Search and Image Recognition
|
||||
|
||||
- **Web search:** Built-in `web_search` tool, supports multiple search engines. Configure `BOCHA_API_KEY` or `LINKAI_API_KEY` to enable.
|
||||
- **Image recognition:** Built-in `openai-image-vision` skill, supports `gpt-4.1-mini`, `gpt-4.1`, and other models. Requires `OPENAI_API_KEY`.
|
||||
@@ -88,7 +101,7 @@ The `skill-creator` skill enables rapid skill creation through conversation. You
|
||||
<img src="https://cdn.link-ai.tech/doc/20260202213219.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 3.3 Skill Hub
|
||||
### 4.3 Skill Hub
|
||||
|
||||
Visit [skills.cowagent.ai](https://skills.cowagent.ai/) to browse all available skills, or use commands in conversation:
|
||||
|
||||
@@ -102,7 +115,7 @@ Also supports installing skills from GitHub, ClawHub, LinkAI, and other third-pa
|
||||
|
||||
<img src="https://cdn.link-ai.tech/doc/20260401110103.png" width="750" />
|
||||
|
||||
## 4. CLI Command System
|
||||
## 5. CLI Command System
|
||||
|
||||
CowAgent provides two command interaction methods, covering service management, skill installation, configuration, and more:
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ description: CowAgent - AI Super Assistant powered by LLMs
|
||||
|
||||
CowAgent can proactively think and plan tasks, operate computers and external resources, create and execute Skills, and continuously grow with long-term memory. It supports flexible switching between multiple models, handles text, voice, images, files and other multimodal messages, and can be integrated into WeChat, web, Feishu, DingTalk, WeCom, and WeChat Official Account. It runs 7x24 hours on your personal computer or server.
|
||||
|
||||
<Card title="GitHub" icon="github" href="https://github.com/zhayujie/chatgpt-on-wechat">
|
||||
github.com/zhayujie/chatgpt-on-wechat
|
||||
<Card title="GitHub" icon="github" href="https://github.com/zhayujie/CowAgent">
|
||||
github.com/zhayujie/CowAgent
|
||||
</Card>
|
||||
|
||||
## Core Capabilities
|
||||
@@ -22,6 +22,9 @@ CowAgent can proactively think and plan tasks, operate computers and external re
|
||||
<Card title="Long-term Memory" icon="database" href="/en/memory">
|
||||
Automatically persists conversation memory to local files and databases, including core memory and daily memory, with keyword and vector retrieval support.
|
||||
</Card>
|
||||
<Card title="Knowledge Base" icon="book" href="/en/knowledge">
|
||||
Automatically organizes structured knowledge with knowledge graph visualization, building a continuously growing knowledge network through cross-references.
|
||||
</Card>
|
||||
<Card title="Skills System" icon="puzzle-piece" href="/en/skills/index">
|
||||
Implements a Skills creation and execution engine with built-in skills, and supports custom Skills development through natural language conversation.
|
||||
</Card>
|
||||
@@ -72,7 +75,7 @@ By default, the Web service starts after running. Access `http://localhost:9899/
|
||||
|
||||
## Disclaimer
|
||||
|
||||
1. This project follows the [MIT License](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/LICENSE) and is intended for technical research and learning. Users must comply with local laws, regulations, policies, and corporate bylaws. Any illegal or rights-infringing use is prohibited.
|
||||
1. This project follows the [MIT License](https://github.com/zhayujie/CowAgent/blob/master/LICENSE) and is intended for technical research and learning. Users must comply with local laws, regulations, policies, and corporate bylaws. Any illegal or rights-infringing use is prohibited.
|
||||
2. Agent mode consumes more tokens than normal chat mode. Choose models based on effectiveness and cost. Agent has access to the host operating system — deploy with caution.
|
||||
3. CowAgent focuses on open-source development and does not participate in, authorize, or issue any cryptocurrency.
|
||||
|
||||
|
||||
89
docs/en/knowledge/index.mdx
Normal file
89
docs/en/knowledge/index.mdx
Normal file
@@ -0,0 +1,89 @@
|
||||
---
|
||||
title: Personal Knowledge Base
|
||||
description: CowAgent personal knowledge base — structured knowledge accumulation, automatic organization, and knowledge graph
|
||||
---
|
||||
|
||||
The personal knowledge base is the Agent's long-term structured knowledge store, saved in the `knowledge/` directory within the workspace. Unlike memory, which is organized by timeline, the knowledge base organizes content by topic — articles, conversation insights, and learning materials are structured into interlinked Markdown pages, forming a continuously growing knowledge network.
|
||||
|
||||
## Core Concepts
|
||||
|
||||
### Knowledge vs Memory
|
||||
|
||||
| Dimension | Knowledge Base (knowledge/) | Long-term Memory (memory/) |
|
||||
| --- | --- | --- |
|
||||
| Organization | By topic, interlinked | By timeline, dated files |
|
||||
| Writing | Agent actively structures content | Auto-summarized on context trimming |
|
||||
| Content | Refined, structured knowledge | Raw conversation summaries |
|
||||
| Use cases | Study notes, tech docs, project knowledge | Conversation history, event records |
|
||||
|
||||
### Directory Structure
|
||||
|
||||
```
|
||||
~/cow/knowledge/
|
||||
├── index.md # Knowledge index, entry point for all pages
|
||||
├── log.md # Change log, records each write
|
||||
├── concepts/ # Conceptual knowledge
|
||||
│ └── machine-learning.md
|
||||
├── entities/ # Entity knowledge (people, orgs, tools)
|
||||
│ └── openai.md
|
||||
└── sources/ # Source knowledge (articles, papers)
|
||||
└── llm-wiki.md
|
||||
```
|
||||
|
||||
The directory structure is flexible — the Agent automatically creates appropriate category directories based on actual content. Users can also customize the organization.
|
||||
|
||||
## Automatic Organization
|
||||
|
||||
Knowledge writing is an autonomous Agent behavior, triggered in these scenarios:
|
||||
|
||||
- **User shares an article or document** — The Agent automatically extracts key information and creates a structured knowledge page
|
||||
- **Conversation produces valuable conclusions** — The Agent organizes insights into knowledge pages and links them to existing knowledge
|
||||
- **User explicitly requests organization** — Users can guide the Agent to organize and update knowledge through conversation
|
||||
|
||||
Each knowledge page includes cross-reference links to related pages, gradually building a knowledge graph.
|
||||
|
||||
<Frame>
|
||||
<img src="https://gist.github.com/user-attachments/assets/3ce92f78-1863-4820-8fa8-660c0f2b7f09" alt="Conversational knowledge ingest" />
|
||||
</Frame>
|
||||
|
||||
## Knowledge Retrieval
|
||||
|
||||
The Agent can retrieve knowledge during conversation through:
|
||||
|
||||
- **Index lookup** — Quickly locate relevant pages via `knowledge/index.md`
|
||||
- **Semantic search** — Search knowledge content via the `memory_search` tool
|
||||
- **Direct read** — Read specific knowledge files via the `memory_get` tool
|
||||
|
||||
## Web Console
|
||||
|
||||
The web console provides a dedicated "Knowledge" module with:
|
||||
|
||||
- **Document browsing** — Tree-style directory structure, searchable and collapsible, click to view content
|
||||
- **Knowledge graph** — Interactive graph visualizing relationships between knowledge pages
|
||||
- **Chat integration** — Knowledge document links referenced in Agent replies are clickable for direct navigation
|
||||
|
||||
<Frame>
|
||||
<img src="https://gist.github.com/user-attachments/assets/b7b9d6be-0ac1-4c65-803b-2c6b36bd59a7" alt="Knowledge document browsing" />
|
||||
</Frame>
|
||||
|
||||
<Frame>
|
||||
<img src="https://gist.github.com/user-attachments/assets/44ae68ca-96cc-40b9-ab33-cdbec34c2379" alt="Knowledge graph visualization" />
|
||||
</Frame>
|
||||
|
||||
## CLI Commands
|
||||
|
||||
Manage the knowledge base with the `/knowledge` command:
|
||||
|
||||
| Command | Description |
|
||||
| --- | --- |
|
||||
| `/knowledge` | Show knowledge base statistics |
|
||||
| `/knowledge list` | Display file directory as a tree |
|
||||
| `/knowledge on` | Enable the knowledge base feature |
|
||||
| `/knowledge off` | Disable the knowledge base feature |
|
||||
|
||||
## Configuration
|
||||
|
||||
| Parameter | Description | Default |
|
||||
| --- | --- | --- |
|
||||
| `knowledge` | Whether to enable the personal knowledge base | `true` |
|
||||
| `agent_workspace` | Workspace path; knowledge is stored under the `knowledge/` subdirectory | `~/cow` |
|
||||
@@ -51,5 +51,5 @@ You can also use the [LinkAI](https://link-ai.tech) platform interface to flexib
|
||||
</CardGroup>
|
||||
|
||||
<Tip>
|
||||
For a full list of model names, refer to the project's [`common/const.py`](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/common/const.py) file.
|
||||
For a full list of model names, refer to the project's [`common/const.py`](https://github.com/zhayujie/CowAgent/blob/master/common/const.py) file.
|
||||
</Tip>
|
||||
|
||||
@@ -22,4 +22,4 @@ description: CowAgent version history
|
||||
| 1.5.0 | 2023.11.10 | gpt-4-turbo, dall-e-3, tts multimodal |
|
||||
| 1.0.0 | 2022.12.12 | Project created, first ChatGPT integration |
|
||||
|
||||
See [GitHub Releases](https://github.com/zhayujie/chatgpt-on-wechat/releases) for full history.
|
||||
See [GitHub Releases](https://github.com/zhayujie/CowAgent/releases) for full history.
|
||||
|
||||
@@ -5,7 +5,7 @@ description: CowAgent 2.0 - Full upgrade from chatbot to AI super assistant
|
||||
|
||||
CowAgent 2.0 is a comprehensive upgrade from a chatbot to an **AI super assistant** — capable of autonomous thinking and task planning, long-term memory, operating computers, and creating and executing skills.
|
||||
|
||||
**Release Date**: 2026.02.03 | [GitHub Release](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.0)
|
||||
**Release Date**: 2026.02.03 | [GitHub Release](https://github.com/zhayujie/CowAgent/releases/tag/2.0.0)
|
||||
|
||||
## Key Updates
|
||||
|
||||
@@ -60,4 +60,4 @@ CowAgent 2.0 is a comprehensive upgrade from a chatbot to an **AI super assistan
|
||||
|
||||
## Contributing
|
||||
|
||||
Welcome to [submit feedback](https://github.com/zhayujie/chatgpt-on-wechat/issues) and [contribute code](https://github.com/zhayujie/chatgpt-on-wechat/pulls).
|
||||
Welcome to [submit feedback](https://github.com/zhayujie/CowAgent/issues) and [contribute code](https://github.com/zhayujie/CowAgent/pulls).
|
||||
|
||||
@@ -3,34 +3,34 @@ title: v2.0.1
|
||||
description: CowAgent 2.0.1 - Built-in Web Search, smart context management, multiple fixes
|
||||
---
|
||||
|
||||
**Release Date**: 2026.02.27 | [Full Changelog](https://github.com/zhayujie/chatgpt-on-wechat/compare/2.0.0..2.0.1)
|
||||
**Release Date**: 2026.02.27 | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.0..2.0.1)
|
||||
|
||||
## New Features
|
||||
|
||||
- **Built-in Web Search tool**: Integrated web search as a built-in Agent tool, reducing decision cost ([4f0ea5d](https://github.com/zhayujie/chatgpt-on-wechat/commit/4f0ea5d7568d61db91ff69c91c429e785fd1b1c2))
|
||||
- **Claude Opus 4.6 model support**: Added support for Claude Opus 4.6 model ([#2661](https://github.com/zhayujie/chatgpt-on-wechat/pull/2661))
|
||||
- **WeCom image recognition**: Support image message recognition in WeCom channel ([#2667](https://github.com/zhayujie/chatgpt-on-wechat/pull/2667))
|
||||
- **Built-in Web Search tool**: Integrated web search as a built-in Agent tool, reducing decision cost ([4f0ea5d](https://github.com/zhayujie/CowAgent/commit/4f0ea5d7568d61db91ff69c91c429e785fd1b1c2))
|
||||
- **Claude Opus 4.6 model support**: Added support for Claude Opus 4.6 model ([#2661](https://github.com/zhayujie/CowAgent/pull/2661))
|
||||
- **WeCom image recognition**: Support image message recognition in WeCom channel ([#2667](https://github.com/zhayujie/CowAgent/pull/2667))
|
||||
|
||||
## Improvements
|
||||
|
||||
- **Smart context management**: Resolved chat context overflow with intelligent context trimming strategy to prevent token limits ([cea7fb7](https://github.com/zhayujie/chatgpt-on-wechat/commit/cea7fb7490c53454602bf05955a0e9f059bcf0fd), [8acf2db](https://github.com/zhayujie/chatgpt-on-wechat/commit/8acf2dbdfe713b84ad74b761b7f86674b1c1904d)) [#2663](https://github.com/zhayujie/chatgpt-on-wechat/issues/2663)
|
||||
- **Runtime info dynamic update**: Automatic update of timestamps and other runtime info in system prompts via dynamic functions ([#2655](https://github.com/zhayujie/chatgpt-on-wechat/pull/2655), [#2657](https://github.com/zhayujie/chatgpt-on-wechat/pull/2657))
|
||||
- **Skill prompt optimization**: Improved Skill system prompt generation, simplified tool descriptions for better Agent performance ([6c21833](https://github.com/zhayujie/chatgpt-on-wechat/commit/6c218331b1f1208ea8be6bf226936d3b556ade3e))
|
||||
- **GLM custom API Base URL**: Support custom API Base URL for GLM models ([#2660](https://github.com/zhayujie/chatgpt-on-wechat/pull/2660))
|
||||
- **Startup script optimization**: Improved `run.sh` script interaction and configuration flow ([#2656](https://github.com/zhayujie/chatgpt-on-wechat/pull/2656))
|
||||
- **Decision step logging**: Added Agent decision step logging for debugging ([cb303e6](https://github.com/zhayujie/chatgpt-on-wechat/commit/cb303e6109c50c8dfef1f5e6c1ec47223bf3cd11))
|
||||
- **Smart context management**: Resolved chat context overflow with intelligent context trimming strategy to prevent token limits ([cea7fb7](https://github.com/zhayujie/CowAgent/commit/cea7fb7490c53454602bf05955a0e9f059bcf0fd), [8acf2db](https://github.com/zhayujie/CowAgent/commit/8acf2dbdfe713b84ad74b761b7f86674b1c1904d)) [#2663](https://github.com/zhayujie/CowAgent/issues/2663)
|
||||
- **Runtime info dynamic update**: Automatic update of timestamps and other runtime info in system prompts via dynamic functions ([#2655](https://github.com/zhayujie/CowAgent/pull/2655), [#2657](https://github.com/zhayujie/CowAgent/pull/2657))
|
||||
- **Skill prompt optimization**: Improved Skill system prompt generation, simplified tool descriptions for better Agent performance ([6c21833](https://github.com/zhayujie/CowAgent/commit/6c218331b1f1208ea8be6bf226936d3b556ade3e))
|
||||
- **GLM custom API Base URL**: Support custom API Base URL for GLM models ([#2660](https://github.com/zhayujie/CowAgent/pull/2660))
|
||||
- **Startup script optimization**: Improved `run.sh` script interaction and configuration flow ([#2656](https://github.com/zhayujie/CowAgent/pull/2656))
|
||||
- **Decision step logging**: Added Agent decision step logging for debugging ([cb303e6](https://github.com/zhayujie/CowAgent/commit/cb303e6109c50c8dfef1f5e6c1ec47223bf3cd11))
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **Scheduler memory loss**: Fixed memory loss caused by Scheduler dispatcher ([a77a874](https://github.com/zhayujie/chatgpt-on-wechat/commit/a77a8741b500a408c6f5c8868856fb4b018fe9db))
|
||||
- **Empty tool calls & long results**: Fixed handling of empty tool calls and excessively long tool results ([0542700](https://github.com/zhayujie/chatgpt-on-wechat/commit/0542700f9091ebb08c1a56103b0f0f45f24aa621))
|
||||
- **OpenAI Function Call**: Fixed function call compatibility with OpenAI models ([158c87a](https://github.com/zhayujie/chatgpt-on-wechat/commit/158c87ab8b05bae054cc1b4eacdbb64fc1062ba9))
|
||||
- **Claude tool name field**: Removed extraneous tool name field from Claude model responses ([eec10cb](https://github.com/zhayujie/chatgpt-on-wechat/commit/eec10cb5db6a3d5bc12ef606606532237d2c5f6e))
|
||||
- **MiniMax reasoning**: Optimized MiniMax model reasoning content handling, hidden thinking process output ([c72cda3](https://github.com/zhayujie/chatgpt-on-wechat/commit/c72cda33864bd1542012ee6e0a8bd8c6c88cb5ed), [72b1cac](https://github.com/zhayujie/chatgpt-on-wechat/commit/72b1cacea1ba0d1f3dedacbab2e088e98fd7e172))
|
||||
- **GLM thinking process**: Hidden GLM model thinking process display ([72b1cac](https://github.com/zhayujie/chatgpt-on-wechat/commit/72b1cacea1ba0d1f3dedacbab2e088e98fd7e172))
|
||||
- **Feishu connection & SSL**: Fixed Feishu channel SSL certificate errors and connection issues ([229b14b](https://github.com/zhayujie/chatgpt-on-wechat/commit/229b14b6fcabe7123d53cab1dea39f38dab26d6d), [8674421](https://github.com/zhayujie/chatgpt-on-wechat/commit/867442155e7f095b4f38b0856f8c1d8312b5fcf7))
|
||||
- **model_type validation**: Fixed `AttributeError` caused by non-string `model_type` ([#2666](https://github.com/zhayujie/chatgpt-on-wechat/pull/2666))
|
||||
- **Scheduler memory loss**: Fixed memory loss caused by Scheduler dispatcher ([a77a874](https://github.com/zhayujie/CowAgent/commit/a77a8741b500a408c6f5c8868856fb4b018fe9db))
|
||||
- **Empty tool calls & long results**: Fixed handling of empty tool calls and excessively long tool results ([0542700](https://github.com/zhayujie/CowAgent/commit/0542700f9091ebb08c1a56103b0f0f45f24aa621))
|
||||
- **OpenAI Function Call**: Fixed function call compatibility with OpenAI models ([158c87a](https://github.com/zhayujie/CowAgent/commit/158c87ab8b05bae054cc1b4eacdbb64fc1062ba9))
|
||||
- **Claude tool name field**: Removed extraneous tool name field from Claude model responses ([eec10cb](https://github.com/zhayujie/CowAgent/commit/eec10cb5db6a3d5bc12ef606606532237d2c5f6e))
|
||||
- **MiniMax reasoning**: Optimized MiniMax model reasoning content handling, hidden thinking process output ([c72cda3](https://github.com/zhayujie/CowAgent/commit/c72cda33864bd1542012ee6e0a8bd8c6c88cb5ed), [72b1cac](https://github.com/zhayujie/CowAgent/commit/72b1cacea1ba0d1f3dedacbab2e088e98fd7e172))
|
||||
- **GLM thinking process**: Hidden GLM model thinking process display ([72b1cac](https://github.com/zhayujie/CowAgent/commit/72b1cacea1ba0d1f3dedacbab2e088e98fd7e172))
|
||||
- **Feishu connection & SSL**: Fixed Feishu channel SSL certificate errors and connection issues ([229b14b](https://github.com/zhayujie/CowAgent/commit/229b14b6fcabe7123d53cab1dea39f38dab26d6d), [8674421](https://github.com/zhayujie/CowAgent/commit/867442155e7f095b4f38b0856f8c1d8312b5fcf7))
|
||||
- **model_type validation**: Fixed `AttributeError` caused by non-string `model_type` ([#2666](https://github.com/zhayujie/CowAgent/pull/2666))
|
||||
|
||||
## Platform Compatibility
|
||||
|
||||
- **Windows compatibility**: Fixed path handling, file encoding, and `os.getuid()` unavailability on Windows across multiple tool modules ([051ffd7](https://github.com/zhayujie/chatgpt-on-wechat/commit/051ffd78a372f71a967fd3259e37fe19131f83cf), [5264f7c](https://github.com/zhayujie/chatgpt-on-wechat/commit/5264f7ce18360ee4db5dcb4ebe67307977d40014))
|
||||
- **Windows compatibility**: Fixed path handling, file encoding, and `os.getuid()` unavailability on Windows across multiple tool modules ([051ffd7](https://github.com/zhayujie/CowAgent/commit/051ffd78a372f71a967fd3259e37fe19131f83cf), [5264f7c](https://github.com/zhayujie/CowAgent/commit/5264f7ce18360ee4db5dcb4ebe67307977d40014))
|
||||
|
||||
@@ -3,7 +3,7 @@ title: v2.0.2
|
||||
description: CowAgent 2.0.2 - Web Console upgrade, multi-channel concurrency, session persistence
|
||||
---
|
||||
|
||||
**Release Date**: 2026.02.27 | [Full Changelog](https://github.com/zhayujie/chatgpt-on-wechat/compare/2.0.1...master)
|
||||
**Release Date**: 2026.02.27 | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.1...master)
|
||||
|
||||
## Highlights
|
||||
|
||||
@@ -53,7 +53,7 @@ View Agent runtime logs in real-time for monitoring and troubleshooting:
|
||||
|
||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173514.png" />
|
||||
|
||||
Related commits: [f1a1413](https://github.com/zhayujie/chatgpt-on-wechat/commit/f1a1413), [c0702c8](https://github.com/zhayujie/chatgpt-on-wechat/commit/c0702c8), [394853c](https://github.com/zhayujie/chatgpt-on-wechat/commit/394853c), [1c71c4e](https://github.com/zhayujie/chatgpt-on-wechat/commit/1c71c4e), [5e3eccb](https://github.com/zhayujie/chatgpt-on-wechat/commit/5e3eccb), [e1dc037](https://github.com/zhayujie/chatgpt-on-wechat/commit/e1dc037), [5edbf4c](https://github.com/zhayujie/chatgpt-on-wechat/commit/5edbf4c), [7d258b5](https://github.com/zhayujie/chatgpt-on-wechat/commit/7d258b5)
|
||||
Related commits: [f1a1413](https://github.com/zhayujie/CowAgent/commit/f1a1413), [c0702c8](https://github.com/zhayujie/CowAgent/commit/c0702c8), [394853c](https://github.com/zhayujie/CowAgent/commit/394853c), [1c71c4e](https://github.com/zhayujie/CowAgent/commit/1c71c4e), [5e3eccb](https://github.com/zhayujie/CowAgent/commit/5e3eccb), [e1dc037](https://github.com/zhayujie/CowAgent/commit/e1dc037), [5edbf4c](https://github.com/zhayujie/CowAgent/commit/5edbf4c), [7d258b5](https://github.com/zhayujie/CowAgent/commit/7d258b5)
|
||||
|
||||
### 🔀 Multi-Channel Concurrency
|
||||
|
||||
@@ -67,24 +67,24 @@ Configuration: Set multiple channels in `config.json` via `channel_type` separat
|
||||
}
|
||||
```
|
||||
|
||||
Related commits: [4694594](https://github.com/zhayujie/chatgpt-on-wechat/commit/4694594), [7cce224](https://github.com/zhayujie/chatgpt-on-wechat/commit/7cce224), [7d258b5](https://github.com/zhayujie/chatgpt-on-wechat/commit/7d258b5), [c9adddb](https://github.com/zhayujie/chatgpt-on-wechat/commit/c9adddb)
|
||||
Related commits: [4694594](https://github.com/zhayujie/CowAgent/commit/4694594), [7cce224](https://github.com/zhayujie/CowAgent/commit/7cce224), [7d258b5](https://github.com/zhayujie/CowAgent/commit/7d258b5), [c9adddb](https://github.com/zhayujie/CowAgent/commit/c9adddb)
|
||||
|
||||
### 💾 Session Persistence
|
||||
|
||||
Session history is now persisted to a local SQLite database. Conversation context is automatically restored after service restarts. Historical conversations in the Web Console are also restored.
|
||||
|
||||
Related commits: [29bfbec](https://github.com/zhayujie/chatgpt-on-wechat/commit/29bfbec), [9917552](https://github.com/zhayujie/chatgpt-on-wechat/commit/9917552), [925d728](https://github.com/zhayujie/chatgpt-on-wechat/commit/925d728)
|
||||
Related commits: [29bfbec](https://github.com/zhayujie/CowAgent/commit/29bfbec), [9917552](https://github.com/zhayujie/CowAgent/commit/9917552), [925d728](https://github.com/zhayujie/CowAgent/commit/925d728)
|
||||
|
||||
## New Models
|
||||
|
||||
- **Gemini 3.1 Pro Preview**: Added `gemini-3.1-pro-preview` model support ([52d7cad](https://github.com/zhayujie/chatgpt-on-wechat/commit/52d7cad))
|
||||
- **Claude 4.6 Sonnet**: Added `claude-4.6-sonnet` model support ([52d7cad](https://github.com/zhayujie/chatgpt-on-wechat/commit/52d7cad))
|
||||
- **Qwen3.5 Plus**: Added `qwen3.5-plus` model support ([e59a289](https://github.com/zhayujie/chatgpt-on-wechat/commit/e59a289))
|
||||
- **MiniMax M2.5**: Added `Minimax-M2.5` model support ([48db538](https://github.com/zhayujie/chatgpt-on-wechat/commit/48db538))
|
||||
- **GLM-5**: Added `glm-5` model support ([48db538](https://github.com/zhayujie/chatgpt-on-wechat/commit/48db538))
|
||||
- **Kimi K2.5**: Added `kimi-k2.5` model support ([48db538](https://github.com/zhayujie/chatgpt-on-wechat/commit/48db538))
|
||||
- **Doubao 2.0 Code**: Added `doubao-2.0-code` coding-specialized model ([ab28ee5](https://github.com/zhayujie/chatgpt-on-wechat/commit/ab28ee5))
|
||||
- **DashScope Models**: Added Alibaba Cloud DashScope model name support ([ce58f23](https://github.com/zhayujie/chatgpt-on-wechat/commit/ce58f23))
|
||||
- **Gemini 3.1 Pro Preview**: Added `gemini-3.1-pro-preview` model support ([52d7cad](https://github.com/zhayujie/CowAgent/commit/52d7cad))
|
||||
- **Claude 4.6 Sonnet**: Added `claude-4.6-sonnet` model support ([52d7cad](https://github.com/zhayujie/CowAgent/commit/52d7cad))
|
||||
- **Qwen3.5 Plus**: Added `qwen3.5-plus` model support ([e59a289](https://github.com/zhayujie/CowAgent/commit/e59a289))
|
||||
- **MiniMax M2.5**: Added `Minimax-M2.5` model support ([48db538](https://github.com/zhayujie/CowAgent/commit/48db538))
|
||||
- **GLM-5**: Added `glm-5` model support ([48db538](https://github.com/zhayujie/CowAgent/commit/48db538))
|
||||
- **Kimi K2.5**: Added `kimi-k2.5` model support ([48db538](https://github.com/zhayujie/CowAgent/commit/48db538))
|
||||
- **Doubao 2.0 Code**: Added `doubao-2.0-code` coding-specialized model ([ab28ee5](https://github.com/zhayujie/CowAgent/commit/ab28ee5))
|
||||
- **DashScope Models**: Added Alibaba Cloud DashScope model name support ([ce58f23](https://github.com/zhayujie/CowAgent/commit/ce58f23))
|
||||
|
||||
## Website & Documentation
|
||||
|
||||
@@ -93,6 +93,6 @@ Related commits: [29bfbec](https://github.com/zhayujie/chatgpt-on-wechat/commit/
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **Gemini DingTalk image recognition**: Fixed Gemini unable to process image markers in DingTalk channel ([05a3304](https://github.com/zhayujie/chatgpt-on-wechat/commit/05a3304)) ([#2670](https://github.com/zhayujie/chatgpt-on-wechat/pull/2670)) Thanks [@SgtPepper114](https://github.com/SgtPepper114)
|
||||
- **Startup script dependencies**: Fixed dependency installation issue in `run.sh` script ([b6fc9fa](https://github.com/zhayujie/chatgpt-on-wechat/commit/b6fc9fa))
|
||||
- **Bare except cleanup**: Replaced `bare except` with `except Exception` for better exception handling ([adca89b](https://github.com/zhayujie/chatgpt-on-wechat/commit/adca89b)) ([#2674](https://github.com/zhayujie/chatgpt-on-wechat/pull/2674)) Thanks [@haosenwang1018](https://github.com/haosenwang1018)
|
||||
- **Gemini DingTalk image recognition**: Fixed Gemini unable to process image markers in DingTalk channel ([05a3304](https://github.com/zhayujie/CowAgent/commit/05a3304)) ([#2670](https://github.com/zhayujie/CowAgent/pull/2670)) Thanks [@SgtPepper114](https://github.com/SgtPepper114)
|
||||
- **Startup script dependencies**: Fixed dependency installation issue in `run.sh` script ([b6fc9fa](https://github.com/zhayujie/CowAgent/commit/b6fc9fa))
|
||||
- **Bare except cleanup**: Replaced `bare except` with `except Exception` for better exception handling ([adca89b](https://github.com/zhayujie/CowAgent/commit/adca89b)) ([#2674](https://github.com/zhayujie/CowAgent/pull/2674)) Thanks [@haosenwang1018](https://github.com/haosenwang1018)
|
||||
|
||||
@@ -16,40 +16,40 @@ Added personal WeChat (`weixin`) channel — the most important update in this r
|
||||
|
||||
Documentation: [WeChat Channel](https://docs.cowagent.ai/channels/weixin).
|
||||
|
||||
Related commits: [ce89869](https://github.com/zhayujie/chatgpt-on-wechat/commit/ce89869), [a483ec0](https://github.com/zhayujie/chatgpt-on-wechat/commit/a483ec0), [c1421e0](https://github.com/zhayujie/chatgpt-on-wechat/commit/c1421e0)
|
||||
Related commits: [ce89869](https://github.com/zhayujie/CowAgent/commit/ce89869), [a483ec0](https://github.com/zhayujie/CowAgent/commit/a483ec0), [c1421e0](https://github.com/zhayujie/CowAgent/commit/c1421e0)
|
||||
|
||||
## 🤖 New Models
|
||||
|
||||
- **MiniMax-M2.7**: Added MiniMax-M2.7 model support
|
||||
- **GLM-5-Turbo**: Added Zhipu glm-5-turbo model support
|
||||
|
||||
Related commits: [9192f6f](https://github.com/zhayujie/chatgpt-on-wechat/commit/9192f6f)
|
||||
Related commits: [9192f6f](https://github.com/zhayujie/CowAgent/commit/9192f6f)
|
||||
|
||||
## 🔧 Script Refactoring
|
||||
|
||||
- **run.sh Refactoring**: Extracted shared logic and eliminated duplication, reducing from 600+ lines to 177 lines ([49d8707](https://github.com/zhayujie/chatgpt-on-wechat/commit/49d8707))
|
||||
- **Executable Permission**: Fixed `run.sh` file permission issue ([652156e](https://github.com/zhayujie/chatgpt-on-wechat/commit/652156e))
|
||||
- **run.sh Refactoring**: Extracted shared logic and eliminated duplication, reducing from 600+ lines to 177 lines ([49d8707](https://github.com/zhayujie/CowAgent/commit/49d8707))
|
||||
- **Executable Permission**: Fixed `run.sh` file permission issue ([652156e](https://github.com/zhayujie/CowAgent/commit/652156e))
|
||||
|
||||
## ⚡ Improvements
|
||||
|
||||
- **Unified Request Headers**: Added identification headers to external requests across Agent services (Chat, Embedding, Vision, WebSearch, etc.) ([b4e711f](https://github.com/zhayujie/chatgpt-on-wechat/commit/b4e711f))
|
||||
- **Auto-Repair Messages**: Enhanced message protocol fault tolerance with automatic repair of malformed message sequences ([b8b57e3](https://github.com/zhayujie/chatgpt-on-wechat/commit/b8b57e3))
|
||||
- **Unified Request Headers**: Added identification headers to external requests across Agent services (Chat, Embedding, Vision, WebSearch, etc.) ([b4e711f](https://github.com/zhayujie/CowAgent/commit/b4e711f))
|
||||
- **Auto-Repair Messages**: Enhanced message protocol fault tolerance with automatic repair of malformed message sequences ([b8b57e3](https://github.com/zhayujie/CowAgent/commit/b8b57e3))
|
||||
|
||||
## 🌍 Japanese Documentation
|
||||
|
||||
Added complete Japanese documentation covering getting started guide, channel integration, model configuration and other major sections. Thanks [@Ikko Ashimine](https://github.com/ikoamu)
|
||||
|
||||
Related commits: [5487c0b](https://github.com/zhayujie/chatgpt-on-wechat/commit/5487c0b)
|
||||
Related commits: [5487c0b](https://github.com/zhayujie/CowAgent/commit/5487c0b)
|
||||
|
||||
## 🐛 Bug Fixes
|
||||
|
||||
- **WeCom Bot Compatibility**: Fixed compatibility with older `websocket-client` versions, added unified WebSocket compatibility layer ([bc7f627](https://github.com/zhayujie/chatgpt-on-wechat/commit/bc7f627))
|
||||
- **run.sh PID**: Fixed process PID retrieval error in `run.sh` ([9febb07](https://github.com/zhayujie/chatgpt-on-wechat/commit/9febb07))
|
||||
- **Feishu Encoding**: Fixed message and log encoding issue in Feishu channel ([7d0e156](https://github.com/zhayujie/chatgpt-on-wechat/commit/7d0e156))
|
||||
- **Feishu Config**: Removed redundant `feishu_bot_name` dependency in `run.sh` ([1b5be1b](https://github.com/zhayujie/chatgpt-on-wechat/commit/1b5be1b))
|
||||
- **WeCom Bot Compatibility**: Fixed compatibility with older `websocket-client` versions, added unified WebSocket compatibility layer ([bc7f627](https://github.com/zhayujie/CowAgent/commit/bc7f627))
|
||||
- **run.sh PID**: Fixed process PID retrieval error in `run.sh` ([9febb07](https://github.com/zhayujie/CowAgent/commit/9febb07))
|
||||
- **Feishu Encoding**: Fixed message and log encoding issue in Feishu channel ([7d0e156](https://github.com/zhayujie/CowAgent/commit/7d0e156))
|
||||
- **Feishu Config**: Removed redundant `feishu_bot_name` dependency in `run.sh` ([1b5be1b](https://github.com/zhayujie/CowAgent/commit/1b5be1b))
|
||||
|
||||
## 📦 Upgrade
|
||||
|
||||
Run `./run.sh update` for a one-click upgrade, or manually pull the latest code and restart. See [Upgrade Guide](https://docs.cowagent.ai/guide/upgrade) for details.
|
||||
|
||||
**Release Date**: 2026.03.22 | [Full Changelog](https://github.com/zhayujie/chatgpt-on-wechat/compare/2.0.3...master)
|
||||
**Release Date**: 2026.03.22 | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.3...master)
|
||||
|
||||
@@ -57,21 +57,21 @@ WeCom Bot channel now supports QR code scan for one-click bot creation:
|
||||
|
||||
Docs: [WeCom Bot](https://docs.cowagent.ai/en/channels/wecom-bot)
|
||||
|
||||
PR: [#2735](https://github.com/zhayujie/chatgpt-on-wechat/pull/2735). Thanks [@WecomTeam](https://github.com/WecomTeam)
|
||||
PR: [#2735](https://github.com/zhayujie/CowAgent/pull/2735). Thanks [@WecomTeam](https://github.com/WecomTeam)
|
||||
|
||||
## 🐛 Other Improvements & Fixes
|
||||
|
||||
- **DeepSeek module**: Independent DeepSeek Bot with dedicated `deepseek_api_key` config ([#2719](https://github.com/zhayujie/chatgpt-on-wechat/pull/2719)). Thanks [@6vision](https://github.com/6vision)
|
||||
- **Web console**: Slash command menu, input history, new model options, mobile optimization ([#2731](https://github.com/zhayujie/chatgpt-on-wechat/pull/2731)). Thanks [@zkjqd](https://github.com/zkjqd)
|
||||
- **Context loss**: Fix context loss after trimming ([393f0c0](https://github.com/zhayujie/chatgpt-on-wechat/commit/393f0c0))
|
||||
- **System prompt**: Fix system prompt not rebuilding on every turn ([13f5fde](https://github.com/zhayujie/chatgpt-on-wechat/commit/13f5fde))
|
||||
- **Gemini**: Fix missing model attribute in GoogleGeminiBot ([#2716](https://github.com/zhayujie/chatgpt-on-wechat/pull/2716)). Thanks [@cowagent](https://github.com/cowagent)
|
||||
- **WeChat channel**: Fix file send failures and filename loss ([6d9b7ba](https://github.com/zhayujie/chatgpt-on-wechat/commit/6d9b7ba), [45faa9c](https://github.com/zhayujie/chatgpt-on-wechat/commit/45faa9c))
|
||||
- **Docker**: Fix volume permissions, reduce image size ([3eb8348](https://github.com/zhayujie/chatgpt-on-wechat/commit/3eb8348), [4470d4c](https://github.com/zhayujie/chatgpt-on-wechat/commit/4470d4c))
|
||||
- **DeepSeek module**: Independent DeepSeek Bot with dedicated `deepseek_api_key` config ([#2719](https://github.com/zhayujie/CowAgent/pull/2719)). Thanks [@6vision](https://github.com/6vision)
|
||||
- **Web console**: Slash command menu, input history, new model options, mobile optimization ([#2731](https://github.com/zhayujie/CowAgent/pull/2731)). Thanks [@zkjqd](https://github.com/zkjqd)
|
||||
- **Context loss**: Fix context loss after trimming ([393f0c0](https://github.com/zhayujie/CowAgent/commit/393f0c0))
|
||||
- **System prompt**: Fix system prompt not rebuilding on every turn ([13f5fde](https://github.com/zhayujie/CowAgent/commit/13f5fde))
|
||||
- **Gemini**: Fix missing model attribute in GoogleGeminiBot ([#2716](https://github.com/zhayujie/CowAgent/pull/2716)). Thanks [@cowagent](https://github.com/cowagent)
|
||||
- **WeChat channel**: Fix file send failures and filename loss ([6d9b7ba](https://github.com/zhayujie/CowAgent/commit/6d9b7ba), [45faa9c](https://github.com/zhayujie/CowAgent/commit/45faa9c))
|
||||
- **Docker**: Fix volume permissions, reduce image size ([3eb8348](https://github.com/zhayujie/CowAgent/commit/3eb8348), [4470d4c](https://github.com/zhayujie/CowAgent/commit/4470d4c))
|
||||
- **Security**: Fix Memory Content path traversal risk. Thanks [@August829](https://github.com/August829)
|
||||
|
||||
## 📦 Upgrade
|
||||
|
||||
Run `cow update` or `./run.sh update` to upgrade, or pull the latest code and restart. See [Upgrade Guide](https://docs.cowagent.ai/en/guide/upgrade).
|
||||
|
||||
**Release Date**: 2026.04.01 | [Full Changelog](https://github.com/zhayujie/chatgpt-on-wechat/compare/2.0.4...master)
|
||||
**Release Date**: 2026.04.01 | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.4...master)
|
||||
|
||||
@@ -54,5 +54,5 @@ Detailed instructions...
|
||||
| `metadata.always` | Always load (default false) |
|
||||
|
||||
<Tip>
|
||||
See the [Skill Creator documentation](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/skills/skill-creator/SKILL.md) for details.
|
||||
See the [Skill Creator documentation](https://github.com/zhayujie/CowAgent/blob/master/skills/skill-creator/SKILL.md) for details.
|
||||
</Tip>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
---
|
||||
title: memory - Memory
|
||||
description: Search and read long-term memory
|
||||
title: memory - Memory & Knowledge
|
||||
description: Search and read long-term memory and knowledge base files
|
||||
---
|
||||
|
||||
The memory tool contains two sub-tools: `memory_search` (search memory) and `memory_get` (read memory files).
|
||||
The memory tool contains two sub-tools: `memory_search` (search memory) and `memory_get` (read memory or knowledge files).
|
||||
|
||||
When the [knowledge base](/en/knowledge) feature is enabled, both tools also support accessing files under the `knowledge/` directory.
|
||||
|
||||
## Dependencies
|
||||
|
||||
@@ -11,7 +13,7 @@ No extra dependencies, available by default. Managed by the Agent Core memory sy
|
||||
|
||||
## memory_search
|
||||
|
||||
Search historical memory with hybrid keyword and vector retrieval.
|
||||
Search historical memory and knowledge base content with hybrid keyword and vector retrieval.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -19,11 +21,11 @@ Search historical memory with hybrid keyword and vector retrieval.
|
||||
|
||||
## memory_get
|
||||
|
||||
Read the content of a specific memory file.
|
||||
Read the content of a specific memory or knowledge file.
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `path` | string | Yes | Relative path to memory file (e.g. `MEMORY.md`, `memory/2026-01-01.md`) |
|
||||
| `path` | string | Yes | Relative path to the file (e.g. `MEMORY.md`, `memory/2026-01-01.md`, `knowledge/concepts/rag.md`) |
|
||||
| `start_line` | integer | No | Start line number |
|
||||
| `end_line` | integer | No | End line number |
|
||||
|
||||
@@ -34,3 +36,8 @@ The Agent automatically invokes memory tools in these scenarios:
|
||||
- When the user shares important information → stores to memory
|
||||
- When historical context is needed → searches relevant memory
|
||||
- When conversation reaches a certain length → extracts summary for storage
|
||||
- When discussing domain knowledge → retrieves relevant pages from the knowledge base
|
||||
|
||||
<Note>
|
||||
When `knowledge` is set to `false` in config, the tool descriptions and search scope automatically adjust to include only memory files.
|
||||
</Note>
|
||||
|
||||
@@ -8,12 +8,12 @@ description: 手动部署 CowAgent(源码 / Docker)
|
||||
### 1. 克隆项目代码
|
||||
|
||||
```bash
|
||||
git clone https://github.com/zhayujie/chatgpt-on-wechat
|
||||
cd chatgpt-on-wechat/
|
||||
git clone https://github.com/zhayujie/CowAgent
|
||||
cd CowAgent/
|
||||
```
|
||||
|
||||
<Tip>
|
||||
若遇到网络问题可使用国内仓库地址:https://gitee.com/zhayujie/chatgpt-on-wechat
|
||||
若遇到网络问题可使用国内仓库地址:https://gitee.com/zhayujie/CowAgent
|
||||
</Tip>
|
||||
|
||||
### 2. 安装依赖
|
||||
@@ -173,5 +173,5 @@ sudo docker logs -f chatgpt-on-wechat
|
||||
| `agent_max_steps` | `AGENT_MAX_STEPS` | 单次任务最大决策步数 | `15` |
|
||||
|
||||
<Tip>
|
||||
全部配置项可在项目 [`config.py`](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/config.py) 文件中查看。Docker 部署时,配置项名称需转为大写环境变量格式。
|
||||
全部配置项可在项目 [`config.py`](https://github.com/zhayujie/CowAgent/blob/master/config.py) 文件中查看。Docker 部署时,配置项名称需转为大写环境变量格式。
|
||||
</Tip>
|
||||
|
||||
@@ -26,7 +26,7 @@ description: 使用脚本一键安装和管理 CowAgent
|
||||
|
||||
1. 检查 Python 环境(需要 Python 3.7+)
|
||||
2. 安装必要工具(git、curl 等)
|
||||
3. 克隆项目代码到 `~/chatgpt-on-wechat`
|
||||
3. 克隆项目代码到 `~/CowAgent`
|
||||
4. 安装 Python 依赖和 Cow CLI
|
||||
5. 引导配置 AI 模型和通信渠道
|
||||
6. 启动服务
|
||||
|
||||
@@ -11,25 +11,27 @@ CowAgent 的整体架构由以下核心模块组成:
|
||||
|
||||
<img src="https://cdn.link-ai.tech/doc/68ef7b212c6f791e0e74314b912149f9-sz_5847990.png" alt="CowAgent Architecture" />
|
||||
|
||||
### 核心模块说明
|
||||
|
||||
| 模块 | 说明 |
|
||||
| --- | --- |
|
||||
| **Channels** | 消息通道层,负责接收和发送消息,支持 Web、飞书、钉钉、企微、公众号等 |
|
||||
| **Agent Core** | 智能体核心引擎,包括任务规划、记忆系统和技能引擎 |
|
||||
| **Tools** | 工具层,Agent 通过工具访问操作系统资源,内置 10+ 种工具 |
|
||||
| **Models** | 模型层,支持国内外主流大语言模型的统一接入 |
|
||||
| **Plan** | 理解用户意图,将复杂任务分解为多步骤计划,循环调用工具直到完成目标 |
|
||||
| **Memory** | 自动将重要信息持久化为核心记忆和日级记忆,支持关键词和向量混合检索,跨会话保持上下文连续性 |
|
||||
| **Knowledge** | 以主题维度组织结构化知识,Agent 自主整理有价值信息为 Markdown 页面,维护索引和交叉引用,构建持续增长的知识网络 |
|
||||
| **Tools** | Agent 访问操作系统资源的核心能力,内置文件读写、终端执行、浏览器操作、定时调度、记忆检索、联网搜索等 10+ 种工具 |
|
||||
| **Skills** | 加载和管理 Skills,支持从 Skill Hub、GitHub 等一键安装,或通过对话创建自定义技能 |
|
||||
| **Models** | 模型层,统一接入 OpenAI、Claude、Gemini、DeepSeek、MiniMax、GLM、Qwen 等国内外主流大语言模型 |
|
||||
| **Channels** | 消息通道层,负责接收和发送消息,支持 Web 控制台、微信、飞书、钉钉、企微、公众号等,统一消息协议 |
|
||||
| **CLI** | 命令行系统,提供终端命令(`cow`)和对话命令(`/`),支持进程管理、技能安装、配置修改、知识库管理等操作 |
|
||||
|
||||
## Agent 模式
|
||||
|
||||
启用 Agent 模式后,CowAgent 会以自主智能体的方式运行,核心工作流如下:
|
||||
|
||||
1. **接收消息** - 通过通道接收用户输入
|
||||
2. **理解意图** - 分析任务需求和上下文
|
||||
3. **规划任务** - 将复杂任务分解为多个步骤
|
||||
4. **调用工具** - 选择合适的工具执行每个步骤
|
||||
5. **记忆更新** - 将重要信息存入长期记忆
|
||||
6. **返回结果** - 将执行结果发送回用户
|
||||
1. **接收消息** — 通过通道接收用户输入
|
||||
2. **理解意图** — 分析任务需求和上下文
|
||||
3. **规划任务** — 将复杂任务分解为多个步骤
|
||||
4. **调用工具** — 选择合适的工具执行每个步骤
|
||||
5. **记忆与知识更新** — 将重要信息存入长期记忆,将结构化知识整理至知识库
|
||||
6. **返回结果** — 将执行结果发送回用户
|
||||
|
||||
## 工作空间
|
||||
|
||||
@@ -37,11 +39,14 @@ Agent 的工作空间默认位于 `~/cow` 目录,用于存储系统提示词
|
||||
|
||||
```
|
||||
~/cow/
|
||||
├── system.md # Agent system prompt
|
||||
├── user.md # User profile
|
||||
├── SYSTEM.md # Agent system prompt
|
||||
├── USER.md # User profile
|
||||
├── MEMORY.md # Core memory
|
||||
├── memory/ # Long-term memory storage
|
||||
│ ├── core.md # Core memory
|
||||
│ └── daily/ # Daily memory
|
||||
│ └── YYYY-MM-DD.md # Daily memory
|
||||
├── knowledge/ # Personal knowledge base
|
||||
│ ├── index.md # Knowledge index
|
||||
│ └── <category>/ # Topic-based pages
|
||||
└── skills/ # Custom skills
|
||||
├── skill-1/
|
||||
└── skill-2/
|
||||
@@ -72,6 +77,7 @@ Agent 的工作空间默认位于 `~/cow` 目录,用于存储系统提示词
|
||||
| --- | --- | --- |
|
||||
| `agent` | 是否启用 Agent 模式 | `true` |
|
||||
| `agent_workspace` | 工作空间路径 | `~/cow` |
|
||||
| `agent_max_context_tokens` | 最大上下文 token 数 | `40000` |
|
||||
| `agent_max_context_turns` | 最大上下文记忆轮次 | `30` |
|
||||
| `agent_max_steps` | 单次任务最大决策步数 | `15` |
|
||||
| `agent_max_context_tokens` | 最大上下文 token 数 | `50000` |
|
||||
| `agent_max_context_turns` | 最大上下文记忆轮次 | `20` |
|
||||
| `agent_max_steps` | 单次任务最大决策步数 | `20` |
|
||||
| `knowledge` | 是否启用个人知识库 | `true` |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: 功能介绍
|
||||
description: CowAgent 长期记忆、任务规划、技能系统、CLI 命令、浏览器工具详细说明
|
||||
description: CowAgent 长期记忆、个人知识库、任务规划、技能系统、CLI 命令、浏览器工具详细说明
|
||||
---
|
||||
|
||||
## 1. 长期记忆
|
||||
@@ -15,13 +15,26 @@ description: CowAgent 长期记忆、任务规划、技能系统、CLI 命令、
|
||||
<img src="https://cdn.link-ai.tech/doc/20260203000455.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
## 2. 任务规划和工具调用
|
||||
## 2. 个人知识库
|
||||
|
||||
> 知识库系统让 Agent 能够持续积累和组织结构化知识。与按时间线记录的记忆不同,知识库以主题为维度,将文章、对话洞察、学习材料等整理为互相关联的 Markdown 页面,形成持续增长的知识网络。
|
||||
|
||||
Agent 会在对话中自动将有价值的信息整理为知识页面,维护交叉引用和索引,通过 Web 控制台可浏览文档和查看知识图谱。知识库存储在工作空间的 `~/cow/knowledge/` 目录下。
|
||||
|
||||
- **自动整理**:Agent 在对话中自主提取和整理结构化知识,维护索引和交叉引用
|
||||
- **知识图谱**:基于页面间的交叉引用自动构建知识图谱,Web 控制台提供可视化关系图浏览
|
||||
- **对话联动**:Agent 回复中引用的知识文档链接可在 Web 控制台中直接点击跳转查看
|
||||
- **CLI 管理**:通过 `/knowledge` 命令查看统计、浏览目录,通过 `/knowledge on|off` 开关功能
|
||||
|
||||
详细说明请参考 [个人知识库](/knowledge)。
|
||||
|
||||
## 3. 任务规划和工具调用
|
||||
|
||||
工具是 Agent 访问操作系统资源的核心,Agent 会根据任务需求智能选择和调用工具,完成文件读写、命令执行、定时任务等各类操作。内置工具的实现在项目的 `agent/tools/` 目录下。
|
||||
|
||||
**主要工具:** 文件读写编辑、Bash 终端、浏览器操作、文件发送、定时调度、记忆搜索、联网搜索、环境配置等。
|
||||
|
||||
### 2.1 终端和文件访问
|
||||
### 3.1 终端和文件访问
|
||||
|
||||
针对操作系统的终端和文件的访问能力,是最基础和核心的工具,其他很多工具或技能都是基于此进行扩展。用户可通过手机端与 Agent 交互,操作个人电脑或服务器上的资源:
|
||||
|
||||
@@ -29,7 +42,7 @@ description: CowAgent 长期记忆、任务规划、技能系统、CLI 命令、
|
||||
<img src="https://cdn.link-ai.tech/doc/20260202181130.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 2.2 编程能力
|
||||
### 3.2 编程能力
|
||||
|
||||
基于编程能力和系统访问能力,Agent 可以实现从信息搜索、图片等素材生成、编码、测试、部署、Nginx 配置修改、发布的 **Vibecoding 全流程**,通过手机端简单的一句命令完成应用的快速 demo:
|
||||
|
||||
@@ -37,7 +50,7 @@ description: CowAgent 长期记忆、任务规划、技能系统、CLI 命令、
|
||||
<img src="https://cdn.link-ai.tech/doc/20260203121008.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 2.3 定时任务
|
||||
### 3.3 定时任务
|
||||
|
||||
基于 `scheduler` 工具实现动态定时任务,支持**一次性任务、固定时间间隔、Cron 表达式**三种形式,任务触发可选择**固定消息发送**或 **Agent 动态任务**执行两种模式:
|
||||
|
||||
@@ -45,7 +58,7 @@ description: CowAgent 长期记忆、任务规划、技能系统、CLI 命令、
|
||||
<img src="https://cdn.link-ai.tech/doc/20260202195402.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 2.4 浏览器操作
|
||||
### 3.4 浏览器操作
|
||||
|
||||
内置 `browser` 工具,Agent 可控制浏览器访问网页、填写表单、点击元素、截图,支持动态 JS 渲染页面。运行 `cow install-browser` 一键安装,自动适配服务器(无头模式)和桌面环境:
|
||||
|
||||
@@ -53,7 +66,7 @@ description: CowAgent 长期记忆、任务规划、技能系统、CLI 命令、
|
||||
<img src="https://cdn.link-ai.tech/doc/20260401115728.png" width="750" />
|
||||
</Frame>
|
||||
|
||||
### 2.5 环境变量管理
|
||||
### 3.5 环境变量管理
|
||||
|
||||
技能所需的秘钥存储在环境变量文件中,由 `env_config` 工具进行管理,你可以通过对话的方式更新秘钥,工具内置安全保护和脱敏策略:
|
||||
|
||||
@@ -61,7 +74,7 @@ description: CowAgent 长期记忆、任务规划、技能系统、CLI 命令、
|
||||
<img src="https://cdn.link-ai.tech/doc/20260202234939.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
## 3. 技能系统
|
||||
## 4. 技能系统
|
||||
|
||||
技能系统为 Agent 提供无限的扩展性,每个 Skill 由说明文件、运行脚本(可选)、资源(可选)组成,描述如何完成特定类型的任务。通过 Skill 可以让 Agent 遵循说明完成复杂流程、调用各类工具或对接第三方系统。
|
||||
|
||||
@@ -71,7 +84,7 @@ description: CowAgent 长期记忆、任务规划、技能系统、CLI 命令、
|
||||
|
||||
安装技能:`/skill install <名称>` 或 `cow skill install <名称>`,支持从 Skill Hub、GitHub、ClawHub、URL 等来源安装。
|
||||
|
||||
### 3.1 创建技能
|
||||
### 4.1 创建技能
|
||||
|
||||
通过 `skill-creator` 技能可以通过对话的方式快速创建技能。你可以让 Agent 将某个工作流程固化为技能,或者把任意接口文档和示例发送给 Agent,让他直接完成对接:
|
||||
|
||||
@@ -79,7 +92,7 @@ description: CowAgent 长期记忆、任务规划、技能系统、CLI 命令、
|
||||
<img src="https://cdn.link-ai.tech/doc/20260202202247.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 3.2 搜索和图像识别
|
||||
### 4.2 搜索和图像识别
|
||||
|
||||
- **联网搜索:** 内置 `web_search` 工具,支持多种搜索引擎,配置 `BOCHA_API_KEY` 或 `LINKAI_API_KEY` 后启用。
|
||||
- **图像识别:** 内置 `openai-image-vision` 技能,可使用 `gpt-4.1-mini`、`gpt-4.1` 等模型,依赖 `OPENAI_API_KEY`。
|
||||
@@ -88,7 +101,7 @@ description: CowAgent 长期记忆、任务规划、技能系统、CLI 命令、
|
||||
<img src="https://cdn.link-ai.tech/doc/20260202213219.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 3.3 技能广场
|
||||
### 4.3 技能广场
|
||||
|
||||
访问 [skills.cowagent.ai](https://skills.cowagent.ai/) 浏览所有可用技能,或在对话中执行:
|
||||
|
||||
@@ -103,7 +116,7 @@ description: CowAgent 长期记忆、任务规划、技能系统、CLI 命令、
|
||||
<img src="https://cdn.link-ai.tech/doc/20260401110103.png" width="750" />
|
||||
|
||||
|
||||
## 4. CLI 命令系统
|
||||
## 5. CLI 命令系统
|
||||
|
||||
CowAgent 提供两种命令交互方式,覆盖服务管理、技能安装、配置调整等日常运维操作:
|
||||
|
||||
|
||||
@@ -5,12 +5,12 @@ description: CowAgent - 基于大模型的超级AI助理
|
||||
|
||||
<img src="https://cdn.link-ai.tech/doc/78c5dd674e2c828642ecc0406669fed7.png" alt="CowAgent" width="450px"/>
|
||||
|
||||
**CowAgent** 是基于大模型的超级AI助理,能够主动思考和任务规划、操作计算机和外部资源、创造和执行Skills、拥有长期记忆并不断成长。
|
||||
**CowAgent** 是基于大模型的超级AI助理,能够主动思考和任务规划、操作计算机和外部资源、创造和执行Skills、拥有长期记忆和知识库并不断成长。
|
||||
|
||||
CowAgent 支持灵活切换多种模型,能处理文本、语音、图片、文件等多模态消息,可接入微信、飞书、钉钉、企业微信应用、微信公众号、网页中使用,7×24小时运行于你的个人电脑或服务器中。
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="GitHub" icon="github" href="https://github.com/zhayujie/chatgpt-on-wechat">
|
||||
<Card title="GitHub" icon="github" href="https://github.com/zhayujie/CowAgent">
|
||||
开源代码仓库,欢迎 Star 和贡献
|
||||
</Card>
|
||||
<Card title="免部署在线体验" icon="cloud" href="https://link-ai.tech/cowagent/create">
|
||||
@@ -27,12 +27,12 @@ CowAgent 支持灵活切换多种模型,能处理文本、语音、图片、
|
||||
<Card title="长期记忆" icon="database" href="/memory">
|
||||
自动将对话记忆持久化至本地文件和数据库中,包括全局记忆和天级记忆,支持关键词及向量检索。
|
||||
</Card>
|
||||
<Card title="个人知识库" icon="book" href="/knowledge">
|
||||
自动整理结构化知识,支持知识图谱可视化,通过交叉引用构建持续增长的知识网络。
|
||||
</Card>
|
||||
<Card title="技能系统" icon="puzzle-piece" href="/skills/index">
|
||||
实现了Skills创建和运行的引擎,内置多种技能,并支持通过自然语言对话完成自定义Skills开发。
|
||||
</Card>
|
||||
<Card title="多模态消息" icon="image" href="/channels/web">
|
||||
支持对文本、图片、语音、文件等多类型消息进行解析、处理、生成、发送等操作。
|
||||
</Card>
|
||||
<Card title="工具系统" icon="wrench" href="/tools/index">
|
||||
内置文件读写、终端执行、浏览器操作、定时任务、消息发送等工具,Agent 可自主调用工具完成复杂任务。
|
||||
</Card>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<p align="center"><img src="https://github.com/user-attachments/assets/eca9a9ec-8534-4615-9e0f-96c5ac1d10a3" alt="CowAgent" width="550" /></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/zhayujie/chatgpt-on-wechat/releases/latest"><img src="https://img.shields.io/github/v/release/zhayujie/chatgpt-on-wechat" alt="Latest release"></a>
|
||||
<a href="https://github.com/zhayujie/chatgpt-on-wechat/blob/master/LICENSE"><img src="https://img.shields.io/github/license/zhayujie/chatgpt-on-wechat" alt="License: MIT"></a>
|
||||
<a href="https://github.com/zhayujie/chatgpt-on-wechat"><img src="https://img.shields.io/github/stars/zhayujie/chatgpt-on-wechat?style=flat-square" alt="Stars"></a> <br/>
|
||||
[<a href="https://github.com/zhayujie/chatgpt-on-wechat/blob/master/README.md">中文</a>] | [<a href="https://github.com/zhayujie/chatgpt-on-wechat/blob/master/docs/en/README.md">English</a>] | [日本語]
|
||||
<a href="https://github.com/zhayujie/CowAgent/releases/latest"><img src="https://img.shields.io/github/v/release/zhayujie/CowAgent" alt="Latest release"></a>
|
||||
<a href="https://github.com/zhayujie/CowAgent/blob/master/LICENSE"><img src="https://img.shields.io/github/license/zhayujie/CowAgent" alt="License: MIT"></a>
|
||||
<a href="https://github.com/zhayujie/CowAgent"><img src="https://img.shields.io/github/stars/zhayujie/CowAgent?style=flat-square" alt="Stars"></a> <br/>
|
||||
[<a href="https://github.com/zhayujie/CowAgent/blob/master/README.md">中文</a>] | [<a href="https://github.com/zhayujie/CowAgent/blob/master/docs/en/README.md">English</a>] | [日本語]
|
||||
</p>
|
||||
|
||||
**CowAgent** はLLMを搭載したAIスーパーアシスタントです。自律的なタスク計画、コンピュータや外部リソースの操作、Skillの作成・実行、長期記憶による継続的な成長が可能です。柔軟なモデル切り替えに対応し、テキスト・音声・画像・ファイルを処理でき、WeChat、Web、Feishu(飛書)、DingTalk(釘釘)、WeCom Bot(企業微信ボット)、WeComアプリ、WeChat公式アカウントに統合可能で、個人のPCやサーバー上で24時間365日稼働できます。
|
||||
**CowAgent** はLLMを搭載したAIスーパーアシスタントです。自律的なタスク計画、コンピュータや外部リソースの操作、Skillの作成・実行、長期記憶とパーソナルナレッジベースによる継続的な成長が可能です。柔軟なモデル切り替えに対応し、テキスト・音声・画像・ファイルを処理でき、WeChat、Web、Feishu(飛書)、DingTalk(釘釘)、WeCom Bot(企業微信ボット)、WeComアプリ、WeChat公式アカウントに統合可能で、個人のPCやサーバー上で24時間365日稼働できます。
|
||||
|
||||
<p align="center">
|
||||
<a href="https://cowagent.ai/">🌐 ウェブサイト</a> ·
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
- ✅ **自律的タスク計画**: 複雑なタスクを理解し、自律的に実行計画を立て、目標達成までツールを呼び出しながら継続的に思考します。
|
||||
- ✅ **長期記憶**: 会話の記憶をローカルファイルやデータベースに自動的に永続化します。コアメモリとデイリーメモリを含み、キーワード検索やベクトル検索に対応しています。
|
||||
- ✅ **パーソナルナレッジベース**: 構造化された知識を自動整理し、相互参照によるナレッジグラフを構築。Web での可視化ブラウジングと対話による管理をサポートします。
|
||||
- ✅ **Skillシステム**: Skillの作成・実行エンジンを実装。[Skill Hub](https://skills.cowagent.ai)、GitHubなどからSkillをインストールでき、会話を通じたカスタムSkill作成もサポートしています。
|
||||
- ✅ **ツールシステム**: ファイル読み書き、ターミナル実行、ブラウザ操作、スケジュールタスク、メッセージ送信などの組み込みツールを提供。Agentが自律的に呼び出して複雑なタスクを完了します。
|
||||
- ✅ **CLIシステム**: ターミナルコマンドとチャットコマンドを提供し、プロセス管理、Skillインストール、設定変更などの操作をサポートします。
|
||||
@@ -42,19 +43,19 @@
|
||||
|
||||
## 更新履歴
|
||||
|
||||
> **2026.04.01:** [v2.0.5](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.5) — Cow CLI、Skill Hubオープンソース化、ブラウザツール、WeCom Botスキャン作成など。
|
||||
> **2026.04.01:** [v2.0.5](https://github.com/zhayujie/CowAgent/releases/tag/2.0.5) — Cow CLI、Skill Hubオープンソース化、ブラウザツール、WeCom Botスキャン作成など。
|
||||
|
||||
> **2026.02.27:** [v2.0.2](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.2) — Webコンソールの全面刷新(ストリーミングチャット、モデル/Skill/メモリ/チャネル/スケジューラ/ログ管理)、マルチチャネル同時実行、セッション永続化、Gemini 3.1 Pro / Claude 4.6 Sonnet / Qwen3.5 Plusなど新モデル追加。
|
||||
> **2026.02.27:** [v2.0.2](https://github.com/zhayujie/CowAgent/releases/tag/2.0.2) — Webコンソールの全面刷新(ストリーミングチャット、モデル/Skill/メモリ/チャネル/スケジューラ/ログ管理)、マルチチャネル同時実行、セッション永続化、Gemini 3.1 Pro / Claude 4.6 Sonnet / Qwen3.5 Plusなど新モデル追加。
|
||||
|
||||
> **2026.02.13:** [v2.0.1](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.1) — 組み込みWeb検索ツール、スマートコンテキストトリミング、ランタイム情報の動的更新、Windows互換性、スケジューラのメモリ喪失やFeishu接続問題などの修正。
|
||||
> **2026.02.13:** [v2.0.1](https://github.com/zhayujie/CowAgent/releases/tag/2.0.1) — 組み込みWeb検索ツール、スマートコンテキストトリミング、ランタイム情報の動的更新、Windows互換性、スケジューラのメモリ喪失やFeishu接続問題などの修正。
|
||||
|
||||
> **2026.02.03:** [v2.0.0](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.0) — マルチステップタスク計画、長期記憶、組み込みツール、Skillフレームワーク、新モデル、チャネル最適化を備えたAIスーパーアシスタントへの全面アップグレード。
|
||||
> **2026.02.03:** [v2.0.0](https://github.com/zhayujie/CowAgent/releases/tag/2.0.0) — マルチステップタスク計画、長期記憶、組み込みツール、Skillフレームワーク、新モデル、チャネル最適化を備えたAIスーパーアシスタントへの全面アップグレード。
|
||||
|
||||
> **2025.05.23:** [v1.7.6](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/1.7.6) — Webチャネル最適化、AgentMeshマルチエージェントプラグイン、Baidu TTS、claude-4-sonnet/opus対応。
|
||||
> **2025.05.23:** [v1.7.6](https://github.com/zhayujie/CowAgent/releases/tag/1.7.6) — Webチャネル最適化、AgentMeshマルチエージェントプラグイン、Baidu TTS、claude-4-sonnet/opus対応。
|
||||
|
||||
> **2025.04.11:** [v1.7.5](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/1.7.5) — wechatferryプロトコル、DeepSeekモデル、Tencent Cloud音声、ModelScope・Gitee-AI対応。
|
||||
> **2025.04.11:** [v1.7.5](https://github.com/zhayujie/CowAgent/releases/tag/1.7.5) — wechatferryプロトコル、DeepSeekモデル、Tencent Cloud音声、ModelScope・Gitee-AI対応。
|
||||
|
||||
> **2024.12.13:** [v1.7.4](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/1.7.4) — Gemini 2.0モデル、Webチャネル、メモリリーク修正。
|
||||
> **2024.12.13:** [v1.7.4](https://github.com/zhayujie/CowAgent/releases/tag/1.7.4) — Gemini 2.0モデル、Webチャネル、メモリリーク修正。
|
||||
|
||||
全更新履歴: [リリースノート](https://docs.cowagent.ai/en/releases/overview)
|
||||
|
||||
@@ -83,8 +84,8 @@ irm https://cdn.link-ai.tech/code/cow/run.ps1 | iex
|
||||
**1. プロジェクトのクローン**
|
||||
|
||||
```bash
|
||||
git clone https://github.com/zhayujie/chatgpt-on-wechat
|
||||
cd chatgpt-on-wechat/
|
||||
git clone https://github.com/zhayujie/CowAgent
|
||||
cd CowAgent/
|
||||
```
|
||||
|
||||
**2. 依存関係のインストール**
|
||||
@@ -232,16 +233,16 @@ Coding Planは各プロバイダーが提供する月額サブスクリプショ
|
||||
|
||||
## 🔎 よくある質問
|
||||
|
||||
FAQ: <https://github.com/zhayujie/chatgpt-on-wechat/wiki/FAQs>
|
||||
FAQ: <https://github.com/zhayujie/CowAgent/wiki/FAQs>
|
||||
|
||||
## 🛠️ コントリビューション
|
||||
|
||||
新しいチャネルの追加を歓迎します。[Feishuチャネル](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/channel/feishu/feishu_channel.py)を参考にしてください。また、新しいSkillのコントリビューションも歓迎します。[Skill作成ドキュメント](https://docs.cowagent.ai/ja/skills/create)を参照するか、[Skill Hub](https://skills.cowagent.ai/submit)に提出してください。
|
||||
新しいチャネルの追加を歓迎します。[Feishuチャネル](https://github.com/zhayujie/CowAgent/blob/master/channel/feishu/feishu_channel.py)を参考にしてください。また、新しいSkillのコントリビューションも歓迎します。[Skill作成ドキュメント](https://docs.cowagent.ai/ja/skills/create)を参照するか、[Skill Hub](https://skills.cowagent.ai/submit)に提出してください。
|
||||
|
||||
## ✉ お問い合わせ
|
||||
|
||||
PRやIssueの提出を歓迎します。🌟 Starでプロジェクトをサポートしてください。ご質問がある場合は、[FAQリスト](https://github.com/zhayujie/chatgpt-on-wechat/wiki/FAQs)を確認するか、[Issues](https://github.com/zhayujie/chatgpt-on-wechat/issues)を検索してください。
|
||||
PRやIssueの提出を歓迎します。🌟 Starでプロジェクトをサポートしてください。ご質問がある場合は、[FAQリスト](https://github.com/zhayujie/CowAgent/wiki/FAQs)を確認するか、[Issues](https://github.com/zhayujie/CowAgent/issues)を検索してください。
|
||||
|
||||
## 🌟 コントリビューター
|
||||
|
||||

|
||||

|
||||
|
||||
@@ -92,6 +92,31 @@ description: ステータスの確認、設定管理、コンテキスト制御
|
||||
/logs 50
|
||||
```
|
||||
|
||||
## knowledge
|
||||
|
||||
パーソナルナレッジベースの表示と管理を行います。デフォルトでは統計情報を表示します。
|
||||
|
||||
```text
|
||||
/knowledge
|
||||
```
|
||||
|
||||
**ディレクトリ構造を表示:**
|
||||
|
||||
```text
|
||||
/knowledge list
|
||||
```
|
||||
|
||||
**ナレッジベースの有効化・無効化:**
|
||||
|
||||
```text
|
||||
/knowledge on
|
||||
/knowledge off
|
||||
```
|
||||
|
||||
<Note>
|
||||
ターミナル CLI では `cow knowledge` と `cow knowledge list` が利用可能ですが、`on|off` はチャットでのみサポートされます(実行時に即座に反映するため)。
|
||||
</Note>
|
||||
|
||||
## version
|
||||
|
||||
現在の CowAgent のバージョンを表示します。
|
||||
|
||||
@@ -40,6 +40,9 @@ Service:
|
||||
Skills:
|
||||
skill Manage skills (list / search / install / uninstall ...)
|
||||
|
||||
Knowledge:
|
||||
knowledge View knowledge base stats and structure
|
||||
|
||||
Others:
|
||||
help Show this help message
|
||||
version Show version
|
||||
@@ -55,6 +58,9 @@ Web コンソールや接続されたチャネルの会話で `/` を入力す
|
||||
| `/status` | サービスの状態と設定を表示 |
|
||||
| `/config` | 実行時設定の表示・変更 |
|
||||
| `/skill` | スキル管理(インストール、アンインストール、有効化、無効化など) |
|
||||
| `/knowledge` | ナレッジベースの統計情報を表示 |
|
||||
| `/knowledge list` | ナレッジベースのディレクトリ構造を表示 |
|
||||
| `/knowledge on\|off` | ナレッジベースの有効化・無効化 |
|
||||
| `/context` | 現在のセッションのコンテキスト情報を表示 |
|
||||
| `/context clear` | 現在のセッションのコンテキストをクリア |
|
||||
| `/logs` | 最近のログを表示 |
|
||||
@@ -74,6 +80,7 @@ Web コンソールや接続されたチャネルの会話で `/` を入力す
|
||||
| logs | ✓ | ✓ |
|
||||
| config | ✗ | ✓ |
|
||||
| context | — | ✓ |
|
||||
| knowledge(サブコマンド) | ✓ | ✓ |
|
||||
| skill(サブコマンド) | ✓ | ✓ |
|
||||
| start / stop / restart | ✓ | ✗ |
|
||||
| update | ✓ | ✗ |
|
||||
|
||||
@@ -8,12 +8,12 @@ description: CowAgentの手動デプロイ(ソースコード / Docker)
|
||||
### 1. プロジェクトをクローン
|
||||
|
||||
```bash
|
||||
git clone https://github.com/zhayujie/chatgpt-on-wechat
|
||||
cd chatgpt-on-wechat/
|
||||
git clone https://github.com/zhayujie/CowAgent
|
||||
cd CowAgent/
|
||||
```
|
||||
|
||||
<Tip>
|
||||
ネットワークに問題がある場合は、ミラーを使用してください: https://gitee.com/zhayujie/chatgpt-on-wechat
|
||||
ネットワークに問題がある場合は、ミラーを使用してください: https://gitee.com/zhayujie/CowAgent
|
||||
</Tip>
|
||||
|
||||
### 2. 依存パッケージをインストール
|
||||
@@ -141,5 +141,5 @@ sudo docker logs -f chatgpt-on-wechat
|
||||
| `agent_max_steps` | タスクごとの最大判断ステップ数 | `15` |
|
||||
|
||||
<Tip>
|
||||
すべての設定オプションはプロジェクトの [`config.py`](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/config.py) に記載されています。
|
||||
すべての設定オプションはプロジェクトの [`config.py`](https://github.com/zhayujie/CowAgent/blob/master/config.py) に記載されています。
|
||||
</Tip>
|
||||
|
||||
@@ -26,7 +26,7 @@ Linux、macOS、Windowsに対応しています。Python 3.7〜3.12が必要で
|
||||
|
||||
1. Python環境の確認(Python 3.7以上が必要)
|
||||
2. 必要なツールのインストール(git、curlなど)
|
||||
3. プロジェクトを `~/chatgpt-on-wechat` にクローン
|
||||
3. プロジェクトを `~/CowAgent` にクローン
|
||||
4. Pythonの依存パッケージと Cow CLI をインストール
|
||||
5. AIモデルとチャネルの対話式設定
|
||||
6. サービスの起動
|
||||
|
||||
@@ -11,14 +11,16 @@ CowAgent のアーキテクチャは以下のコアモジュールで構成さ
|
||||
|
||||
<img src="https://cdn.link-ai.tech/doc/68ef7b212c6f791e0e74314b912149f9-sz_5847990.png" alt="CowAgent Architecture" />
|
||||
|
||||
### コアモジュール
|
||||
|
||||
| モジュール | 説明 |
|
||||
| --- | --- |
|
||||
| **Channels** | メッセージの受信と送信を行うメッセージチャネル層。Web、Feishu(飛書)、DingTalk(釘釘)、WeCom(企業微信)、WeChat公式アカウントなどをサポート |
|
||||
| **Agent Core** | タスク計画、記憶システム、Skill エンジンを含む Agent エンジン |
|
||||
| **Tools** | Agent が OS リソースにアクセスするためのツール層。10 以上の組み込みツール |
|
||||
| **Models** | 主要な LLM への統一アクセスを提供するモデル層 |
|
||||
| **Plan** | ユーザーの意図を理解し、複雑なタスクをマルチステップの計画に分解、目標達成までツールを反復的に呼び出す |
|
||||
| **Memory** | 重要な情報をコアメモリとデイリーメモリとして自動永続化し、キーワードとベクトルのハイブリッド検索でセッション間の連続性を実現 |
|
||||
| **Knowledge** | トピック別に構造化された知識を整理。Agent が価値ある情報を Markdown ページとして自律的に整理し、インデックスと相互参照で成長するナレッジネットワークを構築 |
|
||||
| **Tools** | Agent が OS リソースにアクセスするための中核能力。ファイル読み書き、ターミナル、ブラウザ、スケジューラ、記憶検索、Web 検索など 10 以上の組み込みツール |
|
||||
| **Skills** | Skill の読み込み・管理。Skill Hub や GitHub からのワンクリックインストール、または会話を通じたカスタム Skill の作成をサポート |
|
||||
| **Models** | モデル層。OpenAI、Claude、Gemini、DeepSeek、MiniMax、GLM、Qwen など主要 LLM への統一アクセスを提供 |
|
||||
| **Channels** | メッセージチャネル層。Web コンソール、WeChat、Feishu、DingTalk、WeCom、公式アカウントなど複数チャネルを統一プロトコルでサポート |
|
||||
| **CLI** | コマンドラインシステム。ターミナルコマンド(`cow`)とチャットコマンド(`/`)で、プロセス管理、Skill インストール、設定変更、ナレッジベース管理などをサポート |
|
||||
|
||||
## Agent モードのワークフロー
|
||||
|
||||
@@ -28,7 +30,7 @@ Agent モードが有効な場合、CowAgent は以下のワークフローで
|
||||
2. **意図の理解** — タスク要件とコンテキストを分析
|
||||
3. **タスク計画** — 複雑なタスクを複数のステップに分解
|
||||
4. **ツール呼び出し** — 各ステップに適切なツールを選択・実行
|
||||
5. **記憶の更新** — 重要な情報を長期記憶に保存
|
||||
5. **記憶・ナレッジの更新** — 重要な情報を長期記憶に保存し、構造化された知識をナレッジベースに整理
|
||||
6. **結果の返却** — 実行結果をユーザーに送信
|
||||
|
||||
## ワークスペースのディレクトリ構成
|
||||
@@ -39,9 +41,12 @@ Agent のワークスペースはデフォルトで `~/cow` にあり、シス
|
||||
~/cow/
|
||||
├── system.md # Agent システムプロンプト
|
||||
├── user.md # ユーザープロフィール
|
||||
├── MEMORY.md # コアメモリ
|
||||
├── memory/ # 長期記憶ストレージ
|
||||
│ ├── core.md # コアメモリ
|
||||
│ └── daily/ # デイリーメモリ
|
||||
│ └── YYYY-MM-DD.md # デイリーメモリ
|
||||
├── knowledge/ # パーソナルナレッジベース
|
||||
│ ├── index.md # ナレッジインデックス
|
||||
│ └── <category>/ # トピック別ページ
|
||||
└── skills/ # カスタム Skill
|
||||
├── skill-1/
|
||||
└── skill-2/
|
||||
@@ -75,3 +80,4 @@ Agent のワークスペースはデフォルトで `~/cow` にあり、シス
|
||||
| `agent_max_context_tokens` | 最大コンテキストトークン数 | `40000` |
|
||||
| `agent_max_context_turns` | 最大コンテキストターン数 | `30` |
|
||||
| `agent_max_steps` | タスクあたりの最大判断ステップ数 | `15` |
|
||||
| `knowledge` | パーソナルナレッジベースの有効化 | `true` |
|
||||
|
||||
@@ -15,13 +15,26 @@ description: CowAgent の長期記憶、タスク計画、Skill システム、C
|
||||
<img src="https://cdn.link-ai.tech/doc/20260203000455.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
## 2. タスク計画とツール活用
|
||||
## 2. パーソナルナレッジベース
|
||||
|
||||
> ナレッジベースシステムにより、Agent は構造化された知識を継続的に蓄積・整理できます。時系列で記録されるメモリとは異なり、ナレッジベースはトピック別に整理され、記事、会話からの洞察、学習資料などを相互にリンクされた Markdown ページとして整理し、継続的に成長するナレッジネットワークを形成します。
|
||||
|
||||
Agent は会話中に価値ある情報を自動的にナレッジページとして整理し、相互参照とインデックスを維持します。Web コンソールではドキュメントの閲覧とナレッジグラフの可視化が可能です。ナレッジはワークスペースの `~/cow/knowledge/` ディレクトリに保存されます。
|
||||
|
||||
- **自動整理**:Agent が会話中に構造化された知識を自律的に抽出・整理し、インデックスと相互参照を維持
|
||||
- **ナレッジグラフ**:ページ間の相互参照から自動的にナレッジグラフを構築し、Web コンソールでインタラクティブな関係図として可視化
|
||||
- **チャット連携**:Agent の回答で参照されるナレッジドキュメントのリンクを Web コンソールで直接クリックして閲覧可能
|
||||
- **CLI 管理**:`/knowledge` コマンドで統計表示、ディレクトリ閲覧、`/knowledge on|off` で機能の切り替えが可能
|
||||
|
||||
詳細は [パーソナルナレッジベース](/ja/knowledge) を参照してください。
|
||||
|
||||
## 3. タスク計画とツール活用
|
||||
|
||||
ツールは Agent がオペレーティングシステムのリソースにアクセスするための中核です。Agent はタスク要件に基づいてインテリジェントにツールを選択・呼び出し、ファイルの読み書き、コマンド実行、スケジュールタスクなどを実行します。組み込みツールはプロジェクトの `agent/tools/` ディレクトリに実装されています。
|
||||
|
||||
**主なツール:** ファイルの読み書き・編集、Bash ターミナル、ブラウザ操作、ファイル送信、スケジューラ、記憶検索、Web 検索、環境設定など。
|
||||
|
||||
### 2.1 ターミナルとファイルアクセス
|
||||
### 3.1 ターミナルとファイルアクセス
|
||||
|
||||
OS のターミナルとファイルシステムへのアクセスは、最も基本的かつ中核的な機能です。多くの他のツールや Skill はこの機能の上に構築されています。ユーザーはモバイルデバイスから Agent とやり取りし、パソコンやサーバーのリソースを操作できます:
|
||||
|
||||
@@ -29,7 +42,7 @@ OS のターミナルとファイルシステムへのアクセスは、最も
|
||||
<img src="https://cdn.link-ai.tech/doc/20260202181130.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 2.2 プログラミング能力
|
||||
### 3.2 プログラミング能力
|
||||
|
||||
プログラミングとシステムアクセスを組み合わせることで、Agent は完全な **Vibecoding ワークフロー** を実行できます。情報検索、アセット生成、コーディング、テスト、デプロイ、Nginx 設定、公開まで、すべてスマートフォンからの一つのコマンドで実行可能です:
|
||||
|
||||
@@ -37,7 +50,7 @@ OS のターミナルとファイルシステムへのアクセスは、最も
|
||||
<img src="https://cdn.link-ai.tech/doc/20260203121008.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 2.3 スケジュールタスク
|
||||
### 3.3 スケジュールタスク
|
||||
|
||||
`scheduler` ツールにより動的なスケジュールタスクが可能で、**ワンタイムタスク、固定間隔、Cron 式**をサポートしています。タスクは**固定メッセージ送信**または **Agent 動的タスク**実行としてトリガーできます:
|
||||
|
||||
@@ -45,7 +58,7 @@ OS のターミナルとファイルシステムへのアクセスは、最も
|
||||
<img src="https://cdn.link-ai.tech/doc/20260202195402.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 2.4 ブラウザ操作
|
||||
### 3.4 ブラウザ操作
|
||||
|
||||
組み込みの `browser` ツールにより、Agent は Chromium ブラウザを制御して Web ページへのアクセス、フォームの入力、要素のクリック、スクリーンショットの撮影が可能です。動的 JS レンダリングページにも対応しています。`cow install-browser` でワンコマンドインストール、サーバー(ヘッドレス)とデスクトップ環境に自動対応します:
|
||||
|
||||
@@ -53,7 +66,7 @@ OS のターミナルとファイルシステムへのアクセスは、最も
|
||||
<img src="https://cdn.link-ai.tech/doc/20260401110103.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 2.5 環境変数管理
|
||||
### 3.5 環境変数管理
|
||||
|
||||
Skill が必要とするシークレットキーは環境変数ファイルに保存され、`env_config` ツールによって管理されます。会話を通じてシークレットを更新でき、セキュリティ保護とマスキング機能が組み込まれています:
|
||||
|
||||
@@ -61,7 +74,7 @@ Skill が必要とするシークレットキーは環境変数ファイルに
|
||||
<img src="https://cdn.link-ai.tech/doc/20260202234939.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
## 3. Skill システム
|
||||
## 4. Skill システム
|
||||
|
||||
Skill システムは Agent に無限の拡張性を提供します。各 Skill は説明ファイル、実行スクリプト(任意)、リソース(任意)で構成され、特定のタイプのタスクを完了する方法を記述します。Skill により Agent は複雑なワークフローの指示に従い、ツールを呼び出し、サードパーティシステムと連携できます。
|
||||
|
||||
@@ -71,7 +84,7 @@ Skill システムは Agent に無限の拡張性を提供します。各 Skill
|
||||
|
||||
Skill のインストール:`/skill install <名前>` または `cow skill install <名前>`。Skill Hub、GitHub、ClawHub、URL などからインストール可能。
|
||||
|
||||
### 3.1 Skill の作成
|
||||
### 4.1 Skill の作成
|
||||
|
||||
`skill-creator` Skill により、会話を通じて Skill を素早く作成できます。ワークフローを Skill としてコード化するよう Agent に依頼したり、API ドキュメントやサンプルを送信して Agent に直接連携を完成させることができます:
|
||||
|
||||
@@ -79,7 +92,7 @@ Skill のインストール:`/skill install <名前>` または `cow skill ins
|
||||
<img src="https://cdn.link-ai.tech/doc/20260202202247.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 3.2 Web 検索と画像認識
|
||||
### 4.2 Web 検索と画像認識
|
||||
|
||||
- **Web 検索:** 組み込みの `web_search` ツールで、複数の検索エンジンをサポートします。`BOCHA_API_KEY` または `LINKAI_API_KEY` を設定して有効化してください。
|
||||
- **画像認識:** 組み込みの `openai-image-vision` Skill で、`gpt-4.1-mini`、`gpt-4.1` などのモデルをサポートします。`OPENAI_API_KEY` が必要です。
|
||||
@@ -88,7 +101,7 @@ Skill のインストール:`/skill install <名前>` または `cow skill ins
|
||||
<img src="https://cdn.link-ai.tech/doc/20260202213219.png" width="800" />
|
||||
</Frame>
|
||||
|
||||
### 3.3 Skill Hub
|
||||
### 4.3 Skill Hub
|
||||
|
||||
[skills.cowagent.ai](https://skills.cowagent.ai/) で利用可能なすべての Skill を閲覧するか、会話内でコマンドを実行できます:
|
||||
|
||||
@@ -102,7 +115,7 @@ GitHub、ClawHub、LinkAI などサードパーティプラットフォームの
|
||||
|
||||
<img src="https://cdn.link-ai.tech/doc/20260401110103.png" width="750" />
|
||||
|
||||
## 4. CLI コマンドシステム
|
||||
## 5. CLI コマンドシステム
|
||||
|
||||
CowAgent はサービス管理、Skill インストール、設定変更などをカバーする2つのコマンドインターフェースを提供します:
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ description: CowAgent - LLM を活用した AI スーパーアシスタント
|
||||
|
||||
CowAgent は自ら思考しタスクを計画し、コンピュータや外部リソースを操作し、Skill を作成・実行し、長期記憶により継続的に成長します。複数モデルの柔軟な切り替えをサポートし、テキスト、音声、画像、ファイルなどのマルチモーダルメッセージを処理でき、WeChat、Web、Feishu(飛書)、DingTalk(釘釘)、WeCom(企業微信)、WeChat公式アカウントに統合できます。お使いのパソコンやサーバー上で24時間365日稼働します。
|
||||
|
||||
<Card title="GitHub" icon="github" href="https://github.com/zhayujie/chatgpt-on-wechat">
|
||||
github.com/zhayujie/chatgpt-on-wechat
|
||||
<Card title="GitHub" icon="github" href="https://github.com/zhayujie/CowAgent">
|
||||
github.com/zhayujie/CowAgent
|
||||
</Card>
|
||||
|
||||
## コア機能
|
||||
@@ -22,6 +22,9 @@ CowAgent は自ら思考しタスクを計画し、コンピュータや外部
|
||||
<Card title="長期記憶" icon="database" href="/ja/memory">
|
||||
会話の記憶をローカルファイルやデータベースに自動的に永続化します。コアメモリとデイリーメモリを含み、キーワード検索とベクトル検索に対応しています。
|
||||
</Card>
|
||||
<Card title="ナレッジベース" icon="book" href="/ja/knowledge">
|
||||
構造化された知識を自動整理し、ナレッジグラフの可視化をサポート。相互参照により継続的に成長するナレッジネットワークを構築します。
|
||||
</Card>
|
||||
<Card title="Skill システム" icon="puzzle-piece" href="/ja/skills/index">
|
||||
Skill の作成・実行エンジンを実装し、組み込み Skill を搭載。自然言語の会話を通じてカスタム Skill の開発もサポートしています。
|
||||
</Card>
|
||||
@@ -72,7 +75,7 @@ CowAgent は自ら思考しタスクを計画し、コンピュータや外部
|
||||
|
||||
## 免責事項
|
||||
|
||||
1. 本プロジェクトは [MIT License](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/LICENSE) に基づき、技術研究および学習を目的としています。利用者は現地の法律、規制、ポリシー、および企業の社内規程を遵守する必要があります。違法行為や権利侵害につながる利用は禁止されています。
|
||||
1. 本プロジェクトは [MIT License](https://github.com/zhayujie/CowAgent/blob/master/LICENSE) に基づき、技術研究および学習を目的としています。利用者は現地の法律、規制、ポリシー、および企業の社内規程を遵守する必要があります。違法行為や権利侵害につながる利用は禁止されています。
|
||||
2. Agent モードは通常のチャットモードよりも多くのトークンを消費します。効果とコストを考慮してモデルを選択してください。Agent はホスト OS にアクセスできるため、デプロイには十分注意してください。
|
||||
3. CowAgent はオープンソース開発に注力しており、いかなる暗号通貨の発行、認可、参加も行っておりません。
|
||||
|
||||
|
||||
89
docs/ja/knowledge/index.mdx
Normal file
89
docs/ja/knowledge/index.mdx
Normal file
@@ -0,0 +1,89 @@
|
||||
---
|
||||
title: パーソナルナレッジベース
|
||||
description: CowAgent のパーソナルナレッジベース — 構造化された知識の蓄積、自動整理、ナレッジグラフ
|
||||
---
|
||||
|
||||
パーソナルナレッジベースは、Agent の長期的な構造化知識ストレージで、ワークスペースの `knowledge/` ディレクトリに保存されます。タイムラインで整理されるメモリとは異なり、ナレッジベースはトピック別にコンテンツを整理します。記事、会話のインサイト、学習資料が相互リンクされた Markdown ページとして構造化され、継続的に成長するナレッジネットワークを形成します。
|
||||
|
||||
## コアコンセプト
|
||||
|
||||
### ナレッジ vs メモリ
|
||||
|
||||
| 次元 | ナレッジベース(knowledge/) | 長期記憶(memory/) |
|
||||
| --- | --- | --- |
|
||||
| 整理方法 | トピック別、相互リンク | タイムライン順、日付ファイル |
|
||||
| 書き込み | Agent が能動的に構造化 | コンテキストトリミング時に自動要約 |
|
||||
| コンテンツ | 精製された構造化知識 | 生の会話要約 |
|
||||
| 用途 | 学習ノート、技術ドキュメント、プロジェクト知識 | 会話履歴、イベント記録 |
|
||||
|
||||
### ディレクトリ構造
|
||||
|
||||
```
|
||||
~/cow/knowledge/
|
||||
├── index.md # ナレッジインデックス、全ページのエントリポイント
|
||||
├── log.md # 変更ログ、各書き込みの記録
|
||||
├── concepts/ # 概念的な知識
|
||||
│ └── machine-learning.md
|
||||
├── entities/ # エンティティ知識(人物、組織、ツール)
|
||||
│ └── openai.md
|
||||
└── sources/ # ソース知識(記事、論文)
|
||||
└── llm-wiki.md
|
||||
```
|
||||
|
||||
ディレクトリ構造は柔軟です — Agent は実際のコンテンツに基づいて適切なカテゴリディレクトリを自動作成します。ユーザーが整理方法をカスタマイズすることも可能です。
|
||||
|
||||
## 自動整理
|
||||
|
||||
ナレッジの書き込みは Agent の自律的な動作で、以下のシナリオでトリガーされます:
|
||||
|
||||
- **ユーザーが記事やドキュメントを共有** — Agent が自動的にキー情報を抽出し、構造化されたナレッジページを作成
|
||||
- **会話から価値ある結論が生まれた場合** — Agent がインサイトをナレッジページに整理し、既存の知識とリンク
|
||||
- **ユーザーが明示的に整理を要求** — ユーザーは会話を通じて Agent にナレッジの整理・更新を指示可能
|
||||
|
||||
各ナレッジページには関連ページへの相互参照リンクが含まれ、ナレッジグラフを段階的に構築します。
|
||||
|
||||
<Frame>
|
||||
<img src="https://gist.github.com/user-attachments/assets/3ce92f78-1863-4820-8fa8-660c0f2b7f09" alt="会話によるナレッジの取り込み" />
|
||||
</Frame>
|
||||
|
||||
## ナレッジ検索
|
||||
|
||||
Agent は会話中に以下の方法でナレッジを検索できます:
|
||||
|
||||
- **インデックス参照** — `knowledge/index.md` で関連ページを素早く特定
|
||||
- **セマンティック検索** — `memory_search` ツールでナレッジコンテンツをセマンティック検索
|
||||
- **直接読み取り** — `memory_get` ツールで特定のナレッジファイルを読み取り
|
||||
|
||||
## Web コンソール
|
||||
|
||||
Web コンソールには専用の「ナレッジ」モジュールがあり、以下をサポートします:
|
||||
|
||||
- **ドキュメント閲覧** — ツリー形式のディレクトリ構造、検索・折りたたみ可能、クリックでコンテンツ表示
|
||||
- **ナレッジグラフ** — インタラクティブなグラフによるナレッジ間の関係を可視化
|
||||
- **チャット連携** — Agent の返信で参照されたナレッジドキュメントリンクはクリックで直接ナビゲーション
|
||||
|
||||
<Frame>
|
||||
<img src="https://gist.github.com/user-attachments/assets/b7b9d6be-0ac1-4c65-803b-2c6b36bd59a7" alt="ナレッジドキュメント閲覧" />
|
||||
</Frame>
|
||||
|
||||
<Frame>
|
||||
<img src="https://gist.github.com/user-attachments/assets/44ae68ca-96cc-40b9-ab33-cdbec34c2379" alt="ナレッジグラフの可視化" />
|
||||
</Frame>
|
||||
|
||||
## CLI コマンド
|
||||
|
||||
`/knowledge` コマンドでナレッジベースを管理:
|
||||
|
||||
| コマンド | 説明 |
|
||||
| --- | --- |
|
||||
| `/knowledge` | ナレッジベースの統計情報を表示 |
|
||||
| `/knowledge list` | ファイルディレクトリをツリー形式で表示 |
|
||||
| `/knowledge on` | ナレッジベース機能を有効化 |
|
||||
| `/knowledge off` | ナレッジベース機能を無効化 |
|
||||
|
||||
## 設定
|
||||
|
||||
| パラメータ | 説明 | デフォルト |
|
||||
| --- | --- | --- |
|
||||
| `knowledge` | パーソナルナレッジベースの有効/無効 | `true` |
|
||||
| `agent_workspace` | ワークスペースパス、ナレッジは `knowledge/` サブディレクトリに保存されます | `~/cow` |
|
||||
@@ -51,5 +51,5 @@ CowAgentは国内外の主要なLLMをサポートしています。モデルイ
|
||||
</CardGroup>
|
||||
|
||||
<Tip>
|
||||
モデル名の完全なリストについては、プロジェクトの[`common/const.py`](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/common/const.py)ファイルを参照してください。
|
||||
モデル名の完全なリストについては、プロジェクトの[`common/const.py`](https://github.com/zhayujie/CowAgent/blob/master/common/const.py)ファイルを参照してください。
|
||||
</Tip>
|
||||
|
||||
@@ -22,4 +22,4 @@ description: CowAgent バージョン履歴
|
||||
| 1.5.0 | 2023.11.10 | gpt-4-turbo、dall-e-3、tts マルチモーダル |
|
||||
| 1.0.0 | 2022.12.12 | プロジェクト作成、初の ChatGPT 統合 |
|
||||
|
||||
完全な履歴は [GitHub Releases](https://github.com/zhayujie/chatgpt-on-wechat/releases) をご覧ください。
|
||||
完全な履歴は [GitHub Releases](https://github.com/zhayujie/CowAgent/releases) をご覧ください。
|
||||
|
||||
@@ -5,7 +5,7 @@ description: CowAgent 2.0 - チャットボットから AI スーパーアシス
|
||||
|
||||
CowAgent 2.0 は、チャットボットから **AI スーパーアシスタント** への包括的なアップグレードです。自律的な思考とタスク計画、長期記憶、コンピューターの操作、Skill の作成と実行が可能です。
|
||||
|
||||
**リリース日**: 2026.02.03 | [GitHub Release](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.0)
|
||||
**リリース日**: 2026.02.03 | [GitHub Release](https://github.com/zhayujie/CowAgent/releases/tag/2.0.0)
|
||||
|
||||
## 主な更新内容
|
||||
|
||||
@@ -60,4 +60,4 @@ CowAgent 2.0 は、チャットボットから **AI スーパーアシスタン
|
||||
|
||||
## コントリビューション
|
||||
|
||||
[フィードバックの送信](https://github.com/zhayujie/chatgpt-on-wechat/issues) や [コードのコントリビューション](https://github.com/zhayujie/chatgpt-on-wechat/pulls) を歓迎します。
|
||||
[フィードバックの送信](https://github.com/zhayujie/CowAgent/issues) や [コードのコントリビューション](https://github.com/zhayujie/CowAgent/pulls) を歓迎します。
|
||||
|
||||
@@ -3,34 +3,34 @@ title: v2.0.1
|
||||
description: CowAgent 2.0.1 - 組み込み Web Search、スマートコンテキスト管理、複数の修正
|
||||
---
|
||||
|
||||
**リリース日**: 2026.02.27 | [全変更履歴](https://github.com/zhayujie/chatgpt-on-wechat/compare/2.0.0..2.0.1)
|
||||
**リリース日**: 2026.02.27 | [全変更履歴](https://github.com/zhayujie/CowAgent/compare/2.0.0..2.0.1)
|
||||
|
||||
## 新機能
|
||||
|
||||
- **組み込み Web Search ツール**: Web 検索を Agent の組み込みツールとして統合し、判断コストを削減 ([4f0ea5d](https://github.com/zhayujie/chatgpt-on-wechat/commit/4f0ea5d7568d61db91ff69c91c429e785fd1b1c2))
|
||||
- **Claude Opus 4.6 モデル対応**: Claude Opus 4.6 モデルのサポートを追加 ([#2661](https://github.com/zhayujie/chatgpt-on-wechat/pull/2661))
|
||||
- **企业微信の画像認識**: 企业微信チャネルでの画像メッセージ認識をサポート ([#2667](https://github.com/zhayujie/chatgpt-on-wechat/pull/2667))
|
||||
- **組み込み Web Search ツール**: Web 検索を Agent の組み込みツールとして統合し、判断コストを削減 ([4f0ea5d](https://github.com/zhayujie/CowAgent/commit/4f0ea5d7568d61db91ff69c91c429e785fd1b1c2))
|
||||
- **Claude Opus 4.6 モデル対応**: Claude Opus 4.6 モデルのサポートを追加 ([#2661](https://github.com/zhayujie/CowAgent/pull/2661))
|
||||
- **企业微信の画像認識**: 企业微信チャネルでの画像メッセージ認識をサポート ([#2667](https://github.com/zhayujie/CowAgent/pull/2667))
|
||||
|
||||
## 改善
|
||||
|
||||
- **スマートコンテキスト管理**: インテリジェントなコンテキストトリミング戦略により、チャットコンテキストのオーバーフローを解決し、トークン制限超過を防止 ([cea7fb7](https://github.com/zhayujie/chatgpt-on-wechat/commit/cea7fb7490c53454602bf05955a0e9f059bcf0fd), [8acf2db](https://github.com/zhayujie/chatgpt-on-wechat/commit/8acf2dbdfe713b84ad74b761b7f86674b1c1904d)) [#2663](https://github.com/zhayujie/chatgpt-on-wechat/issues/2663)
|
||||
- **ランタイム情報の動的更新**: 動的関数によるシステムプロンプト内のタイムスタンプおよびその他のランタイム情報の自動更新 ([#2655](https://github.com/zhayujie/chatgpt-on-wechat/pull/2655), [#2657](https://github.com/zhayujie/chatgpt-on-wechat/pull/2657))
|
||||
- **Skill プロンプトの最適化**: Skill システムプロンプト生成を改善し、ツールの説明を簡素化して Agent のパフォーマンスを向上 ([6c21833](https://github.com/zhayujie/chatgpt-on-wechat/commit/6c218331b1f1208ea8be6bf226936d3b556ade3e))
|
||||
- **GLM カスタム API Base URL**: GLM モデルのカスタム API Base URL をサポート ([#2660](https://github.com/zhayujie/chatgpt-on-wechat/pull/2660))
|
||||
- **起動スクリプトの最適化**: `run.sh` スクリプトのインタラクションと設定フローを改善 ([#2656](https://github.com/zhayujie/chatgpt-on-wechat/pull/2656))
|
||||
- **判断ステップのログ記録**: デバッグ用の Agent 判断ステップログを追加 ([cb303e6](https://github.com/zhayujie/chatgpt-on-wechat/commit/cb303e6109c50c8dfef1f5e6c1ec47223bf3cd11))
|
||||
- **スマートコンテキスト管理**: インテリジェントなコンテキストトリミング戦略により、チャットコンテキストのオーバーフローを解決し、トークン制限超過を防止 ([cea7fb7](https://github.com/zhayujie/CowAgent/commit/cea7fb7490c53454602bf05955a0e9f059bcf0fd), [8acf2db](https://github.com/zhayujie/CowAgent/commit/8acf2dbdfe713b84ad74b761b7f86674b1c1904d)) [#2663](https://github.com/zhayujie/CowAgent/issues/2663)
|
||||
- **ランタイム情報の動的更新**: 動的関数によるシステムプロンプト内のタイムスタンプおよびその他のランタイム情報の自動更新 ([#2655](https://github.com/zhayujie/CowAgent/pull/2655), [#2657](https://github.com/zhayujie/CowAgent/pull/2657))
|
||||
- **Skill プロンプトの最適化**: Skill システムプロンプト生成を改善し、ツールの説明を簡素化して Agent のパフォーマンスを向上 ([6c21833](https://github.com/zhayujie/CowAgent/commit/6c218331b1f1208ea8be6bf226936d3b556ade3e))
|
||||
- **GLM カスタム API Base URL**: GLM モデルのカスタム API Base URL をサポート ([#2660](https://github.com/zhayujie/CowAgent/pull/2660))
|
||||
- **起動スクリプトの最適化**: `run.sh` スクリプトのインタラクションと設定フローを改善 ([#2656](https://github.com/zhayujie/CowAgent/pull/2656))
|
||||
- **判断ステップのログ記録**: デバッグ用の Agent 判断ステップログを追加 ([cb303e6](https://github.com/zhayujie/CowAgent/commit/cb303e6109c50c8dfef1f5e6c1ec47223bf3cd11))
|
||||
|
||||
## バグ修正
|
||||
|
||||
- **Scheduler の記憶喪失**: Scheduler ディスパッチャーによる記憶喪失を修正 ([a77a874](https://github.com/zhayujie/chatgpt-on-wechat/commit/a77a8741b500a408c6f5c8868856fb4b018fe9db))
|
||||
- **空のツール呼び出しと長い結果**: 空のツール呼び出しおよび過度に長いツール結果の処理を修正 ([0542700](https://github.com/zhayujie/chatgpt-on-wechat/commit/0542700f9091ebb08c1a56103b0f0f45f24aa621))
|
||||
- **OpenAI Function Call**: OpenAI モデルとの Function Call 互換性を修正 ([158c87a](https://github.com/zhayujie/chatgpt-on-wechat/commit/158c87ab8b05bae054cc1b4eacdbb64fc1062ba9))
|
||||
- **Claude ツール名フィールド**: Claude モデルのレスポンスから余分なツール名フィールドを削除 ([eec10cb](https://github.com/zhayujie/chatgpt-on-wechat/commit/eec10cb5db6a3d5bc12ef606606532237d2c5f6e))
|
||||
- **MiniMax 推論**: MiniMax モデルの推論コンテンツ処理を最適化し、思考プロセスの出力を非表示化 ([c72cda3](https://github.com/zhayujie/chatgpt-on-wechat/commit/c72cda33864bd1542012ee6e0a8bd8c6c88cb5ed), [72b1cac](https://github.com/zhayujie/chatgpt-on-wechat/commit/72b1cacea1ba0d1f3dedacbab2e088e98fd7e172))
|
||||
- **GLM 思考プロセス**: GLM モデルの思考プロセス表示を非表示化 ([72b1cac](https://github.com/zhayujie/chatgpt-on-wechat/commit/72b1cacea1ba0d1f3dedacbab2e088e98fd7e172))
|
||||
- **飞书の接続と SSL**: 飞书チャネルの SSL 証明書エラーおよび接続問題を修正 ([229b14b](https://github.com/zhayujie/chatgpt-on-wechat/commit/229b14b6fcabe7123d53cab1dea39f38dab26d6d), [8674421](https://github.com/zhayujie/chatgpt-on-wechat/commit/867442155e7f095b4f38b0856f8c1d8312b5fcf7))
|
||||
- **model_type バリデーション**: 非文字列の `model_type` による `AttributeError` を修正 ([#2666](https://github.com/zhayujie/chatgpt-on-wechat/pull/2666))
|
||||
- **Scheduler の記憶喪失**: Scheduler ディスパッチャーによる記憶喪失を修正 ([a77a874](https://github.com/zhayujie/CowAgent/commit/a77a8741b500a408c6f5c8868856fb4b018fe9db))
|
||||
- **空のツール呼び出しと長い結果**: 空のツール呼び出しおよび過度に長いツール結果の処理を修正 ([0542700](https://github.com/zhayujie/CowAgent/commit/0542700f9091ebb08c1a56103b0f0f45f24aa621))
|
||||
- **OpenAI Function Call**: OpenAI モデルとの Function Call 互換性を修正 ([158c87a](https://github.com/zhayujie/CowAgent/commit/158c87ab8b05bae054cc1b4eacdbb64fc1062ba9))
|
||||
- **Claude ツール名フィールド**: Claude モデルのレスポンスから余分なツール名フィールドを削除 ([eec10cb](https://github.com/zhayujie/CowAgent/commit/eec10cb5db6a3d5bc12ef606606532237d2c5f6e))
|
||||
- **MiniMax 推論**: MiniMax モデルの推論コンテンツ処理を最適化し、思考プロセスの出力を非表示化 ([c72cda3](https://github.com/zhayujie/CowAgent/commit/c72cda33864bd1542012ee6e0a8bd8c6c88cb5ed), [72b1cac](https://github.com/zhayujie/CowAgent/commit/72b1cacea1ba0d1f3dedacbab2e088e98fd7e172))
|
||||
- **GLM 思考プロセス**: GLM モデルの思考プロセス表示を非表示化 ([72b1cac](https://github.com/zhayujie/CowAgent/commit/72b1cacea1ba0d1f3dedacbab2e088e98fd7e172))
|
||||
- **飞书の接続と SSL**: 飞书チャネルの SSL 証明書エラーおよび接続問題を修正 ([229b14b](https://github.com/zhayujie/CowAgent/commit/229b14b6fcabe7123d53cab1dea39f38dab26d6d), [8674421](https://github.com/zhayujie/CowAgent/commit/867442155e7f095b4f38b0856f8c1d8312b5fcf7))
|
||||
- **model_type バリデーション**: 非文字列の `model_type` による `AttributeError` を修正 ([#2666](https://github.com/zhayujie/CowAgent/pull/2666))
|
||||
|
||||
## プラットフォーム互換性
|
||||
|
||||
- **Windows 互換性**: 複数のツールモジュールにおける Windows でのパス処理、ファイルエンコーディング、および `os.getuid()` の利用不可問題を修正 ([051ffd7](https://github.com/zhayujie/chatgpt-on-wechat/commit/051ffd78a372f71a967fd3259e37fe19131f83cf), [5264f7c](https://github.com/zhayujie/chatgpt-on-wechat/commit/5264f7ce18360ee4db5dcb4ebe67307977d40014))
|
||||
- **Windows 互換性**: 複数のツールモジュールにおける Windows でのパス処理、ファイルエンコーディング、および `os.getuid()` の利用不可問題を修正 ([051ffd7](https://github.com/zhayujie/CowAgent/commit/051ffd78a372f71a967fd3259e37fe19131f83cf), [5264f7c](https://github.com/zhayujie/CowAgent/commit/5264f7ce18360ee4db5dcb4ebe67307977d40014))
|
||||
|
||||
@@ -3,7 +3,7 @@ title: v2.0.2
|
||||
description: CowAgent 2.0.2 - Web Console アップグレード、マルチチャネル同時実行、セッション永続化
|
||||
---
|
||||
|
||||
**リリース日**: 2026.02.27 | [全変更履歴](https://github.com/zhayujie/chatgpt-on-wechat/compare/2.0.1...master)
|
||||
**リリース日**: 2026.02.27 | [全変更履歴](https://github.com/zhayujie/CowAgent/compare/2.0.1...master)
|
||||
|
||||
## ハイライト
|
||||
|
||||
@@ -53,7 +53,7 @@ Agent のランタイムログをリアルタイムで表示し、監視とト
|
||||
|
||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173514.png" />
|
||||
|
||||
関連コミット: [f1a1413](https://github.com/zhayujie/chatgpt-on-wechat/commit/f1a1413), [c0702c8](https://github.com/zhayujie/chatgpt-on-wechat/commit/c0702c8), [394853c](https://github.com/zhayujie/chatgpt-on-wechat/commit/394853c), [1c71c4e](https://github.com/zhayujie/chatgpt-on-wechat/commit/1c71c4e), [5e3eccb](https://github.com/zhayujie/chatgpt-on-wechat/commit/5e3eccb), [e1dc037](https://github.com/zhayujie/chatgpt-on-wechat/commit/e1dc037), [5edbf4c](https://github.com/zhayujie/chatgpt-on-wechat/commit/5edbf4c), [7d258b5](https://github.com/zhayujie/chatgpt-on-wechat/commit/7d258b5)
|
||||
関連コミット: [f1a1413](https://github.com/zhayujie/CowAgent/commit/f1a1413), [c0702c8](https://github.com/zhayujie/CowAgent/commit/c0702c8), [394853c](https://github.com/zhayujie/CowAgent/commit/394853c), [1c71c4e](https://github.com/zhayujie/CowAgent/commit/1c71c4e), [5e3eccb](https://github.com/zhayujie/CowAgent/commit/5e3eccb), [e1dc037](https://github.com/zhayujie/CowAgent/commit/e1dc037), [5edbf4c](https://github.com/zhayujie/CowAgent/commit/5edbf4c), [7d258b5](https://github.com/zhayujie/CowAgent/commit/7d258b5)
|
||||
|
||||
### 🔀 マルチチャネル同時実行
|
||||
|
||||
@@ -67,24 +67,24 @@ Agent のランタイムログをリアルタイムで表示し、監視とト
|
||||
}
|
||||
```
|
||||
|
||||
関連コミット: [4694594](https://github.com/zhayujie/chatgpt-on-wechat/commit/4694594), [7cce224](https://github.com/zhayujie/chatgpt-on-wechat/commit/7cce224), [7d258b5](https://github.com/zhayujie/chatgpt-on-wechat/commit/7d258b5), [c9adddb](https://github.com/zhayujie/chatgpt-on-wechat/commit/c9adddb)
|
||||
関連コミット: [4694594](https://github.com/zhayujie/CowAgent/commit/4694594), [7cce224](https://github.com/zhayujie/CowAgent/commit/7cce224), [7d258b5](https://github.com/zhayujie/CowAgent/commit/7d258b5), [c9adddb](https://github.com/zhayujie/CowAgent/commit/c9adddb)
|
||||
|
||||
### 💾 セッション永続化
|
||||
|
||||
セッション履歴がローカルの SQLite データベースに永続化されるようになりました。サービス再起動後も会話コンテキストが自動的に復元されます。Web Console の過去の会話も復元されます。
|
||||
|
||||
関連コミット: [29bfbec](https://github.com/zhayujie/chatgpt-on-wechat/commit/29bfbec), [9917552](https://github.com/zhayujie/chatgpt-on-wechat/commit/9917552), [925d728](https://github.com/zhayujie/chatgpt-on-wechat/commit/925d728)
|
||||
関連コミット: [29bfbec](https://github.com/zhayujie/CowAgent/commit/29bfbec), [9917552](https://github.com/zhayujie/CowAgent/commit/9917552), [925d728](https://github.com/zhayujie/CowAgent/commit/925d728)
|
||||
|
||||
## 新モデル
|
||||
|
||||
- **Gemini 3.1 Pro Preview**: `gemini-3.1-pro-preview` モデルのサポートを追加 ([52d7cad](https://github.com/zhayujie/chatgpt-on-wechat/commit/52d7cad))
|
||||
- **Claude 4.6 Sonnet**: `claude-4.6-sonnet` モデルのサポートを追加 ([52d7cad](https://github.com/zhayujie/chatgpt-on-wechat/commit/52d7cad))
|
||||
- **Qwen3.5 Plus**: `qwen3.5-plus` モデルのサポートを追加 ([e59a289](https://github.com/zhayujie/chatgpt-on-wechat/commit/e59a289))
|
||||
- **MiniMax M2.5**: `Minimax-M2.5` モデルのサポートを追加 ([48db538](https://github.com/zhayujie/chatgpt-on-wechat/commit/48db538))
|
||||
- **GLM-5**: `glm-5` モデルのサポートを追加 ([48db538](https://github.com/zhayujie/chatgpt-on-wechat/commit/48db538))
|
||||
- **Kimi K2.5**: `kimi-k2.5` モデルのサポートを追加 ([48db538](https://github.com/zhayujie/chatgpt-on-wechat/commit/48db538))
|
||||
- **Doubao 2.0 Code**: コーディング特化型 `doubao-2.0-code` モデルを追加 ([ab28ee5](https://github.com/zhayujie/chatgpt-on-wechat/commit/ab28ee5))
|
||||
- **DashScope モデル**: 阿里云 DashScope モデル名のサポートを追加 ([ce58f23](https://github.com/zhayujie/chatgpt-on-wechat/commit/ce58f23))
|
||||
- **Gemini 3.1 Pro Preview**: `gemini-3.1-pro-preview` モデルのサポートを追加 ([52d7cad](https://github.com/zhayujie/CowAgent/commit/52d7cad))
|
||||
- **Claude 4.6 Sonnet**: `claude-4.6-sonnet` モデルのサポートを追加 ([52d7cad](https://github.com/zhayujie/CowAgent/commit/52d7cad))
|
||||
- **Qwen3.5 Plus**: `qwen3.5-plus` モデルのサポートを追加 ([e59a289](https://github.com/zhayujie/CowAgent/commit/e59a289))
|
||||
- **MiniMax M2.5**: `Minimax-M2.5` モデルのサポートを追加 ([48db538](https://github.com/zhayujie/CowAgent/commit/48db538))
|
||||
- **GLM-5**: `glm-5` モデルのサポートを追加 ([48db538](https://github.com/zhayujie/CowAgent/commit/48db538))
|
||||
- **Kimi K2.5**: `kimi-k2.5` モデルのサポートを追加 ([48db538](https://github.com/zhayujie/CowAgent/commit/48db538))
|
||||
- **Doubao 2.0 Code**: コーディング特化型 `doubao-2.0-code` モデルを追加 ([ab28ee5](https://github.com/zhayujie/CowAgent/commit/ab28ee5))
|
||||
- **DashScope モデル**: 阿里云 DashScope モデル名のサポートを追加 ([ce58f23](https://github.com/zhayujie/CowAgent/commit/ce58f23))
|
||||
|
||||
## ウェブサイトとドキュメント
|
||||
|
||||
@@ -93,6 +93,6 @@ Agent のランタイムログをリアルタイムで表示し、監視とト
|
||||
|
||||
## バグ修正
|
||||
|
||||
- **Gemini 钉钉画像認識**: 钉钉チャネルで Gemini が画像マーカーを処理できない問題を修正 ([05a3304](https://github.com/zhayujie/chatgpt-on-wechat/commit/05a3304)) ([#2670](https://github.com/zhayujie/chatgpt-on-wechat/pull/2670)) Thanks [@SgtPepper114](https://github.com/SgtPepper114)
|
||||
- **起動スクリプトの依存関係**: `run.sh` スクリプトの依存関係インストール問題を修正 ([b6fc9fa](https://github.com/zhayujie/chatgpt-on-wechat/commit/b6fc9fa))
|
||||
- **bare except の整理**: より適切な例外処理のため `bare except` を `except Exception` に置換 ([adca89b](https://github.com/zhayujie/chatgpt-on-wechat/commit/adca89b)) ([#2674](https://github.com/zhayujie/chatgpt-on-wechat/pull/2674)) Thanks [@haosenwang1018](https://github.com/haosenwang1018)
|
||||
- **Gemini 钉钉画像認識**: 钉钉チャネルで Gemini が画像マーカーを処理できない問題を修正 ([05a3304](https://github.com/zhayujie/CowAgent/commit/05a3304)) ([#2670](https://github.com/zhayujie/CowAgent/pull/2670)) Thanks [@SgtPepper114](https://github.com/SgtPepper114)
|
||||
- **起動スクリプトの依存関係**: `run.sh` スクリプトの依存関係インストール問題を修正 ([b6fc9fa](https://github.com/zhayujie/CowAgent/commit/b6fc9fa))
|
||||
- **bare except の整理**: より適切な例外処理のため `bare except` を `except Exception` に置換 ([adca89b](https://github.com/zhayujie/CowAgent/commit/adca89b)) ([#2674](https://github.com/zhayujie/CowAgent/pull/2674)) Thanks [@haosenwang1018](https://github.com/haosenwang1018)
|
||||
|
||||
@@ -11,7 +11,7 @@ description: CowAgent 2.0.3 - 企業微信スマートボットとQQチャネル
|
||||
|
||||
接続ドキュメント:[企業微信スマートボット接続](https://docs.cowagent.ai/channels/wecom-bot)。
|
||||
|
||||
関連コミット:[d4480b6](https://github.com/zhayujie/chatgpt-on-wechat/commit/d4480b6), [a42f31f](https://github.com/zhayujie/chatgpt-on-wechat/commit/a42f31f), [4ecd4df](https://github.com/zhayujie/chatgpt-on-wechat/commit/4ecd4df), [8b45d6c](https://github.com/zhayujie/chatgpt-on-wechat/commit/8b45d6c)
|
||||
関連コミット:[d4480b6](https://github.com/zhayujie/CowAgent/commit/d4480b6), [a42f31f](https://github.com/zhayujie/CowAgent/commit/a42f31f), [4ecd4df](https://github.com/zhayujie/CowAgent/commit/4ecd4df), [8b45d6c](https://github.com/zhayujie/CowAgent/commit/8b45d6c)
|
||||
|
||||
### QQ チャネル
|
||||
|
||||
@@ -19,18 +19,18 @@ QQ 公式ボット(`qq`)チャネルを追加しました。テキストと
|
||||
|
||||
接続ドキュメント:[QQボット接続](https://docs.cowagent.ai/channels/qq)。
|
||||
|
||||
関連コミット:[005a0e1](https://github.com/zhayujie/chatgpt-on-wechat/commit/005a0e1), [a4d54f5](https://github.com/zhayujie/chatgpt-on-wechat/commit/a4d54f5)
|
||||
関連コミット:[005a0e1](https://github.com/zhayujie/CowAgent/commit/005a0e1), [a4d54f5](https://github.com/zhayujie/CowAgent/commit/a4d54f5)
|
||||
|
||||
## 🖥️ Web コンソールのファイル入力・処理対応
|
||||
|
||||
Web コンソールのチャット画面でファイルや画像のアップロードが可能になり、Agent に直接ファイルを送信して処理できます。また、Read ツールに Office ドキュメント(Word、Excel、PPT)の解析機能を追加しました。
|
||||
|
||||
関連コミット:[30c6d9b](https://github.com/zhayujie/chatgpt-on-wechat/commit/30c6d9b)
|
||||
関連コミット:[30c6d9b](https://github.com/zhayujie/CowAgent/commit/30c6d9b)
|
||||
|
||||
## 🤖 新規モデル
|
||||
|
||||
- **GPT-5.4 シリーズ**:`gpt-5.4`、`gpt-5.4-mini`、`gpt-5.4-nano` モデルのサポートを追加 ([1623deb](https://github.com/zhayujie/chatgpt-on-wechat/commit/1623deb))
|
||||
- **Gemini 3.1 Flash Lite Preview**:`gemini-3.1-flash-lite-preview` モデルのサポートを追加 ([ba915f2](https://github.com/zhayujie/chatgpt-on-wechat/commit/ba915f2))
|
||||
- **GPT-5.4 シリーズ**:`gpt-5.4`、`gpt-5.4-mini`、`gpt-5.4-nano` モデルのサポートを追加 ([1623deb](https://github.com/zhayujie/CowAgent/commit/1623deb))
|
||||
- **Gemini 3.1 Flash Lite Preview**:`gemini-3.1-flash-lite-preview` モデルのサポートを追加 ([ba915f2](https://github.com/zhayujie/CowAgent/commit/ba915f2))
|
||||
|
||||
## 💰 Coding Plan サポート
|
||||
|
||||
@@ -48,12 +48,12 @@ Web コンソールのチャット画面でファイルや画像のアップロ
|
||||
- 日次定期フラッシュのフォールバック機能を追加し、低アクティビティシナリオでのメモリ損失を防止
|
||||
- コンテキストメモリの損失問題を修正
|
||||
|
||||
関連コミット:[022c13f](https://github.com/zhayujie/chatgpt-on-wechat/commit/022c13f), [c116235](https://github.com/zhayujie/chatgpt-on-wechat/commit/c116235)
|
||||
関連コミット:[022c13f](https://github.com/zhayujie/CowAgent/commit/022c13f), [c116235](https://github.com/zhayujie/CowAgent/commit/c116235)
|
||||
|
||||
## 🔧 ツールリファクタリング
|
||||
|
||||
- **画像認識**:画像認識(Image Vision)を Skill から内蔵 Tool にリファクタリングし、独立した画像ビジョンプロバイダー(Vision Provider)設定を追加。安定性と保守性を向上 ([a50fafa](https://github.com/zhayujie/chatgpt-on-wechat/commit/a50fafa), [3b8b562](https://github.com/zhayujie/chatgpt-on-wechat/commit/3b8b562))
|
||||
- **Webスクレイピング**:Webスクレイピング(Web Fetch)を Skill から内蔵 Tool にリファクタリング。リモートドキュメントファイル(PDF、Word、Excel、PPT)のダウンロードと解析をサポート ([ccb9030](https://github.com/zhayujie/chatgpt-on-wechat/commit/ccb9030), [fa61744](https://github.com/zhayujie/chatgpt-on-wechat/commit/fa61744))
|
||||
- **画像認識**:画像認識(Image Vision)を Skill から内蔵 Tool にリファクタリングし、独立した画像ビジョンプロバイダー(Vision Provider)設定を追加。安定性と保守性を向上 ([a50fafa](https://github.com/zhayujie/CowAgent/commit/a50fafa), [3b8b562](https://github.com/zhayujie/CowAgent/commit/3b8b562))
|
||||
- **Webスクレイピング**:Webスクレイピング(Web Fetch)を Skill から内蔵 Tool にリファクタリング。リモートドキュメントファイル(PDF、Word、Excel、PPT)のダウンロードと解析をサポート ([ccb9030](https://github.com/zhayujie/CowAgent/commit/ccb9030), [fa61744](https://github.com/zhayujie/CowAgent/commit/fa61744))
|
||||
|
||||
## 🐳 Docker デプロイメントの最適化
|
||||
|
||||
@@ -64,28 +64,28 @@ Web コンソールのチャット画面でファイルや画像のアップロ
|
||||
|
||||
## ⚡ パフォーマンス最適化
|
||||
|
||||
- **起動高速化**:飛書チャネルで依存関係の遅延読み込みを採用し、4-10秒の起動遅延を回避 ([924dc79](https://github.com/zhayujie/chatgpt-on-wechat/commit/924dc79))
|
||||
- **チャネルの安定性**:チャネル接続の安定性を最適化し、環境変数によるチャネル設定をサポート ([f1c04bc](https://github.com/zhayujie/chatgpt-on-wechat/commit/f1c04bc), [46d97fd](https://github.com/zhayujie/chatgpt-on-wechat/commit/46d97fd))
|
||||
- **起動高速化**:飛書チャネルで依存関係の遅延読み込みを採用し、4-10秒の起動遅延を回避 ([924dc79](https://github.com/zhayujie/CowAgent/commit/924dc79))
|
||||
- **チャネルの安定性**:チャネル接続の安定性を最適化し、環境変数によるチャネル設定をサポート ([f1c04bc](https://github.com/zhayujie/CowAgent/commit/f1c04bc), [46d97fd](https://github.com/zhayujie/CowAgent/commit/46d97fd))
|
||||
|
||||
## 🐛 バグ修正
|
||||
|
||||
- **bot_type 設定**:Agent モードでの `bot_type` 設定の受け渡し問題を修正 ([#2691](https://github.com/zhayujie/chatgpt-on-wechat/pull/2691)) Thanks [@Weikjssss](https://github.com/Weikjssss)
|
||||
- **bot_type 優先順位**:Agent モードでの `bot_type` の解析優先順位を調整 ([#2692](https://github.com/zhayujie/chatgpt-on-wechat/pull/2692)) Thanks [@6vision](https://github.com/6vision)
|
||||
- **智譜モデル設定**:智譜の `bot_type` 命名、Web コンソールの永続化、正規表現エスケープの問題を修正 ([#2693](https://github.com/zhayujie/chatgpt-on-wechat/pull/2693)) Thanks [@6vision](https://github.com/6vision)
|
||||
- **OpenAI 互換レイヤー**:`openai_compat` レイヤーによる統一エラー処理 ([#2688](https://github.com/zhayujie/chatgpt-on-wechat/pull/2688)) Thanks [@JasonOA888](https://github.com/JasonOA888)
|
||||
- **OpenAI 互換移行**:全モデル Bot の `openai_compat` 移行を完了 ([#2689](https://github.com/zhayujie/chatgpt-on-wechat/pull/2689))
|
||||
- **Gemini ツール呼び出し**:Gemini モデルのツール呼び出しマッチング問題を修正 ([eda82ba](https://github.com/zhayujie/chatgpt-on-wechat/commit/eda82ba))
|
||||
- **セッション並行処理**:セッション並行シナリオでの競合条件の問題を修正 ([9879878](https://github.com/zhayujie/chatgpt-on-wechat/commit/9879878))
|
||||
- **履歴メッセージの復元**:履歴セッションメッセージの不完全な問題を修正。user/assistant のテキストメッセージのみを復元し、ツール呼び出しを除外 ([b788a3d](https://github.com/zhayujie/chatgpt-on-wechat/commit/b788a3d), [a33ce97](https://github.com/zhayujie/chatgpt-on-wechat/commit/a33ce97))
|
||||
- **飛書グループチャット**:飛書グループチャットシナリオでの `bot_name` 依存を削除 ([b641bff](https://github.com/zhayujie/chatgpt-on-wechat/commit/b641bff))
|
||||
- **Safari 互換性**:Safari ブラウザでの IME Enter キーによるメッセージ誤送信の問題を修正 ([0687916](https://github.com/zhayujie/chatgpt-on-wechat/commit/0687916))
|
||||
- **Windows 互換性**:Windows での bash スタイル `$VAR` 環境変数を `%VAR%` に変換する問題を修正 ([7c67513](https://github.com/zhayujie/chatgpt-on-wechat/commit/7c67513))
|
||||
- **MiniMax パラメータ**:MiniMax モデルの `max_tokens` 制限を追加 ([1767413](https://github.com/zhayujie/chatgpt-on-wechat/commit/1767413))
|
||||
- **.gitignore 更新**:Python ディレクトリの無視ルールを追加 ([#2683](https://github.com/zhayujie/chatgpt-on-wechat/pull/2683)) Thanks [@pelioo](https://github.com/pelioo)
|
||||
- **bot_type 設定**:Agent モードでの `bot_type` 設定の受け渡し問題を修正 ([#2691](https://github.com/zhayujie/CowAgent/pull/2691)) Thanks [@Weikjssss](https://github.com/Weikjssss)
|
||||
- **bot_type 優先順位**:Agent モードでの `bot_type` の解析優先順位を調整 ([#2692](https://github.com/zhayujie/CowAgent/pull/2692)) Thanks [@6vision](https://github.com/6vision)
|
||||
- **智譜モデル設定**:智譜の `bot_type` 命名、Web コンソールの永続化、正規表現エスケープの問題を修正 ([#2693](https://github.com/zhayujie/CowAgent/pull/2693)) Thanks [@6vision](https://github.com/6vision)
|
||||
- **OpenAI 互換レイヤー**:`openai_compat` レイヤーによる統一エラー処理 ([#2688](https://github.com/zhayujie/CowAgent/pull/2688)) Thanks [@JasonOA888](https://github.com/JasonOA888)
|
||||
- **OpenAI 互換移行**:全モデル Bot の `openai_compat` 移行を完了 ([#2689](https://github.com/zhayujie/CowAgent/pull/2689))
|
||||
- **Gemini ツール呼び出し**:Gemini モデルのツール呼び出しマッチング問題を修正 ([eda82ba](https://github.com/zhayujie/CowAgent/commit/eda82ba))
|
||||
- **セッション並行処理**:セッション並行シナリオでの競合条件の問題を修正 ([9879878](https://github.com/zhayujie/CowAgent/commit/9879878))
|
||||
- **履歴メッセージの復元**:履歴セッションメッセージの不完全な問題を修正。user/assistant のテキストメッセージのみを復元し、ツール呼び出しを除外 ([b788a3d](https://github.com/zhayujie/CowAgent/commit/b788a3d), [a33ce97](https://github.com/zhayujie/CowAgent/commit/a33ce97))
|
||||
- **飛書グループチャット**:飛書グループチャットシナリオでの `bot_name` 依存を削除 ([b641bff](https://github.com/zhayujie/CowAgent/commit/b641bff))
|
||||
- **Safari 互換性**:Safari ブラウザでの IME Enter キーによるメッセージ誤送信の問題を修正 ([0687916](https://github.com/zhayujie/CowAgent/commit/0687916))
|
||||
- **Windows 互換性**:Windows での bash スタイル `$VAR` 環境変数を `%VAR%` に変換する問題を修正 ([7c67513](https://github.com/zhayujie/CowAgent/commit/7c67513))
|
||||
- **MiniMax パラメータ**:MiniMax モデルの `max_tokens` 制限を追加 ([1767413](https://github.com/zhayujie/CowAgent/commit/1767413))
|
||||
- **.gitignore 更新**:Python ディレクトリの無視ルールを追加 ([#2683](https://github.com/zhayujie/CowAgent/pull/2683)) Thanks [@pelioo](https://github.com/pelioo)
|
||||
- **AGENT.md の能動的進化**:システムプロンプトでの AGENT.md 更新ガイダンスを最適化。受動的な「ユーザーが変更した時に更新」から、会話中の性格やスタイルの変化を能動的に検出して自動更新するように改善
|
||||
|
||||
## 📦 アップグレード方法
|
||||
|
||||
ソースコードデプロイの場合は `./run.sh update` でワンクリックアップグレードできます。または手動でコードをプルして再起動してください。詳細は [アップデートドキュメント](https://docs.cowagent.ai/guide/upgrade) を参照。
|
||||
|
||||
**リリース日**:2026.03.18 | [Full Changelog](https://github.com/zhayujie/chatgpt-on-wechat/compare/2.0.2...master)
|
||||
**リリース日**:2026.03.18 | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.2...master)
|
||||
|
||||
@@ -16,40 +16,40 @@ description: CowAgent 2.0.4 - 個人WeChat チャネルの追加、新モデル
|
||||
|
||||
接続ドキュメント:[WeChat 接続](https://docs.cowagent.ai/channels/weixin)。
|
||||
|
||||
関連コミット:[ce89869](https://github.com/zhayujie/chatgpt-on-wechat/commit/ce89869), [a483ec0](https://github.com/zhayujie/chatgpt-on-wechat/commit/a483ec0), [c1421e0](https://github.com/zhayujie/chatgpt-on-wechat/commit/c1421e0)
|
||||
関連コミット:[ce89869](https://github.com/zhayujie/CowAgent/commit/ce89869), [a483ec0](https://github.com/zhayujie/CowAgent/commit/a483ec0), [c1421e0](https://github.com/zhayujie/CowAgent/commit/c1421e0)
|
||||
|
||||
## 🤖 新規モデル
|
||||
|
||||
- **MiniMax-M2.7**:MiniMax-M2.7 モデルのサポートを追加
|
||||
- **GLM-5-Turbo**:智譜 glm-5-turbo モデルのサポートを追加
|
||||
|
||||
関連コミット:[9192f6f](https://github.com/zhayujie/chatgpt-on-wechat/commit/9192f6f)
|
||||
関連コミット:[9192f6f](https://github.com/zhayujie/CowAgent/commit/9192f6f)
|
||||
|
||||
## 🔧 スクリプトリファクタリング
|
||||
|
||||
- **run.sh リファクタリング**:共通ロジックを抽出し、大量の重複コードを削除。スクリプトの行数を 600+ 行から 177 行に圧縮 ([49d8707](https://github.com/zhayujie/chatgpt-on-wechat/commit/49d8707))
|
||||
- **実行権限**:`run.sh` ファイルの権限問題を修正 ([652156e](https://github.com/zhayujie/chatgpt-on-wechat/commit/652156e))
|
||||
- **run.sh リファクタリング**:共通ロジックを抽出し、大量の重複コードを削除。スクリプトの行数を 600+ 行から 177 行に圧縮 ([49d8707](https://github.com/zhayujie/CowAgent/commit/49d8707))
|
||||
- **実行権限**:`run.sh` ファイルの権限問題を修正 ([652156e](https://github.com/zhayujie/CowAgent/commit/652156e))
|
||||
|
||||
## ⚡ 最適化
|
||||
|
||||
- **リクエストヘッダー統一**:Agent の各サービス(Chat、Embedding、Vision、WebSearch 等)の外部リクエストに統一的な識別ヘッダーを追加 ([b4e711f](https://github.com/zhayujie/chatgpt-on-wechat/commit/b4e711f))
|
||||
- **メッセージ自動修復**:メッセージプロトコルのフォールトトレランスを強化し、フォーマット異常なメッセージシーケンスを自動修復 ([b8b57e3](https://github.com/zhayujie/chatgpt-on-wechat/commit/b8b57e3))
|
||||
- **リクエストヘッダー統一**:Agent の各サービス(Chat、Embedding、Vision、WebSearch 等)の外部リクエストに統一的な識別ヘッダーを追加 ([b4e711f](https://github.com/zhayujie/CowAgent/commit/b4e711f))
|
||||
- **メッセージ自動修復**:メッセージプロトコルのフォールトトレランスを強化し、フォーマット異常なメッセージシーケンスを自動修復 ([b8b57e3](https://github.com/zhayujie/CowAgent/commit/b8b57e3))
|
||||
|
||||
## 🌍 日本語ドキュメント
|
||||
|
||||
完全な日本語ドキュメントを追加しました。入門ガイド、チャネル接続、モデル設定などの主要セクションをカバーしています。Thanks [@Ikko Ashimine](https://github.com/ikoamu)
|
||||
|
||||
関連コミット:[5487c0b](https://github.com/zhayujie/chatgpt-on-wechat/commit/5487c0b)
|
||||
関連コミット:[5487c0b](https://github.com/zhayujie/CowAgent/commit/5487c0b)
|
||||
|
||||
## 🐛 バグ修正
|
||||
|
||||
- **企業微信ボット互換性**:旧バージョンの `websocket-client` との互換性問題を修正し、統一的な WebSocket 互換レイヤーを追加 ([bc7f627](https://github.com/zhayujie/chatgpt-on-wechat/commit/bc7f627))
|
||||
- **run.sh PID 取得**:`run.sh` でのプロセス PID 取得エラーを修正 ([9febb07](https://github.com/zhayujie/chatgpt-on-wechat/commit/9febb07))
|
||||
- **飛書エンコーディング**:飛書チャネルのメッセージとログのエンコーディング問題を修正 ([7d0e156](https://github.com/zhayujie/chatgpt-on-wechat/commit/7d0e156))
|
||||
- **飛書設定**:`run.sh` での `feishu_bot_name` への冗長な依存を削除 ([1b5be1b](https://github.com/zhayujie/chatgpt-on-wechat/commit/1b5be1b))
|
||||
- **企業微信ボット互換性**:旧バージョンの `websocket-client` との互換性問題を修正し、統一的な WebSocket 互換レイヤーを追加 ([bc7f627](https://github.com/zhayujie/CowAgent/commit/bc7f627))
|
||||
- **run.sh PID 取得**:`run.sh` でのプロセス PID 取得エラーを修正 ([9febb07](https://github.com/zhayujie/CowAgent/commit/9febb07))
|
||||
- **飛書エンコーディング**:飛書チャネルのメッセージとログのエンコーディング問題を修正 ([7d0e156](https://github.com/zhayujie/CowAgent/commit/7d0e156))
|
||||
- **飛書設定**:`run.sh` での `feishu_bot_name` への冗長な依存を削除 ([1b5be1b](https://github.com/zhayujie/CowAgent/commit/1b5be1b))
|
||||
|
||||
## 📦 アップグレード方法
|
||||
|
||||
ソースコードデプロイの場合は `./run.sh update` でワンクリックアップグレードできます。または手動でコードをプルして再起動してください。詳細は [アップデートドキュメント](https://docs.cowagent.ai/guide/upgrade) を参照。
|
||||
|
||||
**リリース日**:2026.03.22 | [Full Changelog](https://github.com/zhayujie/chatgpt-on-wechat/compare/2.0.3...master)
|
||||
**リリース日**:2026.03.22 | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.3...master)
|
||||
|
||||
@@ -57,21 +57,21 @@ description: CowAgent 2.0.5 - Cow CLI、Skill Hub オープンソース、ブラ
|
||||
|
||||
ドキュメント:[企業微信 Bot](https://docs.cowagent.ai/ja/channels/wecom-bot)
|
||||
|
||||
PR:[#2735](https://github.com/zhayujie/chatgpt-on-wechat/pull/2735)。Thanks [@WecomTeam](https://github.com/WecomTeam)
|
||||
PR:[#2735](https://github.com/zhayujie/CowAgent/pull/2735)。Thanks [@WecomTeam](https://github.com/WecomTeam)
|
||||
|
||||
## 🐛 その他の改善と修正
|
||||
|
||||
- **DeepSeek モジュール**:独立 DeepSeek Bot、`deepseek_api_key` 専用設定対応([#2719](https://github.com/zhayujie/chatgpt-on-wechat/pull/2719))。Thanks [@6vision](https://github.com/6vision)
|
||||
- **Web コンソール**:スラッシュコマンドメニュー、入力履歴、新モデル選択肢、モバイル最適化([#2731](https://github.com/zhayujie/chatgpt-on-wechat/pull/2731))。Thanks [@zkjqd](https://github.com/zkjqd)
|
||||
- **コンテキスト**:トリミング後のコンテキスト喪失を修正([393f0c0](https://github.com/zhayujie/chatgpt-on-wechat/commit/393f0c0))
|
||||
- **システムプロンプト**:毎ターン再構築されない問題を修正([13f5fde](https://github.com/zhayujie/chatgpt-on-wechat/commit/13f5fde))
|
||||
- **Gemini**:GoogleGeminiBot の model 属性欠落を修正([#2716](https://github.com/zhayujie/chatgpt-on-wechat/pull/2716))。Thanks [@cowagent](https://github.com/cowagent)
|
||||
- **WeChat チャネル**:ファイル送信失敗・ファイル名消失の修正([6d9b7ba](https://github.com/zhayujie/chatgpt-on-wechat/commit/6d9b7ba)、[45faa9c](https://github.com/zhayujie/chatgpt-on-wechat/commit/45faa9c))
|
||||
- **Docker**:ボリューム権限修正、イメージサイズ削減([3eb8348](https://github.com/zhayujie/chatgpt-on-wechat/commit/3eb8348)、[4470d4c](https://github.com/zhayujie/chatgpt-on-wechat/commit/4470d4c))
|
||||
- **DeepSeek モジュール**:独立 DeepSeek Bot、`deepseek_api_key` 専用設定対応([#2719](https://github.com/zhayujie/CowAgent/pull/2719))。Thanks [@6vision](https://github.com/6vision)
|
||||
- **Web コンソール**:スラッシュコマンドメニュー、入力履歴、新モデル選択肢、モバイル最適化([#2731](https://github.com/zhayujie/CowAgent/pull/2731))。Thanks [@zkjqd](https://github.com/zkjqd)
|
||||
- **コンテキスト**:トリミング後のコンテキスト喪失を修正([393f0c0](https://github.com/zhayujie/CowAgent/commit/393f0c0))
|
||||
- **システムプロンプト**:毎ターン再構築されない問題を修正([13f5fde](https://github.com/zhayujie/CowAgent/commit/13f5fde))
|
||||
- **Gemini**:GoogleGeminiBot の model 属性欠落を修正([#2716](https://github.com/zhayujie/CowAgent/pull/2716))。Thanks [@cowagent](https://github.com/cowagent)
|
||||
- **WeChat チャネル**:ファイル送信失敗・ファイル名消失の修正([6d9b7ba](https://github.com/zhayujie/CowAgent/commit/6d9b7ba)、[45faa9c](https://github.com/zhayujie/CowAgent/commit/45faa9c))
|
||||
- **Docker**:ボリューム権限修正、イメージサイズ削減([3eb8348](https://github.com/zhayujie/CowAgent/commit/3eb8348)、[4470d4c](https://github.com/zhayujie/CowAgent/commit/4470d4c))
|
||||
- **セキュリティ**:Memory Content パストラバーサルリスクを修正。Thanks [@August829](https://github.com/August829)
|
||||
|
||||
## 📦 アップグレード
|
||||
|
||||
`cow update` または `./run.sh update` でアップグレード、またはコードを手動で pull して再起動。詳細は[アップグレードガイド](https://docs.cowagent.ai/ja/guide/upgrade)を参照。
|
||||
|
||||
**リリース日**:2026.04.01 | [Full Changelog](https://github.com/zhayujie/chatgpt-on-wechat/compare/2.0.4...master)
|
||||
**リリース日**:2026.04.01 | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.4...master)
|
||||
|
||||
@@ -54,5 +54,5 @@ Detailed instructions...
|
||||
| `metadata.always` | 常に読み込む(デフォルトは false) |
|
||||
|
||||
<Tip>
|
||||
詳細は [Skill Creator のドキュメント](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/skills/skill-creator/SKILL.md)をご覧ください。
|
||||
詳細は [Skill Creator のドキュメント](https://github.com/zhayujie/CowAgent/blob/master/skills/skill-creator/SKILL.md)をご覧ください。
|
||||
</Tip>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
---
|
||||
title: memory - メモリ
|
||||
description: 長期メモリの検索と読み取り
|
||||
title: memory - メモリ & ナレッジ
|
||||
description: 長期メモリとナレッジベースファイルの検索・読み取り
|
||||
---
|
||||
|
||||
メモリToolには `memory_search`(メモリ検索)と `memory_get`(メモリファイル読み取り)の2つのサブToolがあります。
|
||||
メモリToolには `memory_search`(メモリ検索)と `memory_get`(メモリまたはナレッジファイル読み取り)の2つのサブToolがあります。
|
||||
|
||||
[ナレッジベース](/ja/knowledge) 機能が有効な場合、両ツールとも `knowledge/` ディレクトリのファイルへのアクセスもサポートします。
|
||||
|
||||
## 依存関係
|
||||
|
||||
@@ -11,7 +13,7 @@ description: 長期メモリの検索と読み取り
|
||||
|
||||
## memory_search
|
||||
|
||||
キーワードとベクトルのハイブリッド検索で過去のメモリを検索します。
|
||||
キーワードとベクトルのハイブリッド検索で過去のメモリとナレッジベースの内容を検索します。
|
||||
|
||||
| パラメータ | 型 | 必須 | 説明 |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -19,11 +21,11 @@ description: 長期メモリの検索と読み取り
|
||||
|
||||
## memory_get
|
||||
|
||||
特定のメモリファイルの内容を読み取ります。
|
||||
特定のメモリファイルまたはナレッジファイルの内容を読み取ります。
|
||||
|
||||
| パラメータ | 型 | 必須 | 説明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `path` | string | はい | メモリファイルの相対パス(例:`MEMORY.md`、`memory/2026-01-01.md`) |
|
||||
| `path` | string | はい | ファイルの相対パス(例:`MEMORY.md`、`memory/2026-01-01.md`、`knowledge/concepts/rag.md`) |
|
||||
| `start_line` | integer | いいえ | 開始行番号 |
|
||||
| `end_line` | integer | いいえ | 終了行番号 |
|
||||
|
||||
@@ -34,3 +36,8 @@ Agentは以下のシナリオでメモリToolを自動的に呼び出します
|
||||
- ユーザーが重要な情報を共有した場合 → メモリに保存
|
||||
- 過去のコンテキストが必要な場合 → 関連するメモリを検索
|
||||
- 会話が一定の長さに達した場合 → 要約を抽出して保存
|
||||
- 専門知識について議論する場合 → ナレッジベースから関連ページを検索
|
||||
|
||||
<Note>
|
||||
設定で `knowledge` が `false` に設定されている場合、ツールの説明と検索範囲は自動的にメモリファイルのみに調整されます。
|
||||
</Note>
|
||||
|
||||
77
docs/knowledge/index.mdx
Normal file
77
docs/knowledge/index.mdx
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
title: 个人知识库
|
||||
description: CowAgent 的个人知识库系统 — 结构化知识沉淀、自动整理与知识图谱
|
||||
---
|
||||
|
||||
个人知识库是 Agent 的长期结构化知识存储,保存在工作空间的 `knowledge/` 目录下。与按时间线组织的记忆不同,知识库以主题为维度,将用户分享的文章、对话中的洞察、学习材料等整理为互相关联的 Markdown 页面,形成可持续增长的知识网络。
|
||||
|
||||
## 核心概念
|
||||
|
||||
### 知识 vs 记忆
|
||||
|
||||
| 维度 | 知识库(knowledge/) | 长期记忆(memory/) |
|
||||
| --- | --- | --- |
|
||||
| 组织方式 | 按主题分类、互相关联 | 按时间线、日期文件 |
|
||||
| 写入方式 | Agent 主动整理结构化内容 | 上下文裁剪时自动摘要 |
|
||||
| 内容特点 | 提炼后的结构化知识 | 原始对话摘要 |
|
||||
| 典型用途 | 学习笔记、技术文档、项目知识 | 对话历史、事件记录 |
|
||||
|
||||
### 目录结构
|
||||
|
||||
```
|
||||
~/cow/knowledge/
|
||||
├── index.md # 知识索引,所有页面的入口
|
||||
├── log.md # 变更日志,记录每次写入
|
||||
├── concepts/ # 概念类知识
|
||||
│ └── machine-learning.md
|
||||
├── entities/ # 实体类知识(人物、组织、工具)
|
||||
│ └── openai.md
|
||||
└── sources/ # 来源类知识(文章、论文)
|
||||
└── llm-wiki.md
|
||||
```
|
||||
|
||||
目录结构是灵活的 — Agent 会根据实际内容自动创建合适的分类目录。用户也可以通过对话自定义目录组织方式。
|
||||
|
||||
## 自动整理
|
||||
|
||||
知识库的写入是 Agent 的自主行为,在以下场景中触发:
|
||||
|
||||
- **用户分享文章或文档** — Agent 自动提取关键信息,创建结构化知识页面
|
||||
- **对话产生有价值的结论** — Agent 将洞察整理为知识页面,并与已有知识建立关联
|
||||
- **用户主动要求整理** — 用户可以通过对话指导 Agent 组织和更新知识
|
||||
|
||||
每个知识页面都包含与其他页面的交叉引用链接,逐步构建起一个知识图谱。
|
||||
|
||||
## 知识检索
|
||||
|
||||
Agent 在对话中可以通过以下方式检索知识:
|
||||
|
||||
- **索引查阅** — 通过 `knowledge/index.md` 快速定位相关知识页面
|
||||
- **语义搜索** — 通过 `memory_search` 工具对知识库内容进行语义检索
|
||||
- **直接读取** — 通过 `memory_get` 工具读取特定知识文件
|
||||
|
||||
## Web 控制台
|
||||
|
||||
Web 控制台提供了专用的「知识」模块,支持:
|
||||
|
||||
- **文档浏览** — 树状目录结构,可搜索、可折叠,点击查看文档内容
|
||||
- **知识图谱** — 基于 D3.js 的力导向图,可视化展示知识之间的关联关系
|
||||
- **对话联动** — Agent 回复中引用的知识文档链接可直接点击跳转查看
|
||||
|
||||
## CLI 命令
|
||||
|
||||
通过 `/knowledge` 命令管理知识库:
|
||||
|
||||
| 命令 | 说明 |
|
||||
| --- | --- |
|
||||
| `/knowledge` | 显示知识库统计信息 |
|
||||
| `/knowledge list` | 以树状结构显示文件目录 |
|
||||
| `/knowledge on` | 开启知识库功能 |
|
||||
| `/knowledge off` | 关闭知识库功能 |
|
||||
|
||||
## 相关配置
|
||||
|
||||
| 参数 | 说明 | 默认值 |
|
||||
| --- | --- | --- |
|
||||
| `knowledge` | 是否启用个人知识库功能 | `true` |
|
||||
| `agent_workspace` | 工作空间路径,知识库存储在此目录的 `knowledge/` 子目录下 | `~/cow` |
|
||||
@@ -57,5 +57,5 @@ CowAgent 支持国内外主流厂商的大语言模型,模型接口实现在
|
||||
|
||||
|
||||
<Tip>
|
||||
全部模型名称可参考项目 [`common/const.py`](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/common/const.py) 文件。
|
||||
全部模型名称可参考项目 [`common/const.py`](https://github.com/zhayujie/CowAgent/blob/master/common/const.py) 文件。
|
||||
</Tip>
|
||||
|
||||
@@ -25,4 +25,4 @@ description: CowAgent 版本更新历史
|
||||
| 1.5.0 | 2023.11.10 | gpt-4-turbo、dall-e-3、tts 多模态 |
|
||||
| 1.0.0 | 2022.12.12 | 项目创建,首次接入 ChatGPT 模型 |
|
||||
|
||||
更多历史版本请查看 [GitHub Releases](https://github.com/zhayujie/chatgpt-on-wechat/releases)。
|
||||
更多历史版本请查看 [GitHub Releases](https://github.com/zhayujie/CowAgent/releases)。
|
||||
|
||||
@@ -5,7 +5,7 @@ description: CowAgent 2.0 - 从聊天机器人到超级智能助理的全面升
|
||||
|
||||
CowAgent 2.0 实现了从聊天机器人到**超级智能助理**的全面升级!现在它能够主动思考和规划任务、拥有长期记忆、操作计算机和外部资源、创造和执行技能,真正理解你并和你一起成长。
|
||||
|
||||
**发布日期**:2026.02.03 | [GitHub Release](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.0)
|
||||
**发布日期**:2026.02.03 | [GitHub Release](https://github.com/zhayujie/CowAgent/releases/tag/2.0.0)
|
||||
|
||||
## 重点更新
|
||||
|
||||
@@ -102,4 +102,4 @@ Agent 根据任务需求智能选择和调用工具,完成各类复杂操作
|
||||
|
||||
## 参与共建
|
||||
|
||||
2.0 版本后,项目将持续升级 Agent 能力、拓展接入渠道、内置工具、技能系统,降低模型成本和提升安全性。欢迎 [提出反馈](https://github.com/zhayujie/chatgpt-on-wechat/issues) 和 [贡献代码](https://github.com/zhayujie/chatgpt-on-wechat/pulls)。
|
||||
2.0 版本后,项目将持续升级 Agent 能力、拓展接入渠道、内置工具、技能系统,降低模型成本和提升安全性。欢迎 [提出反馈](https://github.com/zhayujie/CowAgent/issues) 和 [贡献代码](https://github.com/zhayujie/CowAgent/pulls)。
|
||||
|
||||
@@ -3,34 +3,34 @@ title: v2.0.1
|
||||
description: CowAgent 2.0.1 - 内置 Web Search、智能上下文管理、多项修复
|
||||
---
|
||||
|
||||
**发布日期**:2026.02 | [GitHub Release](https://github.com/zhayujie/chatgpt-on-wechat/releases/tag/2.0.1) | [Full Changelog](https://github.com/zhayujie/chatgpt-on-wechat/compare/2.0.0..2.0.1)
|
||||
**发布日期**:2026.02 | [GitHub Release](https://github.com/zhayujie/CowAgent/releases/tag/2.0.1) | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.0..2.0.1)
|
||||
|
||||
## 新特性
|
||||
|
||||
- **内置 Web Search 工具**:将网络搜索作为 Agent 内置工具集成,降低决策成本 ([4f0ea5d](https://github.com/zhayujie/chatgpt-on-wechat/commit/4f0ea5d7568d61db91ff69c91c429e785fd1b1c2))
|
||||
- **Claude Opus 4.6 模型支持**:新增对 Claude Opus 4.6 模型的支持 ([#2661](https://github.com/zhayujie/chatgpt-on-wechat/pull/2661))
|
||||
- **企业微信图片消息识别**:支持企业微信渠道的图片消息识别功能 ([#2667](https://github.com/zhayujie/chatgpt-on-wechat/pull/2667))
|
||||
- **内置 Web Search 工具**:将网络搜索作为 Agent 内置工具集成,降低决策成本 ([4f0ea5d](https://github.com/zhayujie/CowAgent/commit/4f0ea5d7568d61db91ff69c91c429e785fd1b1c2))
|
||||
- **Claude Opus 4.6 模型支持**:新增对 Claude Opus 4.6 模型的支持 ([#2661](https://github.com/zhayujie/CowAgent/pull/2661))
|
||||
- **企业微信图片消息识别**:支持企业微信渠道的图片消息识别功能 ([#2667](https://github.com/zhayujie/CowAgent/pull/2667))
|
||||
|
||||
## 优化
|
||||
|
||||
- **智能上下文管理**:解决聊天上下文溢出问题,新增智能上下文裁剪策略,防止 token 超限 ([cea7fb7](https://github.com/zhayujie/chatgpt-on-wechat/commit/cea7fb7490c53454602bf05955a0e9f059bcf0fd), [8acf2db](https://github.com/zhayujie/chatgpt-on-wechat/commit/8acf2dbdfe713b84ad74b761b7f86674b1c1904d)) [#2663](https://github.com/zhayujie/chatgpt-on-wechat/issues/2663)
|
||||
- **运行时信息动态更新**:通过动态函数方案实现系统提示词中时间戳等运行时信息的自动更新 ([#2655](https://github.com/zhayujie/chatgpt-on-wechat/pull/2655), [#2657](https://github.com/zhayujie/chatgpt-on-wechat/pull/2657))
|
||||
- **Skill 提示词优化**:改进 Skill 系统提示词生成逻辑,简化工具描述,提升 Agent 表现 ([6c21833](https://github.com/zhayujie/chatgpt-on-wechat/commit/6c218331b1f1208ea8be6bf226936d3b556ade3e))
|
||||
- **智谱 AI 自定义 API Base URL**:支持智谱 AI 配置自定义 API Base URL ([#2660](https://github.com/zhayujie/chatgpt-on-wechat/pull/2660))
|
||||
- **启动脚本优化**:改进 `run.sh` 脚本的交互体验和配置流程 ([#2656](https://github.com/zhayujie/chatgpt-on-wechat/pull/2656))
|
||||
- **决策轮次日志**:新增 Agent 决策轮次的日志记录,便于调试 ([cb303e6](https://github.com/zhayujie/chatgpt-on-wechat/commit/cb303e6109c50c8dfef1f5e6c1ec47223bf3cd11))
|
||||
- **智能上下文管理**:解决聊天上下文溢出问题,新增智能上下文裁剪策略,防止 token 超限 ([cea7fb7](https://github.com/zhayujie/CowAgent/commit/cea7fb7490c53454602bf05955a0e9f059bcf0fd), [8acf2db](https://github.com/zhayujie/CowAgent/commit/8acf2dbdfe713b84ad74b761b7f86674b1c1904d)) [#2663](https://github.com/zhayujie/CowAgent/issues/2663)
|
||||
- **运行时信息动态更新**:通过动态函数方案实现系统提示词中时间戳等运行时信息的自动更新 ([#2655](https://github.com/zhayujie/CowAgent/pull/2655), [#2657](https://github.com/zhayujie/CowAgent/pull/2657))
|
||||
- **Skill 提示词优化**:改进 Skill 系统提示词生成逻辑,简化工具描述,提升 Agent 表现 ([6c21833](https://github.com/zhayujie/CowAgent/commit/6c218331b1f1208ea8be6bf226936d3b556ade3e))
|
||||
- **智谱 AI 自定义 API Base URL**:支持智谱 AI 配置自定义 API Base URL ([#2660](https://github.com/zhayujie/CowAgent/pull/2660))
|
||||
- **启动脚本优化**:改进 `run.sh` 脚本的交互体验和配置流程 ([#2656](https://github.com/zhayujie/CowAgent/pull/2656))
|
||||
- **决策轮次日志**:新增 Agent 决策轮次的日志记录,便于调试 ([cb303e6](https://github.com/zhayujie/CowAgent/commit/cb303e6109c50c8dfef1f5e6c1ec47223bf3cd11))
|
||||
|
||||
## 问题修复
|
||||
|
||||
- **定时任务记忆丢失**:修复 Scheduler 调度器导致的记忆丢失问题 ([a77a874](https://github.com/zhayujie/chatgpt-on-wechat/commit/a77a8741b500a408c6f5c8868856fb4b018fe9db))
|
||||
- **空工具调用与超长结果**:修复空 tool calls 及过长工具返回结果的异常处理 ([0542700](https://github.com/zhayujie/chatgpt-on-wechat/commit/0542700f9091ebb08c1a56103b0f0f45f24aa621))
|
||||
- **OpenAI Function Call**:修复 OpenAI 模型的 function call 调用兼容性问题 ([158c87a](https://github.com/zhayujie/chatgpt-on-wechat/commit/158c87ab8b05bae054cc1b4eacdbb64fc1062ba9))
|
||||
- **Claude 工具名字段**:移除 Claude 模型响应中多余的 tool name 字段 ([eec10cb](https://github.com/zhayujie/chatgpt-on-wechat/commit/eec10cb5db6a3d5bc12ef606606532237d2c5f6e))
|
||||
- **MiniMax 推理优化**:优化 MiniMax 模型 reasoning content 处理,隐藏思考过程输出 ([c72cda3](https://github.com/zhayujie/chatgpt-on-wechat/commit/c72cda33864bd1542012ee6e0a8bd8c6c88cb5ed), [72b1cac](https://github.com/zhayujie/chatgpt-on-wechat/commit/72b1cacea1ba0d1f3dedacbab2e088e98fd7e172))
|
||||
- **智谱 AI 思考过程**:隐藏智谱 AI 模型的思考过程展示 ([72b1cac](https://github.com/zhayujie/chatgpt-on-wechat/commit/72b1cacea1ba0d1f3dedacbab2e088e98fd7e172))
|
||||
- **飞书连接与证书**:修复飞书渠道的 SSL 证书错误和连接异常问题 ([229b14b](https://github.com/zhayujie/chatgpt-on-wechat/commit/229b14b6fcabe7123d53cab1dea39f38dab26d6d), [8674421](https://github.com/zhayujie/chatgpt-on-wechat/commit/867442155e7f095b4f38b0856f8c1d8312b5fcf7))
|
||||
- **model_type 类型校验**:修复非字符串 `model_type` 导致的 `AttributeError` ([#2666](https://github.com/zhayujie/chatgpt-on-wechat/pull/2666))
|
||||
- **定时任务记忆丢失**:修复 Scheduler 调度器导致的记忆丢失问题 ([a77a874](https://github.com/zhayujie/CowAgent/commit/a77a8741b500a408c6f5c8868856fb4b018fe9db))
|
||||
- **空工具调用与超长结果**:修复空 tool calls 及过长工具返回结果的异常处理 ([0542700](https://github.com/zhayujie/CowAgent/commit/0542700f9091ebb08c1a56103b0f0f45f24aa621))
|
||||
- **OpenAI Function Call**:修复 OpenAI 模型的 function call 调用兼容性问题 ([158c87a](https://github.com/zhayujie/CowAgent/commit/158c87ab8b05bae054cc1b4eacdbb64fc1062ba9))
|
||||
- **Claude 工具名字段**:移除 Claude 模型响应中多余的 tool name 字段 ([eec10cb](https://github.com/zhayujie/CowAgent/commit/eec10cb5db6a3d5bc12ef606606532237d2c5f6e))
|
||||
- **MiniMax 推理优化**:优化 MiniMax 模型 reasoning content 处理,隐藏思考过程输出 ([c72cda3](https://github.com/zhayujie/CowAgent/commit/c72cda33864bd1542012ee6e0a8bd8c6c88cb5ed), [72b1cac](https://github.com/zhayujie/CowAgent/commit/72b1cacea1ba0d1f3dedacbab2e088e98fd7e172))
|
||||
- **智谱 AI 思考过程**:隐藏智谱 AI 模型的思考过程展示 ([72b1cac](https://github.com/zhayujie/CowAgent/commit/72b1cacea1ba0d1f3dedacbab2e088e98fd7e172))
|
||||
- **飞书连接与证书**:修复飞书渠道的 SSL 证书错误和连接异常问题 ([229b14b](https://github.com/zhayujie/CowAgent/commit/229b14b6fcabe7123d53cab1dea39f38dab26d6d), [8674421](https://github.com/zhayujie/CowAgent/commit/867442155e7f095b4f38b0856f8c1d8312b5fcf7))
|
||||
- **model_type 类型校验**:修复非字符串 `model_type` 导致的 `AttributeError` ([#2666](https://github.com/zhayujie/CowAgent/pull/2666))
|
||||
|
||||
## 平台兼容
|
||||
|
||||
- **Windows 兼容性适配**:修复 Windows 平台下路径处理、文件编码及 `os.getuid()` 不可用等问题,涉及多个工具模块 ([051ffd7](https://github.com/zhayujie/chatgpt-on-wechat/commit/051ffd78a372f71a967fd3259e37fe19131f83cf), [5264f7c](https://github.com/zhayujie/chatgpt-on-wechat/commit/5264f7ce18360ee4db5dcb4ebe67307977d40014))
|
||||
- **Windows 兼容性适配**:修复 Windows 平台下路径处理、文件编码及 `os.getuid()` 不可用等问题,涉及多个工具模块 ([051ffd7](https://github.com/zhayujie/CowAgent/commit/051ffd78a372f71a967fd3259e37fe19131f83cf), [5264f7c](https://github.com/zhayujie/CowAgent/commit/5264f7ce18360ee4db5dcb4ebe67307977d40014))
|
||||
|
||||
@@ -51,7 +51,7 @@ description: CowAgent 2.0.2 - Web 控制台升级、多通道同时运行、会
|
||||
|
||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173514.png" />
|
||||
|
||||
相关提交:[f1a1413](https://github.com/zhayujie/chatgpt-on-wechat/commit/f1a1413), [c0702c8](https://github.com/zhayujie/chatgpt-on-wechat/commit/c0702c8), [394853c](https://github.com/zhayujie/chatgpt-on-wechat/commit/394853c), [1c71c4e](https://github.com/zhayujie/chatgpt-on-wechat/commit/1c71c4e), [5e3eccb](https://github.com/zhayujie/chatgpt-on-wechat/commit/5e3eccb), [e1dc037](https://github.com/zhayujie/chatgpt-on-wechat/commit/e1dc037), [5edbf4c](https://github.com/zhayujie/chatgpt-on-wechat/commit/5edbf4c), [7d258b5](https://github.com/zhayujie/chatgpt-on-wechat/commit/7d258b5)
|
||||
相关提交:[f1a1413](https://github.com/zhayujie/CowAgent/commit/f1a1413), [c0702c8](https://github.com/zhayujie/CowAgent/commit/c0702c8), [394853c](https://github.com/zhayujie/CowAgent/commit/394853c), [1c71c4e](https://github.com/zhayujie/CowAgent/commit/1c71c4e), [5e3eccb](https://github.com/zhayujie/CowAgent/commit/5e3eccb), [e1dc037](https://github.com/zhayujie/CowAgent/commit/e1dc037), [5edbf4c](https://github.com/zhayujie/CowAgent/commit/5edbf4c), [7d258b5](https://github.com/zhayujie/CowAgent/commit/7d258b5)
|
||||
|
||||
### 🔀 多通道同时运行
|
||||
|
||||
@@ -65,24 +65,24 @@ description: CowAgent 2.0.2 - Web 控制台升级、多通道同时运行、会
|
||||
}
|
||||
```
|
||||
|
||||
相关提交:[4694594](https://github.com/zhayujie/chatgpt-on-wechat/commit/4694594), [7cce224](https://github.com/zhayujie/chatgpt-on-wechat/commit/7cce224), [7d258b5](https://github.com/zhayujie/chatgpt-on-wechat/commit/7d258b5), [c9adddb](https://github.com/zhayujie/chatgpt-on-wechat/commit/c9adddb)
|
||||
相关提交:[4694594](https://github.com/zhayujie/CowAgent/commit/4694594), [7cce224](https://github.com/zhayujie/CowAgent/commit/7cce224), [7d258b5](https://github.com/zhayujie/CowAgent/commit/7d258b5), [c9adddb](https://github.com/zhayujie/CowAgent/commit/c9adddb)
|
||||
|
||||
### 💾 会话持久化
|
||||
|
||||
会话历史支持持久化存储至本地 SQLite 数据库,服务重启后会话上下文自动恢复,不再丢失。Web 控制台中的历史对话记录也会同步恢复展示。
|
||||
|
||||
相关提交:[29bfbec](https://github.com/zhayujie/chatgpt-on-wechat/commit/29bfbec), [9917552](https://github.com/zhayujie/chatgpt-on-wechat/commit/9917552), [925d728](https://github.com/zhayujie/chatgpt-on-wechat/commit/925d728)
|
||||
相关提交:[29bfbec](https://github.com/zhayujie/CowAgent/commit/29bfbec), [9917552](https://github.com/zhayujie/CowAgent/commit/9917552), [925d728](https://github.com/zhayujie/CowAgent/commit/925d728)
|
||||
|
||||
### 🤖 新增模型
|
||||
|
||||
- **Gemini 3.1 Pro Preview**:新增 `gemini-3.1-pro-preview` 模型支持 ([52d7cad](https://github.com/zhayujie/chatgpt-on-wechat/commit/52d7cad))
|
||||
- **Claude 4.6 Sonnet**:新增 `claude-4.6-sonnet` 模型支持 ([52d7cad](https://github.com/zhayujie/chatgpt-on-wechat/commit/52d7cad))
|
||||
- **Qwen3.5 Plus**:新增 `qwen3.5-plus` 模型支持 ([e59a289](https://github.com/zhayujie/chatgpt-on-wechat/commit/e59a289))
|
||||
- **MiniMax M2.5**:新增 `Minimax-M2.5` 模型支持 ([48db538](https://github.com/zhayujie/chatgpt-on-wechat/commit/48db538))
|
||||
- **GLM-5**:新增 `glm-5` 模型支持 ([48db538](https://github.com/zhayujie/chatgpt-on-wechat/commit/48db538))
|
||||
- **Kimi K2.5**:新增 `kimi-k2.5` 模型支持 ([48db538](https://github.com/zhayujie/chatgpt-on-wechat/commit/48db538))
|
||||
- **Doubao 2.0 Code**:新增 `doubao-2.0-code` 编程专用模型 ([ab28ee5](https://github.com/zhayujie/chatgpt-on-wechat/commit/ab28ee5))
|
||||
- **DashScope 模型**:新增阿里云 DashScope 模型名称支持 ([ce58f23](https://github.com/zhayujie/chatgpt-on-wechat/commit/ce58f23))
|
||||
- **Gemini 3.1 Pro Preview**:新增 `gemini-3.1-pro-preview` 模型支持 ([52d7cad](https://github.com/zhayujie/CowAgent/commit/52d7cad))
|
||||
- **Claude 4.6 Sonnet**:新增 `claude-4.6-sonnet` 模型支持 ([52d7cad](https://github.com/zhayujie/CowAgent/commit/52d7cad))
|
||||
- **Qwen3.5 Plus**:新增 `qwen3.5-plus` 模型支持 ([e59a289](https://github.com/zhayujie/CowAgent/commit/e59a289))
|
||||
- **MiniMax M2.5**:新增 `Minimax-M2.5` 模型支持 ([48db538](https://github.com/zhayujie/CowAgent/commit/48db538))
|
||||
- **GLM-5**:新增 `glm-5` 模型支持 ([48db538](https://github.com/zhayujie/CowAgent/commit/48db538))
|
||||
- **Kimi K2.5**:新增 `kimi-k2.5` 模型支持 ([48db538](https://github.com/zhayujie/CowAgent/commit/48db538))
|
||||
- **Doubao 2.0 Code**:新增 `doubao-2.0-code` 编程专用模型 ([ab28ee5](https://github.com/zhayujie/CowAgent/commit/ab28ee5))
|
||||
- **DashScope 模型**:新增阿里云 DashScope 模型名称支持 ([ce58f23](https://github.com/zhayujie/CowAgent/commit/ce58f23))
|
||||
|
||||
### 🌐 新增官网和文档中心
|
||||
|
||||
@@ -91,8 +91,8 @@ description: CowAgent 2.0.2 - Web 控制台升级、多通道同时运行、会
|
||||
|
||||
### 🐛 问题修复
|
||||
|
||||
- **Gemini 钉钉图片识别**:修复 Gemini 在钉钉通道中无法处理图片标记的问题 ([05a3304](https://github.com/zhayujie/chatgpt-on-wechat/commit/05a3304)) ([#2670](https://github.com/zhayujie/chatgpt-on-wechat/pull/2670)) Thanks [@SgtPepper114](https://github.com/SgtPepper114)
|
||||
- **启动脚本依赖**:修复 `run.sh` 脚本的依赖安装问题 ([b6fc9fa](https://github.com/zhayujie/chatgpt-on-wechat/commit/b6fc9fa))
|
||||
- **裸异常捕获**:将代码中的 `bare except` 替换为 `except Exception`,提升异常处理规范性 ([adca89b](https://github.com/zhayujie/chatgpt-on-wechat/commit/adca89b)) ([#2674](https://github.com/zhayujie/chatgpt-on-wechat/pull/2674)) Thanks [@haosenwang1018](https://github.com/haosenwang1018)
|
||||
- **Gemini 钉钉图片识别**:修复 Gemini 在钉钉通道中无法处理图片标记的问题 ([05a3304](https://github.com/zhayujie/CowAgent/commit/05a3304)) ([#2670](https://github.com/zhayujie/CowAgent/pull/2670)) Thanks [@SgtPepper114](https://github.com/SgtPepper114)
|
||||
- **启动脚本依赖**:修复 `run.sh` 脚本的依赖安装问题 ([b6fc9fa](https://github.com/zhayujie/CowAgent/commit/b6fc9fa))
|
||||
- **裸异常捕获**:将代码中的 `bare except` 替换为 `except Exception`,提升异常处理规范性 ([adca89b](https://github.com/zhayujie/CowAgent/commit/adca89b)) ([#2674](https://github.com/zhayujie/CowAgent/pull/2674)) Thanks [@haosenwang1018](https://github.com/haosenwang1018)
|
||||
|
||||
**发布日期**:2026.02.27 | [Full Changelog](https://github.com/zhayujie/chatgpt-on-wechat/compare/2.0.1...master)
|
||||
**发布日期**:2026.02.27 | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.1...master)
|
||||
|
||||
@@ -11,7 +11,7 @@ description: CowAgent 2.0.3 - 新增企微智能机器人和 QQ 通道、Web 控
|
||||
|
||||
接入文档:[企微智能机器人接入](https://docs.cowagent.ai/channels/wecom-bot)。
|
||||
|
||||
相关提交:[d4480b6](https://github.com/zhayujie/chatgpt-on-wechat/commit/d4480b6), [a42f31f](https://github.com/zhayujie/chatgpt-on-wechat/commit/a42f31f), [4ecd4df](https://github.com/zhayujie/chatgpt-on-wechat/commit/4ecd4df), [8b45d6c](https://github.com/zhayujie/chatgpt-on-wechat/commit/8b45d6c)
|
||||
相关提交:[d4480b6](https://github.com/zhayujie/CowAgent/commit/d4480b6), [a42f31f](https://github.com/zhayujie/CowAgent/commit/a42f31f), [4ecd4df](https://github.com/zhayujie/CowAgent/commit/4ecd4df), [8b45d6c](https://github.com/zhayujie/CowAgent/commit/8b45d6c)
|
||||
|
||||
### QQ 通道
|
||||
|
||||
@@ -19,18 +19,18 @@ description: CowAgent 2.0.3 - 新增企微智能机器人和 QQ 通道、Web 控
|
||||
|
||||
接入文档参考:[QQ机器人接入](https://docs.cowagent.ai/channels/qq)。
|
||||
|
||||
相关提交:[005a0e1](https://github.com/zhayujie/chatgpt-on-wechat/commit/005a0e1), [a4d54f5](https://github.com/zhayujie/chatgpt-on-wechat/commit/a4d54f5)
|
||||
相关提交:[005a0e1](https://github.com/zhayujie/CowAgent/commit/005a0e1), [a4d54f5](https://github.com/zhayujie/CowAgent/commit/a4d54f5)
|
||||
|
||||
## 🖥️ Web 控制台支持文件输入和处理
|
||||
|
||||
Web 控制台对话界面支持文件和图片上传,可直接发送文件给 Agent 进行处理。同时 Read 工具新增对 Office 文档(Word、Excel、PPT)的解析能力。
|
||||
|
||||
相关提交:[30c6d9b](https://github.com/zhayujie/chatgpt-on-wechat/commit/30c6d9b)
|
||||
相关提交:[30c6d9b](https://github.com/zhayujie/CowAgent/commit/30c6d9b)
|
||||
|
||||
## 🤖 新增模型
|
||||
|
||||
- **GPT-5.4 系列**:新增 `gpt-5.4`、`gpt-5.4-mini`、`gpt-5.4-nano` 模型支持 ([1623deb](https://github.com/zhayujie/chatgpt-on-wechat/commit/1623deb))
|
||||
- **Gemini 3.1 Flash Lite Preview**:新增 `gemini-3.1-flash-lite-preview` 模型支持 ([ba915f2](https://github.com/zhayujie/chatgpt-on-wechat/commit/ba915f2))
|
||||
- **GPT-5.4 系列**:新增 `gpt-5.4`、`gpt-5.4-mini`、`gpt-5.4-nano` 模型支持 ([1623deb](https://github.com/zhayujie/CowAgent/commit/1623deb))
|
||||
- **Gemini 3.1 Flash Lite Preview**:新增 `gemini-3.1-flash-lite-preview` 模型支持 ([ba915f2](https://github.com/zhayujie/CowAgent/commit/ba915f2))
|
||||
|
||||
## 💰 Coding Plan 支持
|
||||
|
||||
@@ -48,12 +48,12 @@ Web 控制台对话界面支持文件和图片上传,可直接发送文件给
|
||||
- 新增每日定时冲刷兜底机制,避免低活跃场景下记忆丢失
|
||||
- 修复上下文记忆丢失问题
|
||||
|
||||
相关提交:[022c13f](https://github.com/zhayujie/chatgpt-on-wechat/commit/022c13f), [c116235](https://github.com/zhayujie/chatgpt-on-wechat/commit/c116235)
|
||||
相关提交:[022c13f](https://github.com/zhayujie/CowAgent/commit/022c13f), [c116235](https://github.com/zhayujie/CowAgent/commit/c116235)
|
||||
|
||||
## 🔧 工具重构
|
||||
|
||||
- **图片识别**:将图片识别(Image Vision)从 Skill 重构为内置 Tool,新增独立的图片视觉提供方(Vision Provider)配置,提升稳定性和可维护性 ([a50fafa](https://github.com/zhayujie/chatgpt-on-wechat/commit/a50fafa), [3b8b562](https://github.com/zhayujie/chatgpt-on-wechat/commit/3b8b562))
|
||||
- **网页抓取**:将网页抓取(Web Fetch)从 Skill 重构为内置 Tool,支持远程文档文件(PDF、Word、Excel、PPT)的下载和解析 ([ccb9030](https://github.com/zhayujie/chatgpt-on-wechat/commit/ccb9030), [fa61744](https://github.com/zhayujie/chatgpt-on-wechat/commit/fa61744))
|
||||
- **图片识别**:将图片识别(Image Vision)从 Skill 重构为内置 Tool,新增独立的图片视觉提供方(Vision Provider)配置,提升稳定性和可维护性 ([a50fafa](https://github.com/zhayujie/CowAgent/commit/a50fafa), [3b8b562](https://github.com/zhayujie/CowAgent/commit/3b8b562))
|
||||
- **网页抓取**:将网页抓取(Web Fetch)从 Skill 重构为内置 Tool,支持远程文档文件(PDF、Word、Excel、PPT)的下载和解析 ([ccb9030](https://github.com/zhayujie/CowAgent/commit/ccb9030), [fa61744](https://github.com/zhayujie/CowAgent/commit/fa61744))
|
||||
|
||||
## 🐳 Docker 部署优化
|
||||
|
||||
@@ -64,28 +64,28 @@ Web 控制台对话界面支持文件和图片上传,可直接发送文件给
|
||||
|
||||
## ⚡ 性能优化
|
||||
|
||||
- **启动加速**:飞书通道采用懒加载方式导入依赖,避免 4-10 秒的启动延迟 ([924dc79](https://github.com/zhayujie/chatgpt-on-wechat/commit/924dc79))
|
||||
- **通道稳定性**:优化通道连接稳定性,支持通道配置通过环境变量设置 ([f1c04bc](https://github.com/zhayujie/chatgpt-on-wechat/commit/f1c04bc), [46d97fd](https://github.com/zhayujie/chatgpt-on-wechat/commit/46d97fd))
|
||||
- **启动加速**:飞书通道采用懒加载方式导入依赖,避免 4-10 秒的启动延迟 ([924dc79](https://github.com/zhayujie/CowAgent/commit/924dc79))
|
||||
- **通道稳定性**:优化通道连接稳定性,支持通道配置通过环境变量设置 ([f1c04bc](https://github.com/zhayujie/CowAgent/commit/f1c04bc), [46d97fd](https://github.com/zhayujie/CowAgent/commit/46d97fd))
|
||||
|
||||
## 🐛 问题修复
|
||||
|
||||
- **bot_type 配置**:修复 Agent 模式下 `bot_type` 配置传递问题 ([#2691](https://github.com/zhayujie/chatgpt-on-wechat/pull/2691)) Thanks [@Weikjssss](https://github.com/Weikjssss)
|
||||
- **bot_type 优先级**:调整 Agent 模式下 `bot_type` 的解析优先级 ([#2692](https://github.com/zhayujie/chatgpt-on-wechat/pull/2692)) Thanks [@6vision](https://github.com/6vision)
|
||||
- **智谱模型配置**:修复智谱 `bot_type` 命名、Web 控制台持久化及正则转义问题 ([#2693](https://github.com/zhayujie/chatgpt-on-wechat/pull/2693)) Thanks [@6vision](https://github.com/6vision)
|
||||
- **OpenAI 兼容层**:使用 `openai_compat` 层统一错误处理 ([#2688](https://github.com/zhayujie/chatgpt-on-wechat/pull/2688)) Thanks [@JasonOA888](https://github.com/JasonOA888)
|
||||
- **OpenAI 兼容迁移**:完成所有模型 Bot 的 `openai_compat` 迁移 ([#2689](https://github.com/zhayujie/chatgpt-on-wechat/pull/2689))
|
||||
- **Gemini 工具调用**:修复 Gemini 模型的工具调用匹配问题 ([eda82ba](https://github.com/zhayujie/chatgpt-on-wechat/commit/eda82ba))
|
||||
- **会话并发**:修复会话并发场景下的竞态条件问题 ([9879878](https://github.com/zhayujie/chatgpt-on-wechat/commit/9879878))
|
||||
- **历史消息恢复**:修复历史会话消息不完整问题,仅恢复 user/assistant 文本消息,剥离工具调用 ([b788a3d](https://github.com/zhayujie/chatgpt-on-wechat/commit/b788a3d), [a33ce97](https://github.com/zhayujie/chatgpt-on-wechat/commit/a33ce97))
|
||||
- **飞书群聊**:移除飞书群聊场景下对 `bot_name` 的依赖 ([b641bff](https://github.com/zhayujie/chatgpt-on-wechat/commit/b641bff))
|
||||
- **Safari 兼容**:修复 Safari 浏览器 IME 回车键误触发消息发送问题 ([0687916](https://github.com/zhayujie/chatgpt-on-wechat/commit/0687916))
|
||||
- **Windows 兼容**:修复 Windows 下 bash 风格 `$VAR` 环境变量转换为 `%VAR%` 的问题 ([7c67513](https://github.com/zhayujie/chatgpt-on-wechat/commit/7c67513))
|
||||
- **MiniMax 参数**:增加 MiniMax 模型的 `max_tokens` 限制 ([1767413](https://github.com/zhayujie/chatgpt-on-wechat/commit/1767413))
|
||||
- **.gitignore 更新**:添加 Python 目录忽略规则 ([#2683](https://github.com/zhayujie/chatgpt-on-wechat/pull/2683)) Thanks [@pelioo](https://github.com/pelioo)
|
||||
- **bot_type 配置**:修复 Agent 模式下 `bot_type` 配置传递问题 ([#2691](https://github.com/zhayujie/CowAgent/pull/2691)) Thanks [@Weikjssss](https://github.com/Weikjssss)
|
||||
- **bot_type 优先级**:调整 Agent 模式下 `bot_type` 的解析优先级 ([#2692](https://github.com/zhayujie/CowAgent/pull/2692)) Thanks [@6vision](https://github.com/6vision)
|
||||
- **智谱模型配置**:修复智谱 `bot_type` 命名、Web 控制台持久化及正则转义问题 ([#2693](https://github.com/zhayujie/CowAgent/pull/2693)) Thanks [@6vision](https://github.com/6vision)
|
||||
- **OpenAI 兼容层**:使用 `openai_compat` 层统一错误处理 ([#2688](https://github.com/zhayujie/CowAgent/pull/2688)) Thanks [@JasonOA888](https://github.com/JasonOA888)
|
||||
- **OpenAI 兼容迁移**:完成所有模型 Bot 的 `openai_compat` 迁移 ([#2689](https://github.com/zhayujie/CowAgent/pull/2689))
|
||||
- **Gemini 工具调用**:修复 Gemini 模型的工具调用匹配问题 ([eda82ba](https://github.com/zhayujie/CowAgent/commit/eda82ba))
|
||||
- **会话并发**:修复会话并发场景下的竞态条件问题 ([9879878](https://github.com/zhayujie/CowAgent/commit/9879878))
|
||||
- **历史消息恢复**:修复历史会话消息不完整问题,仅恢复 user/assistant 文本消息,剥离工具调用 ([b788a3d](https://github.com/zhayujie/CowAgent/commit/b788a3d), [a33ce97](https://github.com/zhayujie/CowAgent/commit/a33ce97))
|
||||
- **飞书群聊**:移除飞书群聊场景下对 `bot_name` 的依赖 ([b641bff](https://github.com/zhayujie/CowAgent/commit/b641bff))
|
||||
- **Safari 兼容**:修复 Safari 浏览器 IME 回车键误触发消息发送问题 ([0687916](https://github.com/zhayujie/CowAgent/commit/0687916))
|
||||
- **Windows 兼容**:修复 Windows 下 bash 风格 `$VAR` 环境变量转换为 `%VAR%` 的问题 ([7c67513](https://github.com/zhayujie/CowAgent/commit/7c67513))
|
||||
- **MiniMax 参数**:增加 MiniMax 模型的 `max_tokens` 限制 ([1767413](https://github.com/zhayujie/CowAgent/commit/1767413))
|
||||
- **.gitignore 更新**:添加 Python 目录忽略规则 ([#2683](https://github.com/zhayujie/CowAgent/pull/2683)) Thanks [@pelioo](https://github.com/pelioo)
|
||||
- **AGENT.md 主动演进**:优化系统提示词中对 AGENT.md 的更新引导,从被动的"用户修改时更新"改为主动识别对话中的性格、风格变化并自动更新
|
||||
|
||||
## 📦 升级方式
|
||||
|
||||
源码部署可执行 `./run.sh update` 一键升级,或手动拉取代码后重启。详见 [更新升级文档](https://docs.cowagent.ai/guide/upgrade)。
|
||||
|
||||
**发布日期**:2026.03.18 | [Full Changelog](https://github.com/zhayujie/chatgpt-on-wechat/compare/2.0.2...master)
|
||||
**发布日期**:2026.03.18 | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.2...master)
|
||||
|
||||
@@ -16,36 +16,36 @@ description: CowAgent 2.0.4 - 新增个人微信通道、新模型支持、日
|
||||
|
||||
接入文档:[微信接入](https://docs.cowagent.ai/channels/weixin)。
|
||||
|
||||
相关提交:[ce89869](https://github.com/zhayujie/chatgpt-on-wechat/commit/ce89869)
|
||||
相关提交:[ce89869](https://github.com/zhayujie/CowAgent/commit/ce89869)
|
||||
|
||||
## 🤖 新增模型
|
||||
|
||||
- **MiniMax-M2.7**:新增 MiniMax-M2.7 模型支持
|
||||
- **GLM-5-Turbo**:新增智谱 glm-5-turbo 模型支持
|
||||
|
||||
相关提交:[9192f6f](https://github.com/zhayujie/chatgpt-on-wechat/commit/9192f6f)
|
||||
相关提交:[9192f6f](https://github.com/zhayujie/CowAgent/commit/9192f6f)
|
||||
|
||||
## 🔧 脚本重构
|
||||
|
||||
- **run.sh 重构**:提取公共逻辑,精简脚本代码([49d8707](https://github.com/zhayujie/chatgpt-on-wechat/commit/49d8707))
|
||||
- **可执行权限**:修复 `run.sh` 文件权限问题 ([652156e](https://github.com/zhayujie/chatgpt-on-wechat/commit/652156e))
|
||||
- **PID 获取**:修复 `run.sh` 中进程 PID 获取错误的问题 ([9febb07](https://github.com/zhayujie/chatgpt-on-wechat/commit/9febb07))
|
||||
- **run.sh 重构**:提取公共逻辑,精简脚本代码([49d8707](https://github.com/zhayujie/CowAgent/commit/49d8707))
|
||||
- **可执行权限**:修复 `run.sh` 文件权限问题 ([652156e](https://github.com/zhayujie/CowAgent/commit/652156e))
|
||||
- **PID 获取**:修复 `run.sh` 中进程 PID 获取错误的问题 ([9febb07](https://github.com/zhayujie/CowAgent/commit/9febb07))
|
||||
|
||||
## 🌍 文档更新
|
||||
|
||||
新增完整的日文文档,覆盖入门指南、通道接入、模型配置等主要章节。Thanks [@Ikko Ashimine](https://github.com/ikoamu)
|
||||
|
||||
相关提交:[5487c0b](https://github.com/zhayujie/chatgpt-on-wechat/commit/5487c0b)
|
||||
相关提交:[5487c0b](https://github.com/zhayujie/CowAgent/commit/5487c0b)
|
||||
|
||||
## 🐛 问题修复
|
||||
|
||||
- **企微机器人兼容**:修复旧版 `websocket-client` 的兼容性问题,新增统一的 WebSocket 兼容层 ([bc7f627](https://github.com/zhayujie/chatgpt-on-wechat/commit/bc7f627))
|
||||
- **消息自动修复**:增强消息协议的容错能力,自动修复格式异常的消息序列 ([b8b57e3](https://github.com/zhayujie/chatgpt-on-wechat/commit/b8b57e3))
|
||||
- **飞书编码**:修复飞书通道消息和日志的编码问题 ([7d0e156](https://github.com/zhayujie/chatgpt-on-wechat/commit/7d0e156))
|
||||
- **飞书配置**:移除 `run.sh` 中对 `feishu_bot_name` 的冗余依赖 ([1b5be1b](https://github.com/zhayujie/chatgpt-on-wechat/commit/1b5be1b))
|
||||
- **企微机器人兼容**:修复旧版 `websocket-client` 的兼容性问题,新增统一的 WebSocket 兼容层 ([bc7f627](https://github.com/zhayujie/CowAgent/commit/bc7f627))
|
||||
- **消息自动修复**:增强消息协议的容错能力,自动修复格式异常的消息序列 ([b8b57e3](https://github.com/zhayujie/CowAgent/commit/b8b57e3))
|
||||
- **飞书编码**:修复飞书通道消息和日志的编码问题 ([7d0e156](https://github.com/zhayujie/CowAgent/commit/7d0e156))
|
||||
- **飞书配置**:移除 `run.sh` 中对 `feishu_bot_name` 的冗余依赖 ([1b5be1b](https://github.com/zhayujie/CowAgent/commit/1b5be1b))
|
||||
|
||||
## 📦 升级方式
|
||||
|
||||
源码部署可执行 `./run.sh update` 一键升级,或手动拉取代码后重启。详见 [更新升级文档](https://docs.cowagent.ai/guide/upgrade)。
|
||||
|
||||
**发布日期**:2026.03.22 | [Full Changelog](https://github.com/zhayujie/chatgpt-on-wechat/compare/2.0.3...master)
|
||||
**发布日期**:2026.03.22 | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.3...master)
|
||||
|
||||
@@ -59,26 +59,26 @@ Skill Hub 开源仓库:[cow-skill-hub](https://github.com/zhayujie/cow-skill-h
|
||||
|
||||
相关文档:[企微智能机器人接入](https://docs.cowagent.ai/channels/wecom-bot)。
|
||||
|
||||
相关提交:[#2735](https://github.com/zhayujie/chatgpt-on-wechat/pull/2735)
|
||||
相关提交:[#2735](https://github.com/zhayujie/CowAgent/pull/2735)
|
||||
|
||||
Thanks [@WecomTeam](https://github.com/WecomTeam)
|
||||
|
||||
## 🐛 其他优化与修复
|
||||
|
||||
- **DeepSeek 独立模块**:新增独立的 DeepSeek Bot 模块,支持 `deepseek_api_key` 专属配置,无需再通过 OpenAI 兼容方式接入([#2719](https://github.com/zhayujie/chatgpt-on-wechat/pull/2719))。Thanks [@6vision](https://github.com/6vision)
|
||||
- **Web 控制台优化**:新增斜杠指令菜单和输入历史回溯,新增模型选项,优化移动端适配([#2731](https://github.com/zhayujie/chatgpt-on-wechat/pull/2731))。Thanks [@zkjqd](https://github.com/zkjqd)
|
||||
- **上下文丢失**:修复上下文裁剪后丢失的问题 ([393f0c0](https://github.com/zhayujie/chatgpt-on-wechat/commit/393f0c0))
|
||||
- **系统提示词**:修复系统提示词未在每轮重建的问题 ([13f5fde](https://github.com/zhayujie/chatgpt-on-wechat/commit/13f5fde))
|
||||
- **Agent 响应**:去除 Agent 响应首尾空白字符 ([f890318](https://github.com/zhayujie/chatgpt-on-wechat/commit/f890318))
|
||||
- **视觉压缩**:优化视觉图片压缩策略 ([22b8ca0](https://github.com/zhayujie/chatgpt-on-wechat/commit/22b8ca0))
|
||||
- **Gemini 模型**:修复 GoogleGeminiBot 缺少 model 属性的问题([#2716](https://github.com/zhayujie/chatgpt-on-wechat/pull/2716))。Thanks [@cowagent](https://github.com/cowagent)
|
||||
- **微信通道**:修复文件发送失败、文件名丢失等问题 ([6d9b7ba](https://github.com/zhayujie/chatgpt-on-wechat/commit/6d9b7ba)、[baf66a1](https://github.com/zhayujie/chatgpt-on-wechat/commit/baf66a1)、[45faa9c](https://github.com/zhayujie/chatgpt-on-wechat/commit/45faa9c))
|
||||
- **Docker 优化**:修复卷权限问题,精简镜像体积 ([3eb8348](https://github.com/zhayujie/chatgpt-on-wechat/commit/3eb8348)、[4470d4c](https://github.com/zhayujie/chatgpt-on-wechat/commit/4470d4c))
|
||||
- **README 排版**:优化中英文排版空格([#2723](https://github.com/zhayujie/chatgpt-on-wechat/pull/2723))。Thanks [@Xiaozhou345](https://github.com/Xiaozhou345)
|
||||
- **DeepSeek 独立模块**:新增独立的 DeepSeek Bot 模块,支持 `deepseek_api_key` 专属配置,无需再通过 OpenAI 兼容方式接入([#2719](https://github.com/zhayujie/CowAgent/pull/2719))。Thanks [@6vision](https://github.com/6vision)
|
||||
- **Web 控制台优化**:新增斜杠指令菜单和输入历史回溯,新增模型选项,优化移动端适配([#2731](https://github.com/zhayujie/CowAgent/pull/2731))。Thanks [@zkjqd](https://github.com/zkjqd)
|
||||
- **上下文丢失**:修复上下文裁剪后丢失的问题 ([393f0c0](https://github.com/zhayujie/CowAgent/commit/393f0c0))
|
||||
- **系统提示词**:修复系统提示词未在每轮重建的问题 ([13f5fde](https://github.com/zhayujie/CowAgent/commit/13f5fde))
|
||||
- **Agent 响应**:去除 Agent 响应首尾空白字符 ([f890318](https://github.com/zhayujie/CowAgent/commit/f890318))
|
||||
- **视觉压缩**:优化视觉图片压缩策略 ([22b8ca0](https://github.com/zhayujie/CowAgent/commit/22b8ca0))
|
||||
- **Gemini 模型**:修复 GoogleGeminiBot 缺少 model 属性的问题([#2716](https://github.com/zhayujie/CowAgent/pull/2716))。Thanks [@cowagent](https://github.com/cowagent)
|
||||
- **微信通道**:修复文件发送失败、文件名丢失等问题 ([6d9b7ba](https://github.com/zhayujie/CowAgent/commit/6d9b7ba)、[baf66a1](https://github.com/zhayujie/CowAgent/commit/baf66a1)、[45faa9c](https://github.com/zhayujie/CowAgent/commit/45faa9c))
|
||||
- **Docker 优化**:修复卷权限问题,精简镜像体积 ([3eb8348](https://github.com/zhayujie/CowAgent/commit/3eb8348)、[4470d4c](https://github.com/zhayujie/CowAgent/commit/4470d4c))
|
||||
- **README 排版**:优化中英文排版空格([#2723](https://github.com/zhayujie/CowAgent/pull/2723))。Thanks [@Xiaozhou345](https://github.com/Xiaozhou345)
|
||||
- **安全修复**:修复 Memory Content路径遍历风险,Thanks [@August829](https://github.com/August829)
|
||||
|
||||
## 📦 升级方式
|
||||
|
||||
源码部署可执行 `cow update` 或 `./run.sh update` 一键升级,或手动拉取代码后重启。详见 [更新升级文档](https://docs.cowagent.ai/guide/upgrade)。
|
||||
|
||||
**发布日期**:2026.04.01 | [Full Changelog](https://github.com/zhayujie/chatgpt-on-wechat/compare/2.0.4...master)
|
||||
**发布日期**:2026.04.01 | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.4...master)
|
||||
|
||||
@@ -54,5 +54,5 @@ Detailed instructions...
|
||||
| `metadata.always` | 是否始终加载(默认 false) |
|
||||
|
||||
<Tip>
|
||||
详细开发文档可参考 [Skill Creator 说明](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/skills/skill-creator/SKILL.md)。
|
||||
详细开发文档可参考 [Skill Creator 说明](https://github.com/zhayujie/CowAgent/blob/master/skills/skill-creator/SKILL.md)。
|
||||
</Tip>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
---
|
||||
title: memory - 记忆
|
||||
description: 搜索和读取长期记忆
|
||||
title: memory - 记忆与知识
|
||||
description: 搜索和读取长期记忆及知识库文件
|
||||
---
|
||||
|
||||
记忆工具包含两个子工具:`memory_search`(搜索记忆)和 `memory_get`(读取记忆文件)。
|
||||
记忆工具包含两个子工具:`memory_search`(搜索记忆)和 `memory_get`(读取记忆或知识文件)。
|
||||
|
||||
当 [知识库](/knowledge) 功能开启时,这两个工具同时支持访问 `memory/` 和 `knowledge/` 目录下的文件。
|
||||
|
||||
## 依赖
|
||||
|
||||
@@ -11,7 +13,7 @@ description: 搜索和读取长期记忆
|
||||
|
||||
## memory_search
|
||||
|
||||
搜索历史记忆,支持关键词和向量混合检索。
|
||||
搜索历史记忆和知识库内容,支持关键词和向量混合检索。
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -19,11 +21,11 @@ description: 搜索和读取长期记忆
|
||||
|
||||
## memory_get
|
||||
|
||||
读取特定记忆文件的内容。
|
||||
读取特定记忆文件或知识库文件的内容。
|
||||
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `path` | string | 是 | 记忆文件的相对路径(如 `MEMORY.md`、`memory/2026-01-01.md`) |
|
||||
| `path` | string | 是 | 文件的相对路径(如 `MEMORY.md`、`memory/2026-01-01.md`、`knowledge/concepts/rag.md`) |
|
||||
| `start_line` | integer | 否 | 起始行号 |
|
||||
| `end_line` | integer | 否 | 结束行号 |
|
||||
|
||||
@@ -34,3 +36,8 @@ Agent 会在以下场景自动调用记忆工具:
|
||||
- 用户分享重要信息时 → 存储到记忆
|
||||
- 需要参考历史信息时 → 搜索相关记忆
|
||||
- 对话达到一定长度时 → 提取摘要存储
|
||||
- 讨论到专业知识时 → 检索知识库中的相关页面
|
||||
|
||||
<Note>
|
||||
当 `knowledge` 配置为 `false` 时,工具的描述和搜索范围会自动调整为仅包含记忆文件。
|
||||
</Note>
|
||||
|
||||
@@ -505,8 +505,21 @@ class ClaudeAPIBot(Bot, OpenAIImage):
|
||||
delta = event.get("delta", {})
|
||||
delta_type = delta.get("type")
|
||||
|
||||
if delta_type == "text_delta":
|
||||
# Text content
|
||||
if delta_type == "thinking_delta":
|
||||
thinking_text = delta.get("thinking", "")
|
||||
if thinking_text:
|
||||
yield {
|
||||
"choices": [{
|
||||
"index": 0,
|
||||
"delta": {
|
||||
"role": "assistant",
|
||||
"reasoning_content": thinking_text
|
||||
},
|
||||
"finish_reason": None
|
||||
}]
|
||||
}
|
||||
|
||||
elif delta_type == "text_delta":
|
||||
content = delta.get("text", "")
|
||||
yield {
|
||||
"id": event.get("id", ""),
|
||||
|
||||
@@ -22,7 +22,7 @@ class MinimaxBot(Bot):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.args = {
|
||||
"model": conf().get("model") or "MiniMax-M2.1",
|
||||
"model": conf().get("model") or "MiniMax-M2.7",
|
||||
"temperature": conf().get("temperature", 0.3),
|
||||
"top_p": conf().get("top_p", 0.95),
|
||||
}
|
||||
@@ -280,11 +280,8 @@ class MinimaxBot(Bot):
|
||||
|
||||
logger.debug(f"[MINIMAX] API call: model={model}, tools={len(converted_tools) if converted_tools else 0}, stream={stream}")
|
||||
|
||||
# Check if we should show thinking process
|
||||
show_thinking = kwargs.pop("show_thinking", conf().get("minimax_show_thinking", False))
|
||||
|
||||
if stream:
|
||||
return self._handle_stream_response(request_body, show_thinking=show_thinking)
|
||||
return self._handle_stream_response(request_body)
|
||||
else:
|
||||
return self._handle_sync_response(request_body)
|
||||
|
||||
@@ -517,12 +514,11 @@ class MinimaxBot(Bot):
|
||||
logger.error(traceback.format_exc())
|
||||
yield {"error": True, "message": str(e), "status_code": 500}
|
||||
|
||||
def _handle_stream_response(self, request_body, show_thinking=False):
|
||||
def _handle_stream_response(self, request_body):
|
||||
"""Handle streaming API response
|
||||
|
||||
|
||||
Args:
|
||||
request_body: API request parameters
|
||||
show_thinking: Whether to show thinking/reasoning process to users
|
||||
"""
|
||||
try:
|
||||
headers = {
|
||||
@@ -601,19 +597,15 @@ class MinimaxBot(Bot):
|
||||
|
||||
current_reasoning[reasoning_index]["text"] += reasoning_text
|
||||
|
||||
# Optionally yield thinking as visible content
|
||||
if show_thinking:
|
||||
# Yield thinking text as-is (without emoji decoration)
|
||||
# The reasoning text will be displayed to users
|
||||
yield {
|
||||
"choices": [{
|
||||
"index": 0,
|
||||
"delta": {
|
||||
"role": "assistant",
|
||||
"content": reasoning_text
|
||||
}
|
||||
}]
|
||||
}
|
||||
yield {
|
||||
"choices": [{
|
||||
"index": 0,
|
||||
"delta": {
|
||||
"role": "assistant",
|
||||
"reasoning_content": reasoning_text
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
# Handle text content
|
||||
if "content" in delta and delta["content"]:
|
||||
|
||||
@@ -576,6 +576,15 @@ class ModelScopeBot(Bot):
|
||||
continue
|
||||
|
||||
if delta.get("reasoning_content"):
|
||||
yield {
|
||||
"choices": [{
|
||||
"index": 0,
|
||||
"delta": {
|
||||
"role": "assistant",
|
||||
"reasoning_content": delta["reasoning_content"]
|
||||
}
|
||||
}]
|
||||
}
|
||||
continue
|
||||
|
||||
tool_call_chunks = delta.get("tool_calls")
|
||||
|
||||
@@ -31,6 +31,7 @@ KNOWN_COMMANDS = {
|
||||
"help", "version", "status", "logs",
|
||||
"start", "stop", "restart",
|
||||
"skill", "context", "config",
|
||||
"knowledge",
|
||||
"install-browser",
|
||||
}
|
||||
|
||||
@@ -157,6 +158,9 @@ class CowCliPlugin(Plugin):
|
||||
" /config 查看当前配置",
|
||||
" /config <key> 查看某项配置",
|
||||
" /config <key> <val> 修改配置",
|
||||
" /knowledge 查看知识库统计",
|
||||
" /knowledge list 查看知识库文件树",
|
||||
" /knowledge on|off 开启/关闭知识库",
|
||||
"",
|
||||
"💡 也可以用 cow <command> 代替 /<command>",
|
||||
]
|
||||
@@ -310,6 +314,7 @@ class CowCliPlugin(Plugin):
|
||||
"agent_max_context_tokens",
|
||||
"agent_max_context_turns",
|
||||
"agent_max_steps",
|
||||
"knowledge",
|
||||
}
|
||||
|
||||
_CONFIG_READABLE = _CONFIG_WRITABLE | {"channel_type"}
|
||||
@@ -851,6 +856,133 @@ class CowCliPlugin(Plugin):
|
||||
icon = "✅" if enabled else "⬚"
|
||||
return f"{icon} 技能 '{name}' 已{action}"
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# knowledge
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def _cmd_knowledge(self, args: str, e_context, **_) -> str:
|
||||
sub = args.strip().lower().split(None, 1)[0] if args.strip() else ""
|
||||
|
||||
if sub == "on":
|
||||
return self._knowledge_toggle(True)
|
||||
elif sub == "off":
|
||||
return self._knowledge_toggle(False)
|
||||
elif sub in ("list", "tree"):
|
||||
return self._knowledge_tree()
|
||||
else:
|
||||
return self._knowledge_stats()
|
||||
|
||||
def _knowledge_toggle(self, enabled: bool) -> str:
|
||||
from config import conf
|
||||
import json as _json
|
||||
|
||||
conf()["knowledge"] = enabled
|
||||
|
||||
project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
config_path = os.path.join(project_root, "config.json")
|
||||
try:
|
||||
with open(config_path, "r", encoding="utf-8") as f:
|
||||
file_config = _json.load(f)
|
||||
file_config["knowledge"] = enabled
|
||||
with open(config_path, "w", encoding="utf-8") as f:
|
||||
_json.dump(file_config, f, indent=4, ensure_ascii=False)
|
||||
except Exception as e:
|
||||
return f"⚠️ 内存中已切换,但写入 config.json 失败: {e}"
|
||||
|
||||
status = "开启 ✅" if enabled else "关闭 ❌"
|
||||
note = "知识库将在下次对话中生效" if enabled else "知识库系统已停用,不再注入提示词和索引知识文件"
|
||||
return f"📚 知识库已{status}\n\n{note}"
|
||||
|
||||
def _knowledge_stats(self) -> str:
|
||||
from config import conf
|
||||
from common.utils import expand_path
|
||||
knowledge_dir = os.path.join(
|
||||
expand_path(conf().get("agent_workspace", "~/cow")),
|
||||
"knowledge"
|
||||
)
|
||||
if not os.path.isdir(knowledge_dir):
|
||||
return "📚 知识库目录不存在\n\n💡 开启知识库: /knowledge on"
|
||||
|
||||
enabled = conf().get("knowledge", True)
|
||||
total_files = 0
|
||||
total_bytes = 0
|
||||
cat_count = {}
|
||||
|
||||
for root, dirs, files in os.walk(knowledge_dir):
|
||||
dirs[:] = [d for d in dirs if not d.startswith(".")]
|
||||
rel_root = os.path.relpath(root, knowledge_dir)
|
||||
category = rel_root.split(os.sep)[0] if rel_root != "." else "root"
|
||||
for f in files:
|
||||
if f.endswith(".md") and f not in ("index.md", "log.md"):
|
||||
total_files += 1
|
||||
total_bytes += os.path.getsize(os.path.join(root, f))
|
||||
cat_count[category] = cat_count.get(category, 0) + 1
|
||||
|
||||
status = "✅ 已开启" if enabled else "❌ 已关闭"
|
||||
lines = [
|
||||
"📚 知识库统计",
|
||||
"",
|
||||
f"状态: {status}",
|
||||
f"页面: {total_files} 篇",
|
||||
f"大小: {total_bytes / 1024:.1f} KB",
|
||||
"",
|
||||
]
|
||||
if cat_count:
|
||||
for cat in sorted(cat_count.keys()):
|
||||
lines.append(f"- {cat}/ ({cat_count[cat]} pages)")
|
||||
lines.append("")
|
||||
|
||||
lines.append(f"路径: {knowledge_dir}")
|
||||
lines.extend([
|
||||
"",
|
||||
"━━━━━━━━━━━━━━━━━━━━━━━━━━",
|
||||
"💡 /knowledge list 查看文件树",
|
||||
"💡 /knowledge on|off 开关知识库",
|
||||
])
|
||||
return "\n".join(lines)
|
||||
|
||||
def _knowledge_tree(self) -> str:
|
||||
from config import conf
|
||||
from common.utils import expand_path
|
||||
knowledge_dir = os.path.join(
|
||||
expand_path(conf().get("agent_workspace", "~/cow")),
|
||||
"knowledge"
|
||||
)
|
||||
if not os.path.isdir(knowledge_dir):
|
||||
return "📚 知识库目录不存在\n\n💡 开启知识库: /knowledge on"
|
||||
|
||||
tree = ["knowledge/"]
|
||||
|
||||
subdirs = sorted([
|
||||
d for d in os.listdir(knowledge_dir)
|
||||
if os.path.isdir(os.path.join(knowledge_dir, d)) and not d.startswith(".")
|
||||
])
|
||||
|
||||
for i, subdir in enumerate(subdirs):
|
||||
is_last_dir = (i == len(subdirs) - 1)
|
||||
branch = "└── " if is_last_dir else "├── "
|
||||
subdir_path = os.path.join(knowledge_dir, subdir)
|
||||
md_files = sorted([
|
||||
f for f in os.listdir(subdir_path)
|
||||
if f.endswith(".md") and not f.startswith(".")
|
||||
])
|
||||
tree.append(f"{branch}{subdir}/ ({len(md_files)})")
|
||||
|
||||
child_prefix = " " if is_last_dir else "│ "
|
||||
max_show = 12
|
||||
for j, fname in enumerate(md_files[:max_show]):
|
||||
is_last_file = (j == len(md_files[:max_show]) - 1) and len(md_files) <= max_show
|
||||
fb = "└── " if is_last_file else "├── "
|
||||
name = fname.replace(".md", "")
|
||||
tree.append(f"{child_prefix}{fb}{name}")
|
||||
if len(md_files) > max_show:
|
||||
tree.append(f"{child_prefix}└── ... +{len(md_files) - max_show} more")
|
||||
|
||||
if not subdirs:
|
||||
tree.append("(空)")
|
||||
|
||||
return "```\n" + "\n".join(tree) + "\n```"
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
@@ -4,6 +4,7 @@ requests>=2.28.2
|
||||
chardet>=5.1.0
|
||||
Pillow
|
||||
web.py
|
||||
legacy-cgi; python_version >= "3.13"
|
||||
python-dotenv>=1.0.0
|
||||
PyYAML>=6.0
|
||||
croniter>=2.0.0
|
||||
|
||||
47
run.sh
47
run.sh
@@ -127,21 +127,21 @@ check_python_version() {
|
||||
|
||||
# Clone project
|
||||
clone_project() {
|
||||
echo -e "${GREEN}🔍 Cloning ChatGPT-on-WeChat project...${NC}"
|
||||
echo -e "${GREEN}🔍 Cloning CowAgent project...${NC}"
|
||||
|
||||
if [ -d "chatgpt-on-wechat" ]; then
|
||||
echo -e "${YELLOW}⚠️ Directory 'chatgpt-on-wechat' already exists.${NC}"
|
||||
if [ -d "CowAgent" ]; then
|
||||
echo -e "${YELLOW}⚠️ Directory 'CowAgent' already exists.${NC}"
|
||||
read -p "Choose action: overwrite(o), backup(b), or quit(q)? [press Enter for default: b]: " choice
|
||||
choice=${choice:-b}
|
||||
case "$choice" in
|
||||
o|O)
|
||||
echo -e "${YELLOW}🗑️ Overwriting 'chatgpt-on-wechat' directory...${NC}"
|
||||
rm -rf chatgpt-on-wechat
|
||||
echo -e "${YELLOW}🗑️ Overwriting 'CowAgent' directory...${NC}"
|
||||
rm -rf CowAgent
|
||||
;;
|
||||
b|B)
|
||||
backup_dir="chatgpt-on-wechat_backup_$(date +%s)"
|
||||
backup_dir="CowAgent_backup_$(date +%s)"
|
||||
echo -e "${YELLOW}🔀 Backing up to '$backup_dir'...${NC}"
|
||||
mv chatgpt-on-wechat "$backup_dir"
|
||||
mv CowAgent "$backup_dir"
|
||||
;;
|
||||
q|Q)
|
||||
echo -e "${RED}❌ Installation cancelled.${NC}"
|
||||
@@ -158,31 +158,36 @@ clone_project() {
|
||||
|
||||
if ! command -v git &> /dev/null; then
|
||||
echo -e "${YELLOW}⚠️ Git not available. Trying wget/curl...${NC}"
|
||||
local zip_url="https://gitee.com/zhayujie/chatgpt-on-wechat/repository/archive/master.zip"
|
||||
local zip_url="https://gitee.com/zhayujie/CowAgent/repository/archive/master.zip"
|
||||
if command -v wget &> /dev/null; then
|
||||
wget "$zip_url" -O chatgpt-on-wechat.zip
|
||||
wget "$zip_url" -O CowAgent.zip
|
||||
elif command -v curl &> /dev/null; then
|
||||
curl -L "$zip_url" -o chatgpt-on-wechat.zip
|
||||
curl -L "$zip_url" -o CowAgent.zip
|
||||
else
|
||||
echo -e "${RED}❌ Cannot download project. Please install Git, wget, or curl.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
unzip chatgpt-on-wechat.zip
|
||||
mv chatgpt-on-wechat-master chatgpt-on-wechat
|
||||
rm chatgpt-on-wechat.zip
|
||||
unzip CowAgent.zip
|
||||
mv CowAgent-master CowAgent
|
||||
rm CowAgent.zip
|
||||
else
|
||||
GIT_HTTP_CONNECT_TIMEOUT=10 GIT_HTTP_LOW_SPEED_LIMIT=1024 GIT_HTTP_LOW_SPEED_TIME=15 \
|
||||
git clone --depth 10 --progress https://github.com/zhayujie/chatgpt-on-wechat.git || {
|
||||
echo -e "${YELLOW}⚠️ GitHub is slow, switching to Gitee mirror...${NC}"
|
||||
git clone --depth 10 --progress https://gitee.com/zhayujie/chatgpt-on-wechat.git
|
||||
}
|
||||
if [[ $? -ne 0 ]]; then
|
||||
local clone_ok=false
|
||||
# Test GitHub connectivity before attempting clone
|
||||
if curl -s --connect-timeout 5 --max-time 10 https://github.com > /dev/null 2>&1; then
|
||||
echo -e "${YELLOW}🌐 GitHub is reachable, cloning from GitHub...${NC}"
|
||||
timeout 15 git clone --depth 10 --progress https://github.com/zhayujie/CowAgent.git && clone_ok=true
|
||||
fi
|
||||
if [ "$clone_ok" = false ]; then
|
||||
echo -e "${YELLOW}⚠️ GitHub clone failed or timed out, switching to Gitee mirror...${NC}"
|
||||
timeout 30 git clone --depth 10 --progress https://gitee.com/zhayujie/CowAgent.git && clone_ok=true
|
||||
fi
|
||||
if [ "$clone_ok" = false ]; then
|
||||
echo -e "${RED}❌ Project clone failed. Please check network connection.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
cd chatgpt-on-wechat || { echo -e "${RED}❌ Failed to enter project directory.${NC}"; exit 1; }
|
||||
cd CowAgent || { echo -e "${RED}❌ Failed to enter project directory.${NC}"; exit 1; }
|
||||
export BASE_DIR=$(pwd)
|
||||
echo -e "${GREEN}✅ Project cloned successfully: $BASE_DIR${NC}"
|
||||
|
||||
@@ -802,7 +807,7 @@ cmd_update() {
|
||||
pull_ok=true
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ git pull failed, trying Gitee mirror...${NC}"
|
||||
git remote set-url origin https://gitee.com/zhayujie/chatgpt-on-wechat.git
|
||||
git remote set-url origin https://gitee.com/zhayujie/CowAgent.git
|
||||
if git pull; then
|
||||
pull_ok=true
|
||||
else
|
||||
|
||||
@@ -60,6 +60,7 @@ $PythonCmd = Find-Python
|
||||
function Assert-Python {
|
||||
if (-not $PythonCmd) {
|
||||
Write-Err "Python 3.9-3.13 not found. Please install from https://www.python.org/downloads/"
|
||||
Read-Host "Press Enter to exit"
|
||||
exit 1
|
||||
}
|
||||
Write-Cow "Found Python: $PythonCmd"
|
||||
@@ -67,15 +68,15 @@ function Assert-Python {
|
||||
|
||||
# ── clone project ────────────────────────────────────────────────
|
||||
function Install-Project {
|
||||
if (Test-Path "chatgpt-on-wechat") {
|
||||
Write-Warn "Directory 'chatgpt-on-wechat' already exists."
|
||||
if (Test-Path "CowAgent") {
|
||||
Write-Warn "Directory 'CowAgent' already exists."
|
||||
$choice = Read-Host "Overwrite(o), backup(b), or quit(q)? [default: b]"
|
||||
if (-not $choice) { $choice = "b" }
|
||||
switch ($choice.ToLower()) {
|
||||
"o" { Remove-Item -Recurse -Force "chatgpt-on-wechat" }
|
||||
"o" { Remove-Item -Recurse -Force "CowAgent" }
|
||||
"b" {
|
||||
$backup = "chatgpt-on-wechat_backup_$(Get-Date -Format 'yyyyMMddHHmmss')"
|
||||
Rename-Item "chatgpt-on-wechat" $backup
|
||||
$backup = "CowAgent_backup_$(Get-Date -Format 'yyyyMMddHHmmss')"
|
||||
Rename-Item "CowAgent" $backup
|
||||
Write-Cow "Backed up to '$backup'"
|
||||
}
|
||||
"q" { Write-Err "Installation cancelled."; exit 1 }
|
||||
@@ -86,27 +87,45 @@ function Install-Project {
|
||||
$gitBin = Get-Command git -ErrorAction SilentlyContinue
|
||||
if (-not $gitBin) {
|
||||
Write-Err "Git not found. Please install from https://git-scm.com/download/win"
|
||||
Read-Host "Press Enter to exit"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Cow "Cloning CowAgent project..."
|
||||
$prevEAP = $ErrorActionPreference; $ErrorActionPreference = "Continue"
|
||||
git clone https://github.com/zhayujie/chatgpt-on-wechat.git 2>&1 | Out-Null
|
||||
$cloneExit = $LASTEXITCODE
|
||||
$ErrorActionPreference = $prevEAP
|
||||
if ($cloneExit -ne 0) {
|
||||
Write-Warn "GitHub failed, trying Gitee..."
|
||||
$ErrorActionPreference = "Continue"
|
||||
git clone https://gitee.com/zhayujie/chatgpt-on-wechat.git 2>&1 | Out-Null
|
||||
$cloneExit = $LASTEXITCODE
|
||||
$cloneOk = $false
|
||||
|
||||
# Test GitHub connectivity before attempting clone
|
||||
try {
|
||||
$null = Invoke-WebRequest -Uri "https://github.com" -UseBasicParsing -TimeoutSec 5 -ErrorAction Stop
|
||||
Write-Cow "GitHub is reachable, cloning from GitHub..."
|
||||
$prevEAP = $ErrorActionPreference; $ErrorActionPreference = "Continue"
|
||||
git clone --depth 10 --progress "https://github.com/zhayujie/CowAgent.git" 2>&1 | ForEach-Object { Write-Host $_ }
|
||||
if ($LASTEXITCODE -eq 0) { $cloneOk = $true }
|
||||
$ErrorActionPreference = $prevEAP
|
||||
if ($cloneExit -ne 0) {
|
||||
Write-Err "Clone failed. Check your network."
|
||||
exit 1
|
||||
if (-not $cloneOk) {
|
||||
if (Test-Path "CowAgent") { Remove-Item -Recurse -Force "CowAgent" }
|
||||
}
|
||||
} catch {}
|
||||
|
||||
if (-not $cloneOk) {
|
||||
Write-Warn "GitHub clone failed or timed out, switching to Gitee mirror..."
|
||||
$prevEAP = $ErrorActionPreference; $ErrorActionPreference = "Continue"
|
||||
git clone --depth 10 --progress "https://gitee.com/zhayujie/CowAgent.git" 2>&1 | ForEach-Object { Write-Host $_ }
|
||||
if ($LASTEXITCODE -eq 0) { $cloneOk = $true }
|
||||
$ErrorActionPreference = $prevEAP
|
||||
if (-not $cloneOk) {
|
||||
if (Test-Path "CowAgent") { Remove-Item -Recurse -Force "CowAgent" }
|
||||
}
|
||||
}
|
||||
|
||||
Set-Location "chatgpt-on-wechat"
|
||||
if (-not $cloneOk) {
|
||||
Write-Err "Clone failed from both GitHub and Gitee. Please check your network connection."
|
||||
Write-Err "You can also manually clone: git clone https://gitee.com/zhayujie/CowAgent.git"
|
||||
Read-Host "Press Enter to exit"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Set-Location "CowAgent"
|
||||
$script:BaseDir = $PWD.Path
|
||||
$script:IsProjectDir = $true
|
||||
Write-Cow "Project cloned: $BaseDir"
|
||||
@@ -443,7 +462,7 @@ function Update-Project {
|
||||
if ($pullExit -ne 0) {
|
||||
Write-Warn "GitHub failed, trying Gitee..."
|
||||
$ErrorActionPreference = "Continue"
|
||||
git remote set-url origin https://gitee.com/zhayujie/chatgpt-on-wechat.git 2>&1 | Out-Null
|
||||
git remote set-url origin https://gitee.com/zhayujie/CowAgent.git 2>&1 | Out-Null
|
||||
git pull 2>&1 | Out-Null
|
||||
$ErrorActionPreference = $prevEAP
|
||||
}
|
||||
|
||||
92
skills/knowledge-wiki/SKILL.md
Normal file
92
skills/knowledge-wiki/SKILL.md
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
name: knowledge-wiki
|
||||
description: Manage the personal knowledge wiki. Use when the user shares articles, documents, or asks to organize knowledge; when a conversation produces insights worth preserving as structured knowledge; or when the user asks about the knowledge base.
|
||||
metadata:
|
||||
cowagent:
|
||||
always: true
|
||||
---
|
||||
|
||||
# Knowledge Wiki
|
||||
|
||||
Maintain a persistent, structured knowledge base in the `knowledge/` directory.
|
||||
|
||||
## Core Operations
|
||||
|
||||
### 1. Ingest — User shares an article, document, or resource
|
||||
|
||||
1. Read and understand the source material
|
||||
2. Extract key facts, insights, and structured knowledge
|
||||
3. Determine the appropriate subdirectory:
|
||||
- Read `knowledge/index.md` to see existing categories
|
||||
- If a matching category exists, follow that structure
|
||||
- If not, create a new subdirectory with a clear name
|
||||
4. Create the knowledge page: `knowledge/<category>/<slug>.md`
|
||||
5. Update `knowledge/index.md` and append to `knowledge/log.md`
|
||||
|
||||
### 2. Synthesize — Conversation produces valuable structured knowledge
|
||||
|
||||
1. Create a knowledge page under the appropriate category
|
||||
2. Update related pages with cross-references
|
||||
3. Update `knowledge/index.md` and `knowledge/log.md`
|
||||
|
||||
### 3. Query — User asks about accumulated knowledge
|
||||
|
||||
1. Check `knowledge/index.md` (already in your context) for relevant pages
|
||||
2. Read specific pages with the `read` tool
|
||||
3. Supplement with `memory_search` if needed
|
||||
|
||||
## Page Format
|
||||
|
||||
```markdown
|
||||
# Page Title
|
||||
|
||||
Content here. Cross-reference related pages with markdown links:
|
||||
[Related Page](../category/related-page.md)
|
||||
|
||||
## Key Points
|
||||
|
||||
- ...
|
||||
|
||||
## Related
|
||||
|
||||
- [Page A](../category/page-a.md) — how it relates
|
||||
- [Page B](../category/page-b.md) — how it relates
|
||||
```
|
||||
|
||||
Cross-references build a knowledge graph. When creating or updating a page, link to related pages and update those pages to link back. **Only link to pages that already exist** — if a concept deserves its own page, create it first, then add the link.
|
||||
|
||||
## Index Format (`knowledge/index.md`)
|
||||
|
||||
Flat list, one line per page: `[Title](path) — one-line summary`. Group by category (matching subdirectories). No tables, no emoji.
|
||||
|
||||
```markdown
|
||||
# Knowledge Index
|
||||
|
||||
## Category A
|
||||
- [Page Title](category-a/page-slug.md) — one-line summary
|
||||
|
||||
## Category B
|
||||
- [Page Title](category-b/page-slug.md) — one-line summary
|
||||
```
|
||||
|
||||
Category names and structure are flexible — follow whatever organization already exists in the index, or create new categories based on the content.
|
||||
|
||||
## Log Format (`knowledge/log.md`)
|
||||
|
||||
Append-only, newest at bottom:
|
||||
|
||||
```markdown
|
||||
## [YYYY-MM-DD] ingest | Page Title
|
||||
## [YYYY-MM-DD] synthesize | Page Title
|
||||
```
|
||||
|
||||
## Guidelines
|
||||
|
||||
- **File naming**: lowercase kebab-case (e.g. `machine-learning.md`)
|
||||
- **One topic per page**: link between pages rather than duplicating
|
||||
- **Update, don't duplicate**: if a page exists, update it
|
||||
- **Cross-reference**: every page should link to related pages; keep the knowledge graph connected
|
||||
- **Index is mandatory**: always update `knowledge/index.md` after any change
|
||||
- **Be concise**: capture essence, not copy entire sources
|
||||
- **Full paths in replies**: when referencing knowledge files in conversation replies, use the full path from workspace root (e.g. `[Title](knowledge/<category>/<slug>.md)`), not relative paths. Relative paths are only for cross-references inside knowledge pages themselves.
|
||||
- **Cite sources**: when answering based on knowledge pages, include links to the relevant pages so the user can explore further.
|
||||
184
tests/test_minimax_provider.py
Normal file
184
tests/test_minimax_provider.py
Normal file
@@ -0,0 +1,184 @@
|
||||
# encoding:utf-8
|
||||
"""
|
||||
Unit tests for MiniMax provider additions:
|
||||
- MiniMax-M2.7-highspeed constant in const.py
|
||||
- Default model update in MinimaxBot
|
||||
- MinimaxVoice TTS provider
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
import unittest
|
||||
from unittest.mock import MagicMock, patch, PropertyMock
|
||||
|
||||
# Add project root to path
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
||||
|
||||
|
||||
class TestMinimaxConst(unittest.TestCase):
|
||||
"""Test that MiniMax-M2.7-highspeed is properly registered in const.py."""
|
||||
|
||||
def test_m2_7_highspeed_constant_defined(self):
|
||||
from common import const
|
||||
self.assertTrue(hasattr(const, "MINIMAX_M2_7_HIGHSPEED"))
|
||||
self.assertEqual(const.MINIMAX_M2_7_HIGHSPEED, "MiniMax-M2.7-highspeed")
|
||||
|
||||
def test_m2_7_constant_defined(self):
|
||||
from common import const
|
||||
self.assertEqual(const.MINIMAX_M2_7, "MiniMax-M2.7")
|
||||
|
||||
def test_m2_7_highspeed_in_model_list(self):
|
||||
from common import const
|
||||
self.assertIn("MiniMax-M2.7-highspeed", const.MODEL_LIST)
|
||||
|
||||
def test_m2_7_in_model_list(self):
|
||||
from common import const
|
||||
self.assertIn("MiniMax-M2.7", const.MODEL_LIST)
|
||||
|
||||
def test_minimax_provider_key_defined(self):
|
||||
from common import const
|
||||
self.assertEqual(const.MiniMax, "minimax")
|
||||
|
||||
|
||||
class TestMinimaxBotDefaultModel(unittest.TestCase):
|
||||
"""Test that MinimaxBot defaults to MiniMax-M2.7."""
|
||||
|
||||
def test_default_model_is_m2_7(self):
|
||||
# Patch conf() to return empty config
|
||||
mock_conf = MagicMock()
|
||||
mock_conf.get = MagicMock(side_effect=lambda key, default=None: default)
|
||||
|
||||
with patch("models.minimax.minimax_bot.conf", return_value=mock_conf):
|
||||
with patch("models.minimax.minimax_bot.SessionManager"):
|
||||
from models.minimax import minimax_bot
|
||||
# Reload to pick up patches
|
||||
import importlib
|
||||
importlib.reload(minimax_bot)
|
||||
with patch("models.minimax.minimax_bot.conf", return_value=mock_conf):
|
||||
bot = minimax_bot.MinimaxBot.__new__(minimax_bot.MinimaxBot)
|
||||
bot.args = {
|
||||
"model": mock_conf.get("model") or "MiniMax-M2.7",
|
||||
}
|
||||
self.assertEqual(bot.args["model"], "MiniMax-M2.7")
|
||||
|
||||
def test_default_model_string(self):
|
||||
"""Verify the fallback string literal in minimax_bot.py is MiniMax-M2.7."""
|
||||
import ast
|
||||
bot_path = os.path.join(os.path.dirname(__file__), "..", "models", "minimax", "minimax_bot.py")
|
||||
with open(bot_path) as f:
|
||||
source = f.read()
|
||||
# Verify MiniMax-M2.7 is in the source (not M2.1)
|
||||
self.assertIn("MiniMax-M2.7", source)
|
||||
self.assertNotIn('"MiniMax-M2.1"', source)
|
||||
|
||||
|
||||
class TestMinimaxVoice(unittest.TestCase):
|
||||
"""Test MinimaxVoice TTS provider."""
|
||||
|
||||
def _make_voice(self, api_key="test-key", api_base="https://api.minimax.io/v1"):
|
||||
mock_conf = MagicMock()
|
||||
def conf_get(key, default=None):
|
||||
return {
|
||||
"minimax_api_key": api_key,
|
||||
"minimax_api_base": api_base,
|
||||
}.get(key, default)
|
||||
mock_conf.get = conf_get
|
||||
with patch("voice.minimax.minimax_voice.conf", return_value=mock_conf):
|
||||
from voice.minimax.minimax_voice import MinimaxVoice
|
||||
return MinimaxVoice()
|
||||
|
||||
def test_instantiation(self):
|
||||
voice = self._make_voice()
|
||||
self.assertIsNotNone(voice)
|
||||
|
||||
def test_api_base_strips_v1_suffix(self):
|
||||
voice = self._make_voice(api_base="https://api.minimax.io/v1")
|
||||
self.assertEqual(voice.api_base, "https://api.minimax.io")
|
||||
|
||||
def test_api_base_no_trailing_slash(self):
|
||||
voice = self._make_voice(api_base="https://api.minimax.io")
|
||||
self.assertEqual(voice.api_base, "https://api.minimax.io")
|
||||
|
||||
def test_voice_to_text_not_supported(self):
|
||||
voice = self._make_voice()
|
||||
with self.assertRaises(NotImplementedError):
|
||||
voice.voiceToText("dummy.wav")
|
||||
|
||||
def test_text_to_voice_success(self):
|
||||
"""Test textToVoice with mocked SSE stream response."""
|
||||
import os
|
||||
os.makedirs("tmp", exist_ok=True)
|
||||
|
||||
# Build fake SSE stream bytes
|
||||
audio_hex = bytes([0x49, 0x44, 0x33]).hex() # "ID3" MP3 magic bytes
|
||||
sse_line = f'data: {{"data": {{"audio": "{audio_hex}", "status": 2}}}}\n\n'
|
||||
done_line = "data: [DONE]\n\n"
|
||||
fake_body = (sse_line + done_line).encode("utf-8")
|
||||
|
||||
mock_response = MagicMock()
|
||||
mock_response.raise_for_status = MagicMock()
|
||||
mock_response.iter_lines.return_value = [
|
||||
line.encode("utf-8") for line in (sse_line + done_line).splitlines() if line
|
||||
]
|
||||
|
||||
mock_conf = MagicMock()
|
||||
def conf_get(key, default=None):
|
||||
return {
|
||||
"minimax_api_key": "test-key",
|
||||
"minimax_api_base": "https://api.minimax.io",
|
||||
}.get(key, default)
|
||||
mock_conf.get = conf_get
|
||||
|
||||
with patch("voice.minimax.minimax_voice.conf", return_value=mock_conf):
|
||||
with patch("voice.minimax.minimax_voice.requests.post", return_value=mock_response):
|
||||
from voice.minimax import minimax_voice
|
||||
import importlib
|
||||
importlib.reload(minimax_voice)
|
||||
with patch("voice.minimax.minimax_voice.conf", return_value=mock_conf):
|
||||
voice = minimax_voice.MinimaxVoice()
|
||||
from bridge.reply import ReplyType
|
||||
reply = voice.textToVoice("Hello, world!")
|
||||
self.assertEqual(reply.type, ReplyType.VOICE)
|
||||
self.assertTrue(reply.content.endswith(".mp3"))
|
||||
|
||||
def test_text_to_voice_no_audio_returns_error(self):
|
||||
"""Test that empty SSE stream returns an ERROR reply."""
|
||||
mock_response = MagicMock()
|
||||
mock_response.raise_for_status = MagicMock()
|
||||
mock_response.iter_lines.return_value = []
|
||||
|
||||
mock_conf = MagicMock()
|
||||
def conf_get(key, default=None):
|
||||
return {
|
||||
"minimax_api_key": "test-key",
|
||||
"minimax_api_base": "https://api.minimax.io",
|
||||
}.get(key, default)
|
||||
mock_conf.get = conf_get
|
||||
|
||||
with patch("voice.minimax.minimax_voice.conf", return_value=mock_conf):
|
||||
with patch("voice.minimax.minimax_voice.requests.post", return_value=mock_response):
|
||||
from voice.minimax import minimax_voice
|
||||
import importlib
|
||||
importlib.reload(minimax_voice)
|
||||
with patch("voice.minimax.minimax_voice.conf", return_value=mock_conf):
|
||||
voice = minimax_voice.MinimaxVoice()
|
||||
from bridge.reply import ReplyType
|
||||
reply = voice.textToVoice("Hello")
|
||||
self.assertEqual(reply.type, ReplyType.ERROR)
|
||||
|
||||
|
||||
class TestVoiceFactory(unittest.TestCase):
|
||||
"""Test that minimax is registered in the voice factory."""
|
||||
|
||||
def test_minimax_voice_factory(self):
|
||||
mock_conf = MagicMock()
|
||||
mock_conf.get = MagicMock(return_value=None)
|
||||
with patch("voice.minimax.minimax_voice.conf", return_value=mock_conf):
|
||||
from voice.factory import create_voice
|
||||
voice = create_voice("minimax")
|
||||
from voice.minimax.minimax_voice import MinimaxVoice
|
||||
self.assertIsInstance(voice, MinimaxVoice)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -54,4 +54,8 @@ def create_voice(voice_type):
|
||||
from voice.tencent.tencent_voice import TencentVoice
|
||||
|
||||
return TencentVoice()
|
||||
elif voice_type == "minimax":
|
||||
from voice.minimax.minimax_voice import MinimaxVoice
|
||||
|
||||
return MinimaxVoice()
|
||||
raise RuntimeError
|
||||
|
||||
0
voice/minimax/__init__.py
Normal file
0
voice/minimax/__init__.py
Normal file
106
voice/minimax/minimax_voice.py
Normal file
106
voice/minimax/minimax_voice.py
Normal file
@@ -0,0 +1,106 @@
|
||||
# encoding:utf-8
|
||||
"""
|
||||
MiniMax TTS voice service
|
||||
"""
|
||||
import datetime
|
||||
import random
|
||||
import requests
|
||||
|
||||
from bridge.reply import Reply, ReplyType
|
||||
from common.log import logger
|
||||
from config import conf
|
||||
from voice.voice import Voice
|
||||
|
||||
|
||||
MINIMAX_TTS_VOICES = [
|
||||
"English_Graceful_Lady",
|
||||
"English_Insightful_Speaker",
|
||||
"English_radiant_girl",
|
||||
"English_Persuasive_Man",
|
||||
"English_Lucky_Robot",
|
||||
"English_expressive_narrator",
|
||||
"Chinese_Warm_Woman",
|
||||
"Chinese_Gentle_Man",
|
||||
]
|
||||
|
||||
|
||||
class MinimaxVoice(Voice):
|
||||
def __init__(self):
|
||||
self.api_key = conf().get("minimax_api_key")
|
||||
self.api_base = conf().get("minimax_api_base") or "https://api.minimax.io"
|
||||
# Strip trailing /v1 if present so we can always append /v1/t2a_v2
|
||||
self.api_base = self.api_base.rstrip("/")
|
||||
if self.api_base.endswith("/v1"):
|
||||
self.api_base = self.api_base[:-3]
|
||||
|
||||
def voiceToText(self, voice_file):
|
||||
"""MiniMax does not provide an ASR endpoint; raise NotImplementedError."""
|
||||
raise NotImplementedError("MiniMax voice-to-text is not supported")
|
||||
|
||||
def textToVoice(self, text):
|
||||
try:
|
||||
model = conf().get("text_to_voice_model") or "speech-2.8-hd"
|
||||
voice_id = conf().get("tts_voice_id") or "English_Graceful_Lady"
|
||||
|
||||
url = f"{self.api_base}/v1/t2a_v2"
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
}
|
||||
payload = {
|
||||
"model": model,
|
||||
"text": text,
|
||||
"stream": True,
|
||||
"voice_setting": {
|
||||
"voice_id": voice_id,
|
||||
"speed": 1,
|
||||
"vol": 1,
|
||||
"pitch": 0,
|
||||
},
|
||||
"audio_setting": {
|
||||
"sample_rate": 32000,
|
||||
"bitrate": 128000,
|
||||
"format": "mp3",
|
||||
"channel": 1,
|
||||
},
|
||||
}
|
||||
|
||||
response = requests.post(url, headers=headers, json=payload, stream=True, timeout=60)
|
||||
response.raise_for_status()
|
||||
|
||||
# Parse SSE stream and collect hex-encoded audio chunks
|
||||
audio_chunks = []
|
||||
buffer = ""
|
||||
for raw in response.iter_lines():
|
||||
if not raw:
|
||||
continue
|
||||
line = raw.decode("utf-8") if isinstance(raw, bytes) else raw
|
||||
if not line.startswith("data:"):
|
||||
continue
|
||||
json_str = line[5:].strip()
|
||||
if not json_str or json_str == "[DONE]":
|
||||
continue
|
||||
try:
|
||||
import json
|
||||
event_data = json.loads(json_str)
|
||||
audio_hex = event_data.get("data", {}).get("audio")
|
||||
if audio_hex:
|
||||
audio_chunks.append(bytes.fromhex(audio_hex))
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
if not audio_chunks:
|
||||
logger.error("[MINIMAX] TTS returned no audio data")
|
||||
return Reply(ReplyType.ERROR, "语音合成失败,未获取到音频数据")
|
||||
|
||||
audio_data = b"".join(audio_chunks)
|
||||
file_name = "tmp/" + datetime.datetime.now().strftime("%Y%m%d%H%M%S") + str(random.randint(0, 1000)) + ".mp3"
|
||||
with open(file_name, "wb") as f:
|
||||
f.write(audio_data)
|
||||
|
||||
logger.info(f"[MINIMAX] textToVoice success, file={file_name}")
|
||||
return Reply(ReplyType.VOICE, file_name)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"[MINIMAX] textToVoice error: {e}")
|
||||
return Reply(ReplyType.ERROR, "遇到了一点小问题,请稍后再试")
|
||||
Reference in New Issue
Block a user