mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-06-02 00:57:41 +08:00
Merge pull request #2852 from zhayujie/feat-i18n
feat: support i18n across the whole project
This commit is contained in:
90
README.md
90
README.md
@@ -13,8 +13,8 @@ CowAgent is lightweight, easy to deploy, and built to extend. Plug in any major
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://cowagent.ai/">🌐 Website</a> ·
|
<a href="https://cowagent.ai/">🌐 Website</a> ·
|
||||||
<a href="https://docs.cowagent.ai/en/intro/index">📖 Docs</a> ·
|
<a href="https://docs.cowagent.ai/intro/index">📖 Docs</a> ·
|
||||||
<a href="https://docs.cowagent.ai/en/guide/quick-start">🚀 Quick Start</a> ·
|
<a href="https://docs.cowagent.ai/guide/quick-start">🚀 Quick Start</a> ·
|
||||||
<a href="https://skills.cowagent.ai/">🧩 Skill Hub</a> ·
|
<a href="https://skills.cowagent.ai/">🧩 Skill Hub</a> ·
|
||||||
<a href="https://link-ai.tech/cowagent/create">☁️ Try Online</a>
|
<a href="https://link-ai.tech/cowagent/create">☁️ Try Online</a>
|
||||||
</p>
|
</p>
|
||||||
@@ -25,15 +25,15 @@ CowAgent is lightweight, easy to deploy, and built to extend. Plug in any major
|
|||||||
|
|
||||||
| Capability | Description |
|
| Capability | Description |
|
||||||
| :--- | :--- |
|
| :--- | :--- |
|
||||||
| [Planning](https://docs.cowagent.ai/en/intro/architecture) | Decomposes complex tasks and executes them step by step, looping over tools until the goal is reached |
|
| [Planning](https://docs.cowagent.ai/intro/architecture) | Decomposes complex tasks and executes them step by step, looping over tools until the goal is reached |
|
||||||
| [Memory](https://docs.cowagent.ai/en/memory/index) | Three-tier architecture (context → daily → core), automatic Deep Dream distillation, hybrid keyword + vector retrieval |
|
| [Memory](https://docs.cowagent.ai/memory/index) | Three-tier architecture (context → daily → core), automatic Deep Dream distillation, hybrid keyword + vector retrieval |
|
||||||
| [Knowledge](https://docs.cowagent.ai/en/knowledge/index) | Auto-curates structured knowledge into a Markdown wiki, builds an evolving knowledge graph with visual browsing |
|
| [Knowledge](https://docs.cowagent.ai/knowledge/index) | Auto-curates structured knowledge into a Markdown wiki, builds an evolving knowledge graph with visual browsing |
|
||||||
| [Skills](https://docs.cowagent.ai/en/skills/index) | One-click install from [Skill Hub](https://skills.cowagent.ai/), GitHub, ClawHub; or create custom skills via natural-language conversation |
|
| [Skills](https://docs.cowagent.ai/skills/index) | One-click install from [Skill Hub](https://skills.cowagent.ai/), GitHub, ClawHub; or create custom skills via natural-language conversation |
|
||||||
| [Tools](https://docs.cowagent.ai/en/tools/index) | Built-in file I/O, terminal, browser, scheduler, memory retrieval, web search, and 10+ more tools — with native MCP integration |
|
| [Tools](https://docs.cowagent.ai/tools/index) | Built-in file I/O, terminal, browser, scheduler, memory retrieval, web search, and 10+ more tools — with native MCP integration |
|
||||||
| [Channels](https://docs.cowagent.ai/en/channels/index) | Integrates with Web, WeChat, Feishu, DingTalk, WeCom, QQ, Official Accounts, Telegram, and Slack |
|
| [Channels](https://docs.cowagent.ai/channels/index) | Integrates with Web, WeChat, Feishu, DingTalk, WeCom, QQ, Official Accounts, Telegram, and Slack |
|
||||||
| Multimodal | First-class support for text, images, voice, and files — recognition, generation, and delivery |
|
| Multimodal | First-class support for text, images, voice, and files — recognition, generation, and delivery |
|
||||||
| [Models](https://docs.cowagent.ai/en/models/index) | Claude, GPT, Gemini, DeepSeek, Qwen, GLM, Kimi, MiniMax, Doubao, and more — swap providers from the Web console with one click |
|
| [Models](https://docs.cowagent.ai/models/index) | Claude, GPT, Gemini, DeepSeek, Qwen, GLM, Kimi, MiniMax, Doubao, and more — swap providers from the Web console with one click |
|
||||||
| [Deploy](https://docs.cowagent.ai/en/guide/quick-start) | One-line installer, unified Web console, multiple deployment modes (local, Docker, server) |
|
| [Deploy](https://docs.cowagent.ai/guide/quick-start) | One-line installer, unified Web console, multiple deployment modes (local, Docker, server) |
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ CowAgent is lightweight, easy to deploy, and built to extend. Plug in any major
|
|||||||
|
|
||||||
CowAgent is a complete **Agent Harness**: messages flow in through **Channels**; the **Agent Core** plans and reasons over memory, knowledge, and the available tools and skills; **Models** generate the response, which is sent back through the originating channel. Every layer is decoupled and independently extensible.
|
CowAgent is a complete **Agent Harness**: messages flow in through **Channels**; the **Agent Core** plans and reasons over memory, knowledge, and the available tools and skills; **Models** generate the response, which is sent back through the originating channel. Every layer is decoupled and independently extensible.
|
||||||
|
|
||||||
Read more in [Architecture](https://docs.cowagent.ai/en/intro/architecture).
|
Read more in [Architecture](https://docs.cowagent.ai/intro/architecture).
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
@@ -74,9 +74,9 @@ Once started, open `http://localhost:9899` to access the **Web console** — you
|
|||||||
|
|
||||||
> Deploying on a server? Set `web_host` to `0.0.0.0` in `config.json` to make the console reachable from outside, and set `web_password` to protect it. Don't forget to open port `9899` in your firewall or security group.
|
> Deploying on a server? Set `web_host` to `0.0.0.0` in `config.json` to make the console reachable from outside, and set `web_password` to protect it. Don't forget to open port `9899` in your firewall or security group.
|
||||||
|
|
||||||
> 📖 Detailed guides: [Quick Start](https://docs.cowagent.ai/en/guide/quick-start) · [Install from Source](https://docs.cowagent.ai/en/guide/manual-install) · [Upgrade](https://docs.cowagent.ai/en/guide/upgrade)
|
> 📖 Detailed guides: [Quick Start](https://docs.cowagent.ai/guide/quick-start) · [Install from Source](https://docs.cowagent.ai/guide/manual-install) · [Upgrade](https://docs.cowagent.ai/guide/upgrade)
|
||||||
|
|
||||||
After installation, manage the service with the [cow CLI](https://docs.cowagent.ai/en/cli/index):
|
After installation, manage the service with the [cow CLI](https://docs.cowagent.ai/cli/index):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cow start | stop | restart # service control
|
cow start | stop | restart # service control
|
||||||
@@ -94,21 +94,21 @@ CowAgent supports all mainstream LLM providers. **Chat, vision, image generation
|
|||||||
|
|
||||||
| Provider | Featured Models | Chat | Vision | Image Gen | ASR | TTS | Embedding |
|
| Provider | Featured Models | Chat | Vision | Image Gen | ASR | TTS | Embedding |
|
||||||
| --- | --- | :-: | :-: | :-: | :-: | :-: | :-: |
|
| --- | --- | :-: | :-: | :-: | :-: | :-: | :-: |
|
||||||
| [Claude](https://docs.cowagent.ai/en/models/claude) | claude-opus-4-8 | ✅ | ✅ | | | | |
|
| [Claude](https://docs.cowagent.ai/models/claude) | claude-opus-4-8 | ✅ | ✅ | | | | |
|
||||||
| [OpenAI](https://docs.cowagent.ai/en/models/openai) | gpt-5.5, o-series | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| [OpenAI](https://docs.cowagent.ai/models/openai) | gpt-5.5, o-series | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [Gemini](https://docs.cowagent.ai/en/models/gemini) | gemini-3.5-flash | ✅ | ✅ | ✅ | | | |
|
| [Gemini](https://docs.cowagent.ai/models/gemini) | gemini-3.5-flash | ✅ | ✅ | ✅ | | | |
|
||||||
| [DeepSeek](https://docs.cowagent.ai/en/models/deepseek) | deepseek-v4-flash / pro | ✅ | | | | | |
|
| [DeepSeek](https://docs.cowagent.ai/models/deepseek) | deepseek-v4-flash / pro | ✅ | | | | | |
|
||||||
| [Qwen](https://docs.cowagent.ai/en/models/qwen) | qwen3.7-max | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| [Qwen](https://docs.cowagent.ai/models/qwen) | qwen3.7-max | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [GLM](https://docs.cowagent.ai/en/models/glm) | glm-5.1, glm-5v-turbo | ✅ | ✅ | | ✅ | | ✅ |
|
| [GLM](https://docs.cowagent.ai/models/glm) | glm-5.1, glm-5v-turbo | ✅ | ✅ | | ✅ | | ✅ |
|
||||||
| [Doubao](https://docs.cowagent.ai/en/models/doubao) | doubao-seed-2.0 series | ✅ | ✅ | ✅ | | | ✅ |
|
| [Doubao](https://docs.cowagent.ai/models/doubao) | doubao-seed-2.0 series | ✅ | ✅ | ✅ | | | ✅ |
|
||||||
| [Kimi](https://docs.cowagent.ai/en/models/kimi) | kimi-k2.6 | ✅ | ✅ | | | | |
|
| [Kimi](https://docs.cowagent.ai/models/kimi) | kimi-k2.6 | ✅ | ✅ | | | | |
|
||||||
| [MiniMax](https://docs.cowagent.ai/en/models/minimax) | MiniMax-M2.7 | ✅ | ✅ | ✅ | | ✅ | |
|
| [MiniMax](https://docs.cowagent.ai/models/minimax) | MiniMax-M2.7 | ✅ | ✅ | ✅ | | ✅ | |
|
||||||
| [ERNIE](https://docs.cowagent.ai/en/models/qianfan) | ernie-5.1 | ✅ | ✅ | | | | |
|
| [ERNIE](https://docs.cowagent.ai/models/qianfan) | ernie-5.1 | ✅ | ✅ | | | | |
|
||||||
| [MiMo](https://docs.cowagent.ai/en/models/mimo) | mimo-v2.5 / pro | ✅ | ✅ | | | ✅ | |
|
| [MiMo](https://docs.cowagent.ai/models/mimo) | mimo-v2.5 / pro | ✅ | ✅ | | | ✅ | |
|
||||||
| [LinkAI](https://docs.cowagent.ai/en/models/linkai) | One key for 100+ models | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| [LinkAI](https://docs.cowagent.ai/models/linkai) | One key for 100+ models | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [Custom](https://docs.cowagent.ai/en/models/custom) | Local models / third-party proxy | ✅ | | | | | |
|
| [Custom](https://docs.cowagent.ai/models/custom) | Local models / third-party proxy | ✅ | | | | | |
|
||||||
|
|
||||||
> For details on each provider, see the [Models overview](https://docs.cowagent.ai/en/models/index).
|
> For details on each provider, see the [Models overview](https://docs.cowagent.ai/models/index).
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
@@ -118,20 +118,20 @@ A single Agent instance can serve multiple channels in parallel. Most channels c
|
|||||||
|
|
||||||
| Channel | Text | Image | File | Voice | Group |
|
| Channel | Text | Image | File | Voice | Group |
|
||||||
| --- | :-: | :-: | :-: | :-: | :-: |
|
| --- | :-: | :-: | :-: | :-: | :-: |
|
||||||
| [Web Console](https://docs.cowagent.ai/en/channels/web) (default) | ✅ | ✅ | ✅ | ✅ | |
|
| [Web Console](https://docs.cowagent.ai/channels/web) (default) | ✅ | ✅ | ✅ | ✅ | |
|
||||||
| [Telegram](https://docs.cowagent.ai/en/channels/telegram) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| [Telegram](https://docs.cowagent.ai/channels/telegram) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [Slack](https://docs.cowagent.ai/en/channels/slack) | ✅ | ✅ | ✅ | | ✅ |
|
| [Slack](https://docs.cowagent.ai/channels/slack) | ✅ | ✅ | ✅ | | ✅ |
|
||||||
| [Discord](https://docs.cowagent.ai/en/channels/discord) | ✅ | ✅ | ✅ | | ✅ |
|
| [Discord](https://docs.cowagent.ai/channels/discord) | ✅ | ✅ | ✅ | | ✅ |
|
||||||
| [WeChat](https://docs.cowagent.ai/en/channels/weixin) | ✅ | ✅ | ✅ | ✅ | |
|
| [WeChat](https://docs.cowagent.ai/channels/weixin) | ✅ | ✅ | ✅ | ✅ | |
|
||||||
| [Feishu / Lark](https://docs.cowagent.ai/en/channels/feishu) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| [Feishu / Lark](https://docs.cowagent.ai/channels/feishu) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [DingTalk](https://docs.cowagent.ai/en/channels/dingtalk) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| [DingTalk](https://docs.cowagent.ai/channels/dingtalk) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [WeCom Bot](https://docs.cowagent.ai/en/channels/wecom-bot) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| [WeCom Bot](https://docs.cowagent.ai/channels/wecom-bot) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [QQ](https://docs.cowagent.ai/en/channels/qq) | ✅ | ✅ | ✅ | | ✅ |
|
| [QQ](https://docs.cowagent.ai/channels/qq) | ✅ | ✅ | ✅ | | ✅ |
|
||||||
| [WeCom App](https://docs.cowagent.ai/en/channels/wecom) | ✅ | ✅ | ✅ | ✅ | |
|
| [WeCom App](https://docs.cowagent.ai/channels/wecom) | ✅ | ✅ | ✅ | ✅ | |
|
||||||
| [WeChat Customer Service](https://docs.cowagent.ai/en/channels/wechat-kf) | ✅ | ✅ | ✅ | ✅ | |
|
| [WeChat Customer Service](https://docs.cowagent.ai/channels/wechat-kf) | ✅ | ✅ | ✅ | ✅ | |
|
||||||
| [WeChat Official Account](https://docs.cowagent.ai/en/channels/wechatmp) | ✅ | ✅ | | ✅ | |
|
| [WeChat Official Account](https://docs.cowagent.ai/channels/wechatmp) | ✅ | ✅ | | ✅ | |
|
||||||
|
|
||||||
> See the [Channels overview](https://docs.cowagent.ai/en/channels/index) for setup details.
|
> See the [Channels overview](https://docs.cowagent.ai/channels/index) for setup details.
|
||||||
|
|
||||||
<img src="https://cdn.jsdelivr.net/gh/zhayujie/cowagent-assets@main/screenshots/en/web-console-chat.png" alt="CowAgent Web Console" width="800"/>
|
<img src="https://cdn.jsdelivr.net/gh/zhayujie/cowagent-assets@main/screenshots/en/web-console-chat.png" alt="CowAgent Web Console" width="800"/>
|
||||||
|
|
||||||
@@ -141,9 +141,9 @@ A single Agent instance can serve multiple channels in parallel. Most channels c
|
|||||||
|
|
||||||
## 🧠 Memory & Knowledge Base
|
## 🧠 Memory & Knowledge Base
|
||||||
|
|
||||||
**Long-term memory** uses a three-tier architecture: conversation context (short-term) → daily memory (mid-term) → MEMORY.md (long-term). A nightly **Deep Dream** pass distills scattered memories into refined long-term entries and a narrative journal. See [Long-term Memory](https://docs.cowagent.ai/en/memory/index) · [Deep Dream](https://docs.cowagent.ai/en/memory/deep-dream).
|
**Long-term memory** uses a three-tier architecture: conversation context (short-term) → daily memory (mid-term) → MEMORY.md (long-term). A nightly **Deep Dream** pass distills scattered memories into refined long-term entries and a narrative journal. See [Long-term Memory](https://docs.cowagent.ai/memory/index) · [Deep Dream](https://docs.cowagent.ai/memory/deep-dream).
|
||||||
|
|
||||||
**Personal knowledge base** complements the time-ordered memory by organizing structured knowledge **by topic**. The Agent automatically curates valuable information from conversations, maintains cross-references and indexes, and the Web console offers an interactive knowledge-graph view. See [Personal Knowledge Base](https://docs.cowagent.ai/en/knowledge/index).
|
**Personal knowledge base** complements the time-ordered memory by organizing structured knowledge **by topic**. The Agent automatically curates valuable information from conversations, maintains cross-references and indexes, and the Web console offers an interactive knowledge-graph view. See [Personal Knowledge Base](https://docs.cowagent.ai/knowledge/index).
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -170,7 +170,7 @@ A single Agent instance can serve multiple channels in parallel. Most channels c
|
|||||||
|
|
||||||
**MCP protocol** integrates the open ecosystem of [Model Context Protocol](https://modelcontextprotocol.io) servers. A single `mcp.json` is enough — supports stdio / SSE transports, hot reload, and zero-code integration.
|
**MCP protocol** integrates the open ecosystem of [Model Context Protocol](https://modelcontextprotocol.io) servers. A single `mcp.json` is enough — supports stdio / SSE transports, hot reload, and zero-code integration.
|
||||||
|
|
||||||
Learn more: [Tools overview](https://docs.cowagent.ai/en/tools/index) · [MCP integration](https://docs.cowagent.ai/en/tools/mcp).
|
Learn more: [Tools overview](https://docs.cowagent.ai/tools/index) · [MCP integration](https://docs.cowagent.ai/tools/mcp).
|
||||||
|
|
||||||
### Skills System
|
### Skills System
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ Learn more: [Tools overview](https://docs.cowagent.ai/en/tools/index) · [MCP in
|
|||||||
/skill install <name> # one-click install
|
/skill install <name> # one-click install
|
||||||
```
|
```
|
||||||
|
|
||||||
Learn more: [Skills overview](https://docs.cowagent.ai/en/skills/index) · [Creating Skills](https://docs.cowagent.ai/en/skills/create).
|
Learn more: [Skills overview](https://docs.cowagent.ai/skills/index) · [Creating Skills](https://docs.cowagent.ai/skills/create).
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
@@ -202,7 +202,7 @@ Learn more: [Skills overview](https://docs.cowagent.ai/en/skills/index) · [Crea
|
|||||||
|
|
||||||
> **2026.02.03:** [v2.0.0](https://github.com/zhayujie/CowAgent/releases/tag/2.0.0) — Major upgrade to a super Agent assistant with multi-step task planning, long-term memory, and the Skills framework.
|
> **2026.02.03:** [v2.0.0](https://github.com/zhayujie/CowAgent/releases/tag/2.0.0) — Major upgrade to a super Agent assistant with multi-step task planning, long-term memory, and the Skills framework.
|
||||||
|
|
||||||
Full history: [Release Notes](https://docs.cowagent.ai/en/releases/overview)
|
Full history: [Release Notes](https://docs.cowagent.ai/releases/overview)
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from datetime import datetime
|
|||||||
from common.log import logger
|
from common.log import logger
|
||||||
|
|
||||||
|
|
||||||
SUMMARIZE_SYSTEM_PROMPT = """你是一个对话记录助手。请将对话内容归纳为当天的日常记录。
|
SUMMARIZE_SYSTEM_PROMPT_ZH = """你是一个对话记录助手。请将对话内容归纳为当天的日常记录。
|
||||||
|
|
||||||
## 要求
|
## 要求
|
||||||
|
|
||||||
@@ -28,7 +28,23 @@ SUMMARIZE_SYSTEM_PROMPT = """你是一个对话记录助手。请将对话内容
|
|||||||
|
|
||||||
当对话没有任何记录价值(仅含问候或无意义内容),直接回复"无"。"""
|
当对话没有任何记录价值(仅含问候或无意义内容),直接回复"无"。"""
|
||||||
|
|
||||||
SUMMARIZE_USER_PROMPT = """请归纳以下对话的日常记录:
|
SUMMARIZE_SYSTEM_PROMPT_EN = """You are a conversation-logging assistant. Summarize the conversation into a daily record.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
Summarize by "event", not turn by turn:
|
||||||
|
- One item per line, starting with "- "
|
||||||
|
- Merge multiple turns about the same thing
|
||||||
|
- Only record meaningful events; ignore small talk and greetings
|
||||||
|
- Keep key decisions, conclusions and to-dos
|
||||||
|
|
||||||
|
If the conversation has no record value (only greetings or meaningless content), reply with exactly "None"."""
|
||||||
|
|
||||||
|
SUMMARIZE_USER_PROMPT_ZH = """请归纳以下对话的日常记录:
|
||||||
|
|
||||||
|
{conversation}"""
|
||||||
|
|
||||||
|
SUMMARIZE_USER_PROMPT_EN = """Summarize the daily record of the following conversation:
|
||||||
|
|
||||||
{conversation}"""
|
{conversation}"""
|
||||||
|
|
||||||
@@ -36,7 +52,7 @@ SUMMARIZE_USER_PROMPT = """请归纳以下对话的日常记录:
|
|||||||
# Deep Dream prompts — distill daily memories → MEMORY.md + dream diary
|
# Deep Dream prompts — distill daily memories → MEMORY.md + dream diary
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
DREAM_SYSTEM_PROMPT = """你是一个记忆整理助手,负责定期整理用户的长期记忆。
|
DREAM_SYSTEM_PROMPT_ZH = """你是一个记忆整理助手,负责定期整理用户的长期记忆。
|
||||||
|
|
||||||
你将收到两份材料:
|
你将收到两份材料:
|
||||||
1. **当前长期记忆** — MEMORY.md 的全部现有内容
|
1. **当前长期记忆** — MEMORY.md 的全部现有内容
|
||||||
@@ -80,7 +96,51 @@ MEMORY.md 会注入每次对话的系统提示词中,因此必须保持精炼
|
|||||||
梦境日记内容...
|
梦境日记内容...
|
||||||
```"""
|
```"""
|
||||||
|
|
||||||
DREAM_USER_PROMPT = """## 当前长期记忆(MEMORY.md)
|
DREAM_SYSTEM_PROMPT_EN = """You are a memory-curation assistant that periodically organizes the user's long-term memory.
|
||||||
|
|
||||||
|
You will receive two inputs:
|
||||||
|
1. **Current long-term memory** — the full existing content of MEMORY.md
|
||||||
|
2. **Today's diary** — the daily records
|
||||||
|
|
||||||
|
MEMORY.md is injected into the system prompt of every conversation, so it must stay concise and hold only valuable, memory-worthy content.
|
||||||
|
|
||||||
|
**Important: organize strictly based on the provided material. Never fabricate, infer, or add information not present in it.**
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
### Part 1: Updated long-term memory ([MEMORY])
|
||||||
|
|
||||||
|
Organize and distill on top of the existing memory, and output the complete updated content:
|
||||||
|
- **Merge & distill**: combine semantically similar items into one dense statement rather than listing them
|
||||||
|
- **Extract new**: pull memory-worthy new info from today's diary (preferences, decisions, people, rules, lessons)
|
||||||
|
- **Resolve conflicts**: when new info contradicts an old item, prefer the new and replace the old
|
||||||
|
- **Clean invalid**: remove temporary notes, blank items, formatting residue, meaningless or duplicate content
|
||||||
|
- **Drop redundancy**: delete old items already covered by a more concise statement
|
||||||
|
- One item per line, starting with "- ", without a date prefix
|
||||||
|
- You may group related items under "## headings" for clarity
|
||||||
|
- Goal: keep under 50 items, each ideally a single sentence
|
||||||
|
|
||||||
|
### Part 2: Dream diary ([DREAM])
|
||||||
|
|
||||||
|
Write a short diary in a concise narrative style recording what this curation found, keep it clean and readable:
|
||||||
|
- Which duplicates or conflicts were found
|
||||||
|
- What new insights were extracted from the diary
|
||||||
|
- What cleanup and optimization was done
|
||||||
|
- Overall feelings and observations
|
||||||
|
|
||||||
|
## Output format (follow strictly)
|
||||||
|
|
||||||
|
```
|
||||||
|
[MEMORY]
|
||||||
|
- memory item 1
|
||||||
|
- memory item 2
|
||||||
|
...
|
||||||
|
|
||||||
|
[DREAM]
|
||||||
|
dream diary content...
|
||||||
|
```"""
|
||||||
|
|
||||||
|
DREAM_USER_PROMPT_ZH = """## 当前长期记忆(MEMORY.md)
|
||||||
|
|
||||||
{memory_content}
|
{memory_content}
|
||||||
|
|
||||||
@@ -88,6 +148,47 @@ DREAM_USER_PROMPT = """## 当前长期记忆(MEMORY.md)
|
|||||||
|
|
||||||
{daily_content}"""
|
{daily_content}"""
|
||||||
|
|
||||||
|
DREAM_USER_PROMPT_EN = """## Current long-term memory (MEMORY.md)
|
||||||
|
|
||||||
|
{memory_content}
|
||||||
|
|
||||||
|
## Recent diary (last {days} days)
|
||||||
|
|
||||||
|
{daily_content}"""
|
||||||
|
|
||||||
|
|
||||||
|
def _is_en() -> bool:
|
||||||
|
"""True when the resolved UI language is English."""
|
||||||
|
try:
|
||||||
|
from common import i18n
|
||||||
|
return i18n.get_language() == "en"
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _summarize_system_prompt() -> str:
|
||||||
|
return SUMMARIZE_SYSTEM_PROMPT_EN if _is_en() else SUMMARIZE_SYSTEM_PROMPT_ZH
|
||||||
|
|
||||||
|
|
||||||
|
def _summarize_user_prompt() -> str:
|
||||||
|
return SUMMARIZE_USER_PROMPT_EN if _is_en() else SUMMARIZE_USER_PROMPT_ZH
|
||||||
|
|
||||||
|
|
||||||
|
def _dream_system_prompt() -> str:
|
||||||
|
return DREAM_SYSTEM_PROMPT_EN if _is_en() else DREAM_SYSTEM_PROMPT_ZH
|
||||||
|
|
||||||
|
|
||||||
|
def _dream_user_prompt() -> str:
|
||||||
|
return DREAM_USER_PROMPT_EN if _is_en() else DREAM_USER_PROMPT_ZH
|
||||||
|
|
||||||
|
|
||||||
|
def _is_empty_sentinel(text: str) -> bool:
|
||||||
|
"""Match the "no record value" sentinel in both zh ("无") and en ("None")."""
|
||||||
|
if not text:
|
||||||
|
return True
|
||||||
|
s = text.strip()
|
||||||
|
return s == "" or s == "无" or s.lower() == "none"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MemoryFlushManager:
|
class MemoryFlushManager:
|
||||||
@@ -224,7 +325,7 @@ class MemoryFlushManager:
|
|||||||
"""Background worker: summarize with LLM, write daily memory file."""
|
"""Background worker: summarize with LLM, write daily memory file."""
|
||||||
try:
|
try:
|
||||||
raw_summary = self._summarize_messages(messages, max_messages)
|
raw_summary = self._summarize_messages(messages, max_messages)
|
||||||
if not raw_summary or not raw_summary.strip() or raw_summary.strip() == "无":
|
if _is_empty_sentinel(raw_summary):
|
||||||
logger.info(f"[MemoryFlush] No valuable content to flush (reason={reason})")
|
logger.info(f"[MemoryFlush] No valuable content to flush (reason={reason})")
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -264,7 +365,7 @@ class MemoryFlushManager:
|
|||||||
def _clean_summary_output(raw: str) -> str:
|
def _clean_summary_output(raw: str) -> str:
|
||||||
"""Strip legacy [DAILY]/[MEMORY] markers if present, return clean daily text."""
|
"""Strip legacy [DAILY]/[MEMORY] markers if present, return clean daily text."""
|
||||||
raw = raw.strip()
|
raw = raw.strip()
|
||||||
if not raw or raw == "无":
|
if _is_empty_sentinel(raw):
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
# Strip [DAILY] marker
|
# Strip [DAILY] marker
|
||||||
@@ -355,7 +456,7 @@ class MemoryFlushManager:
|
|||||||
import time as _time
|
import time as _time
|
||||||
t0 = _time.monotonic()
|
t0 = _time.monotonic()
|
||||||
try:
|
try:
|
||||||
user_msg = DREAM_USER_PROMPT.format(
|
user_msg = _dream_user_prompt().format(
|
||||||
memory_content=memory_content or "(empty)",
|
memory_content=memory_content or "(empty)",
|
||||||
days=lookback_days,
|
days=lookback_days,
|
||||||
daily_content=daily_content or "(no recent daily records)",
|
daily_content=daily_content or "(no recent daily records)",
|
||||||
@@ -369,7 +470,7 @@ class MemoryFlushManager:
|
|||||||
temperature=0.3,
|
temperature=0.3,
|
||||||
max_tokens=dream_max_tokens,
|
max_tokens=dream_max_tokens,
|
||||||
stream=False,
|
stream=False,
|
||||||
system=DREAM_SYSTEM_PROMPT,
|
system=_dream_system_prompt(),
|
||||||
)
|
)
|
||||||
response = self.llm_model.call(request)
|
response = self.llm_model.call(request)
|
||||||
raw = self._extract_response_text(response)
|
raw = self._extract_response_text(response)
|
||||||
@@ -501,9 +602,9 @@ class MemoryFlushManager:
|
|||||||
if self.llm_model:
|
if self.llm_model:
|
||||||
try:
|
try:
|
||||||
summary = self._call_llm_for_summary(conversation_text)
|
summary = self._call_llm_for_summary(conversation_text)
|
||||||
if summary and summary.strip() and summary.strip() != "无":
|
if not _is_empty_sentinel(summary):
|
||||||
return summary.strip()
|
return summary.strip()
|
||||||
logger.info("[MemoryFlush] LLM returned empty or '无', skipping write")
|
logger.info("[MemoryFlush] LLM returned empty sentinel, skipping write")
|
||||||
return ""
|
return ""
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"[MemoryFlush] LLM summarization failed, using fallback: {e}")
|
logger.warning(f"[MemoryFlush] LLM summarization failed, using fallback: {e}")
|
||||||
@@ -579,11 +680,11 @@ class MemoryFlushManager:
|
|||||||
from agent.protocol.models import LLMRequest
|
from agent.protocol.models import LLMRequest
|
||||||
|
|
||||||
request = LLMRequest(
|
request = LLMRequest(
|
||||||
messages=[{"role": "user", "content": SUMMARIZE_USER_PROMPT.format(conversation=conversation_text)}],
|
messages=[{"role": "user", "content": _summarize_user_prompt().format(conversation=conversation_text)}],
|
||||||
temperature=0,
|
temperature=0,
|
||||||
max_tokens=500,
|
max_tokens=500,
|
||||||
stream=False,
|
stream=False,
|
||||||
system=SUMMARIZE_SYSTEM_PROMPT,
|
system=_summarize_system_prompt(),
|
||||||
)
|
)
|
||||||
|
|
||||||
response = self.llm_model.call(request)
|
response = self.llm_model.call(request)
|
||||||
|
|||||||
@@ -15,13 +15,13 @@ from config import conf
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ContextFile:
|
class ContextFile:
|
||||||
"""上下文文件"""
|
"""A context file (path + content)."""
|
||||||
path: str
|
path: str
|
||||||
content: str
|
content: str
|
||||||
|
|
||||||
|
|
||||||
class PromptBuilder:
|
class PromptBuilder:
|
||||||
"""提示词构建器"""
|
"""System prompt builder."""
|
||||||
|
|
||||||
def __init__(self, workspace_dir: str, language: str = "zh"):
|
def __init__(self, workspace_dir: str, language: str = "zh"):
|
||||||
"""
|
"""
|
||||||
@@ -88,97 +88,144 @@ def build_agent_system_prompt(
|
|||||||
**kwargs
|
**kwargs
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
构建Agent系统提示词
|
Build the agent system prompt.
|
||||||
|
|
||||||
顺序说明(按重要性和逻辑关系排列):
|
Section order (by importance and logical flow):
|
||||||
1. 工具系统 - 核心能力,最先介绍
|
1. Tooling - core capabilities, introduced first
|
||||||
2. 技能系统 - 紧跟工具,因为技能需要用 read 工具读取
|
2. Skills - right after tools, since skills are read via the read tool
|
||||||
3. 记忆系统 - 记忆检索与写入引导
|
3. Memory - memory recall and writing guidance
|
||||||
3.5 知识系统 - 结构化知识库(knowledge/index.md 注入)
|
3.5 Knowledge - structured knowledge base (injects knowledge/index.md)
|
||||||
4. 工作空间 - 工作环境说明
|
4. Workspace - working environment description
|
||||||
5. 用户身份 - 用户信息(可选)
|
5. User identity - user info (optional)
|
||||||
6. 项目上下文 - AGENT.md, USER.md, RULE.md, MEMORY.md, BOOTSTRAP.md
|
6. Project context - AGENT.md, USER.md, RULE.md, MEMORY.md, BOOTSTRAP.md
|
||||||
7. 运行时信息 - 元信息(时间、模型等)
|
7. Runtime info - meta info (time, model, etc.)
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
workspace_dir: 工作空间目录
|
workspace_dir: workspace directory
|
||||||
language: 语言 ("zh" 或 "en")
|
language: language ("zh" or "en")
|
||||||
base_persona: 基础人格描述(已废弃,由AGENT.md定义)
|
base_persona: base persona description (deprecated, defined by AGENT.md)
|
||||||
user_identity: 用户身份信息
|
user_identity: user identity info
|
||||||
tools: 工具列表
|
tools: tool list
|
||||||
context_files: 上下文文件列表
|
context_files: context file list
|
||||||
skill_manager: 技能管理器
|
skill_manager: skill manager
|
||||||
memory_manager: 记忆管理器
|
memory_manager: memory manager
|
||||||
runtime_info: 运行时信息
|
runtime_info: runtime info
|
||||||
**kwargs: 其他参数
|
**kwargs: extra args
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
完整的系统提示词
|
The full system prompt.
|
||||||
"""
|
"""
|
||||||
sections = []
|
sections = []
|
||||||
|
|
||||||
# 1. 工具系统(最重要,放在最前面)
|
# 1. Tooling (most important, goes first)
|
||||||
if tools:
|
if tools:
|
||||||
sections.extend(_build_tooling_section(tools, language))
|
sections.extend(_build_tooling_section(tools, language))
|
||||||
|
|
||||||
# 2. 技能系统(紧跟工具,因为需要用 read 工具)
|
# 2. Skills (right after tools, since they need the read tool)
|
||||||
if skill_manager:
|
if skill_manager:
|
||||||
sections.extend(_build_skills_section(skill_manager, tools, language))
|
sections.extend(_build_skills_section(skill_manager, tools, language))
|
||||||
|
|
||||||
# 3. 记忆系统(独立的记忆能力)
|
# 3. Memory (standalone memory capability)
|
||||||
if memory_manager:
|
if memory_manager:
|
||||||
sections.extend(_build_memory_section(memory_manager, tools, language))
|
sections.extend(_build_memory_section(memory_manager, tools, language))
|
||||||
|
|
||||||
# 3.5 知识系统(结构化知识库)
|
# 3.5 Knowledge (structured knowledge base)
|
||||||
if conf().get("knowledge", True):
|
if conf().get("knowledge", True):
|
||||||
sections.extend(_build_knowledge_section(workspace_dir, language))
|
sections.extend(_build_knowledge_section(workspace_dir, language))
|
||||||
|
|
||||||
# 4. 工作空间(工作环境说明)
|
# 4. Workspace (working environment description)
|
||||||
sections.extend(_build_workspace_section(workspace_dir, language))
|
sections.extend(_build_workspace_section(workspace_dir, language))
|
||||||
|
|
||||||
# 5. 用户身份(如果有)
|
# 5. User identity (if present)
|
||||||
if user_identity:
|
if user_identity:
|
||||||
sections.extend(_build_user_identity_section(user_identity, language))
|
sections.extend(_build_user_identity_section(user_identity, language))
|
||||||
|
|
||||||
# 6. 项目上下文文件(AGENT.md, USER.md, RULE.md - 定义人格)
|
# 6. Project context files (AGENT.md, USER.md, RULE.md - define the persona)
|
||||||
if context_files:
|
if context_files:
|
||||||
sections.extend(_build_context_files_section(context_files, language))
|
sections.extend(_build_context_files_section(context_files, language))
|
||||||
|
|
||||||
# 7. 运行时信息(元信息,放在最后)
|
# 7. Runtime info (meta info, goes last)
|
||||||
if runtime_info:
|
if runtime_info:
|
||||||
sections.extend(_build_runtime_section(runtime_info, language))
|
sections.extend(_build_runtime_section(runtime_info, language))
|
||||||
|
|
||||||
|
# 8. Response language (always appended, independent of the skeleton language)
|
||||||
|
sections.extend(_build_response_language_section(language))
|
||||||
|
|
||||||
return "\n".join(sections)
|
return "\n".join(sections)
|
||||||
|
|
||||||
|
|
||||||
|
def _build_response_language_section(language: str) -> List[str]:
|
||||||
|
"""Response-language rule, appended regardless of the prompt skeleton language.
|
||||||
|
|
||||||
|
Keeps the agent's reply language aligned with the user's input by default,
|
||||||
|
so a Chinese-built prompt still answers an English user in English.
|
||||||
|
"""
|
||||||
|
if language == "en":
|
||||||
|
return [
|
||||||
|
"## 🌐 Response language",
|
||||||
|
"",
|
||||||
|
"By default, reply in the same language as the user's input, "
|
||||||
|
"unless the user explicitly asks for another language.",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
return [
|
||||||
|
"## 🌐 回复语言",
|
||||||
|
"",
|
||||||
|
"默认使用与用户输入相同的语言回复,除非用户明确要求使用其他语言。",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def _build_identity_section(base_persona: Optional[str], language: str) -> List[str]:
|
def _build_identity_section(base_persona: Optional[str], language: str) -> List[str]:
|
||||||
"""构建基础身份section - 不再需要,身份由AGENT.md定义"""
|
"""Base identity section - no longer needed, identity is defined by AGENT.md."""
|
||||||
# 不再生成基础身份section,完全由AGENT.md定义
|
# Identity is fully defined by AGENT.md, so emit nothing here.
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def _build_tooling_section(tools: List[Any], language: str) -> List[str]:
|
def _build_tooling_section(tools: List[Any], language: str) -> List[str]:
|
||||||
"""Build tooling section with concise tool list and call style guide."""
|
"""Build tooling section with concise tool list and call style guide."""
|
||||||
|
is_en = language == "en"
|
||||||
# One-line summaries for known tools (details are in the tool schema)
|
# One-line summaries for known tools (details are in the tool schema)
|
||||||
core_summaries = {
|
if is_en:
|
||||||
"read": "读取文件内容",
|
core_summaries = {
|
||||||
"write": "创建或覆盖文件",
|
"read": "read file content",
|
||||||
"edit": "精确编辑文件",
|
"write": "create or overwrite a file",
|
||||||
"ls": "列出目录内容",
|
"edit": "make precise edits to a file",
|
||||||
"grep": "搜索文件内容",
|
"ls": "list directory contents",
|
||||||
"find": "按模式查找文件",
|
"grep": "search file contents",
|
||||||
"bash": "执行shell命令",
|
"find": "find files by pattern",
|
||||||
"terminal": "管理后台进程",
|
"bash": "run shell commands",
|
||||||
"web_search": "网络搜索",
|
"terminal": "manage background processes",
|
||||||
"web_fetch": "获取URL内容",
|
"web_search": "web search",
|
||||||
"browser": "控制浏览器(关键结果或需要协助可截图发送给用户)",
|
"web_fetch": "fetch URL content",
|
||||||
"memory_search": "搜索记忆",
|
"browser": "control the browser (screenshot key results or send to the user when help is needed)",
|
||||||
"memory_get": "读取记忆内容",
|
"memory_search": "search memory",
|
||||||
"env_config": "管理API密钥和技能配置",
|
"memory_get": "read memory content",
|
||||||
"scheduler": "管理定时任务和提醒",
|
"env_config": "manage API keys and skill config",
|
||||||
"send": "发送本地文件给用户(仅限本地文件,URL直接放在回复文本中)",
|
"scheduler": "manage scheduled tasks and reminders",
|
||||||
"vision": "分析图片内容(识别、描述、OCR文字提取等)",
|
"send": "send a local file to the user (local files only; put URLs directly in the reply text)",
|
||||||
}
|
"vision": "analyze images (recognition, description, OCR, etc.)",
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
core_summaries = {
|
||||||
|
"read": "读取文件内容",
|
||||||
|
"write": "创建或覆盖文件",
|
||||||
|
"edit": "精确编辑文件",
|
||||||
|
"ls": "列出目录内容",
|
||||||
|
"grep": "搜索文件内容",
|
||||||
|
"find": "按模式查找文件",
|
||||||
|
"bash": "执行shell命令",
|
||||||
|
"terminal": "管理后台进程",
|
||||||
|
"web_search": "网络搜索",
|
||||||
|
"web_fetch": "获取URL内容",
|
||||||
|
"browser": "控制浏览器(关键结果或需要协助可截图发送给用户)",
|
||||||
|
"memory_search": "搜索记忆",
|
||||||
|
"memory_get": "读取记忆内容",
|
||||||
|
"env_config": "管理API密钥和技能配置",
|
||||||
|
"scheduler": "管理定时任务和提醒",
|
||||||
|
"send": "发送本地文件给用户(仅限本地文件,URL直接放在回复文本中)",
|
||||||
|
"vision": "分析图片内容(识别、描述、OCR文字提取等)",
|
||||||
|
}
|
||||||
|
|
||||||
# Preferred display order
|
# Preferred display order
|
||||||
tool_order = [
|
tool_order = [
|
||||||
@@ -205,30 +252,46 @@ def _build_tooling_section(tools: List[Any], language: str) -> List[str]:
|
|||||||
summary = available[name]
|
summary = available[name]
|
||||||
tool_lines.append(f"- {name}: {summary}" if summary else f"- {name}")
|
tool_lines.append(f"- {name}: {summary}" if summary else f"- {name}")
|
||||||
|
|
||||||
lines = [
|
if is_en:
|
||||||
"## 🔧 工具系统",
|
lines = [
|
||||||
"",
|
"## 🔧 Tooling",
|
||||||
"可用工具(名称大小写敏感,严格按列表调用):",
|
"",
|
||||||
"\n".join(tool_lines),
|
"Available tools (names are case-sensitive, call exactly as listed):",
|
||||||
"",
|
"\n".join(tool_lines),
|
||||||
"工具调用风格:",
|
"",
|
||||||
"",
|
"Tool-calling style:",
|
||||||
"- 多步骤任务、复杂决策、敏感操作时,应简要说明当前在做什么、为什么这样做,让用户了解关键进展",
|
"",
|
||||||
"- 持续推进直到任务完成,完成后向用户报告结果",
|
"- For multi-step tasks, complex decisions or sensitive operations, briefly explain what you are doing and why, so the user follows key progress",
|
||||||
"- 回复中涉及密钥、令牌等敏感信息必须脱敏",
|
"- Keep going until the task is done, then report the result to the user",
|
||||||
"- URL链接直接放在回复文本中即可,系统会自动处理和渲染。无需下载后使用send工具发送",
|
"- Always redact secrets, tokens and other sensitive info in replies",
|
||||||
"",
|
"- Put URLs directly in the reply text; the system handles and renders them. Don't download and re-send them via the send tool",
|
||||||
]
|
"",
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
lines = [
|
||||||
|
"## 🔧 工具系统",
|
||||||
|
"",
|
||||||
|
"可用工具(名称大小写敏感,严格按列表调用):",
|
||||||
|
"\n".join(tool_lines),
|
||||||
|
"",
|
||||||
|
"工具调用风格:",
|
||||||
|
"",
|
||||||
|
"- 多步骤任务、复杂决策、敏感操作时,应简要说明当前在做什么、为什么这样做,让用户了解关键进展",
|
||||||
|
"- 持续推进直到任务完成,完成后向用户报告结果",
|
||||||
|
"- 回复中涉及密钥、令牌等敏感信息必须脱敏",
|
||||||
|
"- URL链接直接放在回复文本中即可,系统会自动处理和渲染。无需下载后使用send工具发送",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
|
|
||||||
def _build_skills_section(skill_manager: Any, tools: Optional[List[Any]], language: str) -> List[str]:
|
def _build_skills_section(skill_manager: Any, tools: Optional[List[Any]], language: str) -> List[str]:
|
||||||
"""构建技能系统section"""
|
"""Build the skills section."""
|
||||||
if not skill_manager:
|
if not skill_manager:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
# 获取read工具名称
|
# Resolve the read tool name
|
||||||
read_tool_name = "read"
|
read_tool_name = "read"
|
||||||
if tools:
|
if tools:
|
||||||
for tool in tools:
|
for tool in tools:
|
||||||
@@ -237,23 +300,40 @@ def _build_skills_section(skill_manager: Any, tools: Optional[List[Any]], langua
|
|||||||
read_tool_name = tool_name
|
read_tool_name = tool_name
|
||||||
break
|
break
|
||||||
|
|
||||||
lines = [
|
if language == "en":
|
||||||
"## 🧩 技能系统(mandatory)",
|
lines = [
|
||||||
"",
|
"## 🧩 Skills (mandatory)",
|
||||||
"在回复之前:扫描下方 <available_skills> 中每个技能的 <description>。",
|
"",
|
||||||
"",
|
"Before replying: scan the <description> of every skill in <available_skills> below.",
|
||||||
f"- 如果有技能的描述与用户需求匹配:使用 `{read_tool_name}` 工具读取其 <location> 路径的 SKILL.md 文件,然后严格遵循文件中的指令。"
|
"",
|
||||||
"当有匹配的技能时,应优先使用技能",
|
f"- If a skill's description matches the user's need: use the `{read_tool_name}` tool to read the SKILL.md at its <location> path, then strictly follow the instructions in the file. "
|
||||||
"- 如果多个技能都适用则选择最匹配的一个,然后读取并遵循。",
|
"Prefer using a skill when one matches.",
|
||||||
"- 如果没有技能明确适用:不要读取任何 SKILL.md,直接使用通用工具。",
|
"- If multiple skills apply, pick the best-matching one, then read and follow it.",
|
||||||
"",
|
"- If no skill clearly applies: do not read any SKILL.md, just use the general tools.",
|
||||||
f"**重要**: 技能不是工具,不能直接调用。使用技能的唯一方式是用 `{read_tool_name}` 读取 SKILL.md 文件,然后按文件内容操作。"
|
"",
|
||||||
"永远不要一次性读取多个技能,只在选择后再读取。",
|
f"**Important**: skills are not tools and cannot be called directly. The only way to use a skill is to read its SKILL.md with `{read_tool_name}`, then act on the file's content. "
|
||||||
"",
|
"Never read multiple skills at once — only read one after selecting it.",
|
||||||
"以下是可用技能:"
|
"",
|
||||||
]
|
"Available skills:"
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
lines = [
|
||||||
|
"## 🧩 技能系统(mandatory)",
|
||||||
|
"",
|
||||||
|
"在回复之前:扫描下方 <available_skills> 中每个技能的 <description>。",
|
||||||
|
"",
|
||||||
|
f"- 如果有技能的描述与用户需求匹配:使用 `{read_tool_name}` 工具读取其 <location> 路径的 SKILL.md 文件,然后严格遵循文件中的指令。"
|
||||||
|
"当有匹配的技能时,应优先使用技能",
|
||||||
|
"- 如果多个技能都适用则选择最匹配的一个,然后读取并遵循。",
|
||||||
|
"- 如果没有技能明确适用:不要读取任何 SKILL.md,直接使用通用工具。",
|
||||||
|
"",
|
||||||
|
f"**重要**: 技能不是工具,不能直接调用。使用技能的唯一方式是用 `{read_tool_name}` 读取 SKILL.md 文件,然后按文件内容操作。"
|
||||||
|
"永远不要一次性读取多个技能,只在选择后再读取。",
|
||||||
|
"",
|
||||||
|
"以下是可用技能:"
|
||||||
|
]
|
||||||
|
|
||||||
# 添加技能列表(通过skill_manager获取)
|
# Append the skills list (built by skill_manager)
|
||||||
try:
|
try:
|
||||||
skills_prompt = skill_manager.build_skills_prompt()
|
skills_prompt = skill_manager.build_skills_prompt()
|
||||||
logger.debug(f"[PromptBuilder] Skills prompt length: {len(skills_prompt) if skills_prompt else 0}")
|
logger.debug(f"[PromptBuilder] Skills prompt length: {len(skills_prompt) if skills_prompt else 0}")
|
||||||
@@ -271,7 +351,7 @@ def _build_skills_section(skill_manager: Any, tools: Optional[List[Any]], langua
|
|||||||
|
|
||||||
|
|
||||||
def _build_memory_section(memory_manager: Any, tools: Optional[List[Any]], language: str) -> List[str]:
|
def _build_memory_section(memory_manager: Any, tools: Optional[List[Any]], language: str) -> List[str]:
|
||||||
"""构建记忆系统section"""
|
"""Build the memory section."""
|
||||||
if not memory_manager:
|
if not memory_manager:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@@ -286,43 +366,82 @@ def _build_memory_section(memory_manager: Any, tools: Optional[List[Any]], langu
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
today_file = datetime.now().strftime("%Y-%m-%d") + ".md"
|
today_file = datetime.now().strftime("%Y-%m-%d") + ".md"
|
||||||
|
|
||||||
lines = [
|
if language == "en":
|
||||||
"## 🧠 记忆系统",
|
lines = [
|
||||||
"",
|
"## 🧠 Memory",
|
||||||
"### Memory Recall(mandatory)",
|
"",
|
||||||
"",
|
"### Memory Recall (mandatory)",
|
||||||
"当用户询问过往事件、引用之前的决定、提到人物关系、偏好、待办、或你对某事不确定时,**必须先检索记忆再回答**。",
|
"",
|
||||||
"如果 MEMORY.md 中已有相关信息则无需重复检索。完整内容和每日记忆需要通过工具检索。",
|
"When the user asks about past events, references an earlier decision, mentions relationships, preferences or to-dos, or when you are unsure about something, **you must search memory before answering**.",
|
||||||
"",
|
"No need to re-search if the info is already in MEMORY.md. Full content and daily memory must be retrieved via tools.",
|
||||||
"1. 不确定位置 → `memory_search` 关键词/语义检索",
|
"",
|
||||||
"2. 已知位置 → `memory_get` 直接读取对应行",
|
"1. Location unknown → `memory_search` (keyword / semantic search)",
|
||||||
"3. search 无结果 → `memory_get` 读最近两天记忆",
|
"2. Location known → `memory_get` to read the exact lines",
|
||||||
"",
|
"3. Search returns nothing → `memory_get` to read the last two days of memory",
|
||||||
"**记忆文件结构**:",
|
"",
|
||||||
"- `MEMORY.md`: 长期记忆索引(已自动加载到上下文,核心信息、偏好、决策等)",
|
"**Memory file structure**:",
|
||||||
f"- `memory/YYYY-MM-DD.md`: 每日记忆,今天是 `memory/{today_file}`",
|
"- `MEMORY.md`: long-term memory index (already auto-loaded into context: core info, preferences, decisions, etc.)",
|
||||||
"- `knowledge/`: 结构化知识库(见下方知识系统)",
|
f"- `memory/YYYY-MM-DD.md`: daily memory; today is `memory/{today_file}`",
|
||||||
"",
|
"- `knowledge/`: structured knowledge base (see the knowledge system below)",
|
||||||
"### 写入记忆",
|
"",
|
||||||
"",
|
"### Writing memory",
|
||||||
"遇到以下情况时,**主动**将信息写入记忆文件(无需告知用户):",
|
"",
|
||||||
"",
|
"In the following cases, **proactively** write info to memory files (no need to tell the user):",
|
||||||
"- 用户要求记住某些信息,或使用了「记住」「以后」「总是」「不要」「偏好」等表达",
|
"",
|
||||||
"- 用户分享了重要的个人偏好、习惯、决策",
|
"- The user asks you to remember something, or uses words like \"remember\", \"from now on\", \"always\", \"never\", \"prefer\"",
|
||||||
"- 对话中产生了重要的结论、方案、约定",
|
"- The user shares important personal preferences, habits or decisions",
|
||||||
"- 完成了复杂任务,值得记录关键步骤和结果",
|
"- The conversation produces an important conclusion, plan or agreement",
|
||||||
"",
|
"- A complex task is completed and the key steps and results are worth recording",
|
||||||
"**存储规则**:",
|
"",
|
||||||
f"- 长期核心信息 → `MEMORY.md`",
|
"**Storage rules**:",
|
||||||
f"- 当天事件/进展 → `memory/{today_file}`",
|
"- Long-term core info → `MEMORY.md`",
|
||||||
"- 结构化知识 → `knowledge/`(见知识系统)",
|
f"- Today's events/progress → `memory/{today_file}`",
|
||||||
"- 追加 → `edit` 工具,oldText 留空",
|
"- Structured knowledge → `knowledge/` (see the knowledge system)",
|
||||||
"- 修改 → `edit` 工具,oldText 填写要替换的文本",
|
"- Append → `edit` tool with empty oldText",
|
||||||
"- **禁止写入敏感信息**(API密钥、令牌等)",
|
"- Modify → `edit` tool with oldText set to the text to replace",
|
||||||
"",
|
"- **Never write sensitive info** (API keys, tokens, etc.)",
|
||||||
"**使用原则**: 自然使用记忆,就像你本来就知道;不用刻意提起,除非用户问起。",
|
"",
|
||||||
"",
|
"**Principle**: use memory naturally, as if you simply knew it; don't bring it up unless asked.",
|
||||||
]
|
"",
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
lines = [
|
||||||
|
"## 🧠 记忆系统",
|
||||||
|
"",
|
||||||
|
"### Memory Recall(mandatory)",
|
||||||
|
"",
|
||||||
|
"当用户询问过往事件、引用之前的决定、提到人物关系、偏好、待办、或你对某事不确定时,**必须先检索记忆再回答**。",
|
||||||
|
"如果 MEMORY.md 中已有相关信息则无需重复检索。完整内容和每日记忆需要通过工具检索。",
|
||||||
|
"",
|
||||||
|
"1. 不确定位置 → `memory_search` 关键词/语义检索",
|
||||||
|
"2. 已知位置 → `memory_get` 直接读取对应行",
|
||||||
|
"3. search 无结果 → `memory_get` 读最近两天记忆",
|
||||||
|
"",
|
||||||
|
"**记忆文件结构**:",
|
||||||
|
"- `MEMORY.md`: 长期记忆索引(已自动加载到上下文,核心信息、偏好、决策等)",
|
||||||
|
f"- `memory/YYYY-MM-DD.md`: 每日记忆,今天是 `memory/{today_file}`",
|
||||||
|
"- `knowledge/`: 结构化知识库(见下方知识系统)",
|
||||||
|
"",
|
||||||
|
"### 写入记忆",
|
||||||
|
"",
|
||||||
|
"遇到以下情况时,**主动**将信息写入记忆文件(无需告知用户):",
|
||||||
|
"",
|
||||||
|
"- 用户要求记住某些信息,或使用了「记住」「以后」「总是」「不要」「偏好」等表达",
|
||||||
|
"- 用户分享了重要的个人偏好、习惯、决策",
|
||||||
|
"- 对话中产生了重要的结论、方案、约定",
|
||||||
|
"- 完成了复杂任务,值得记录关键步骤和结果",
|
||||||
|
"",
|
||||||
|
"**存储规则**:",
|
||||||
|
f"- 长期核心信息 → `MEMORY.md`",
|
||||||
|
f"- 当天事件/进展 → `memory/{today_file}`",
|
||||||
|
"- 结构化知识 → `knowledge/`(见知识系统)",
|
||||||
|
"- 追加 → `edit` 工具,oldText 留空",
|
||||||
|
"- 修改 → `edit` 工具,oldText 填写要替换的文本",
|
||||||
|
"- **禁止写入敏感信息**(API密钥、令牌等)",
|
||||||
|
"",
|
||||||
|
"**使用原则**: 自然使用记忆,就像你本来就知道;不用刻意提起,除非用户问起。",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
@@ -339,37 +458,61 @@ def _build_knowledge_section(workspace_dir: str, language: str) -> List[str]:
|
|||||||
except Exception:
|
except Exception:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
lines = [
|
if language == "en":
|
||||||
"## 📚 知识系统",
|
lines = [
|
||||||
"",
|
"## 📚 Knowledge",
|
||||||
"你拥有一个持续积累的个人知识库 `knowledge/`,这是你的长期结构化知识存储。",
|
"",
|
||||||
"",
|
"You have a continuously growing personal knowledge base `knowledge/` — your long-term structured knowledge store.",
|
||||||
"### 自动写入规则(mandatory)",
|
"",
|
||||||
"",
|
"### Auto-write rules (mandatory)",
|
||||||
"以下场景**必须**在回复的同时写入知识库,**直接写入,不要询问用户是否需要**:",
|
"",
|
||||||
"",
|
"In the following cases you **must** write to the knowledge base alongside your reply, **directly, without asking the user**:",
|
||||||
"1. **用户分享了文章/链接/文档** → 阅读理解后,在同一轮回复中将要点写入 `knowledge/sources/<slug>.md`",
|
"",
|
||||||
"2. **深度讨论产生了结论/方案** → 整理为 `knowledge/analysis/<slug>.md`",
|
"1. **User shares an article / link / document** → after reading and understanding, write the key points to `knowledge/sources/<slug>.md` in the same turn",
|
||||||
"3. **对话涉及重要实体**(人物/公司/项目)→ 创建或更新 `knowledge/entities/<name>.md`",
|
"2. **An in-depth discussion produces a conclusion / plan** → organize it into `knowledge/analysis/<slug>.md`",
|
||||||
"4. **讨论了技术概念/方法论** → 整理为 `knowledge/concepts/<topic>.md`",
|
"3. **The conversation involves an important entity** (person / company / project) → create or update `knowledge/entities/<name>.md`",
|
||||||
"",
|
"4. **A technical concept / methodology is discussed** → organize it into `knowledge/concepts/<topic>.md`",
|
||||||
"每次写入知识页面后,**必须同步更新** `knowledge/index.md` 添加一行索引。",
|
"",
|
||||||
"详细的页面格式和操作规范,请读取技能 `knowledge-wiki` 的 SKILL.md。",
|
"After writing any knowledge page, you **must update** `knowledge/index.md` with a new index line in sync.",
|
||||||
"",
|
"For detailed page format and conventions, read the SKILL.md of the `knowledge-wiki` skill.",
|
||||||
"⚠️ 不要问「要不要存到知识库」——符合上述场景就直接写入,这是你的本能行为。",
|
"",
|
||||||
"",
|
"⚠️ Don't ask \"should I save this to the knowledge base?\" — if a case above matches, just write it. This is instinctive.",
|
||||||
]
|
"",
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
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:
|
if index_content:
|
||||||
lines.extend([
|
lines.extend([
|
||||||
"### 当前知识索引",
|
("### Current knowledge index" if language == "en" else "### 当前知识索引"),
|
||||||
"",
|
"",
|
||||||
index_content,
|
index_content,
|
||||||
"",
|
"",
|
||||||
])
|
])
|
||||||
|
|
||||||
lines.extend([
|
lines.extend([
|
||||||
"**查询方式**:用 `read` 读取知识页面,或用 `memory_search` 检索(知识已纳入向量索引)。",
|
("**How to query**: use `read` to open a knowledge page, or `memory_search` (knowledge is in the vector index)."
|
||||||
|
if language == "en" else
|
||||||
|
"**查询方式**:用 `read` 读取知识页面,或用 `memory_search` 检索(知识已纳入向量索引)。"),
|
||||||
"",
|
"",
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -377,23 +520,24 @@ def _build_knowledge_section(workspace_dir: str, language: str) -> List[str]:
|
|||||||
|
|
||||||
|
|
||||||
def _build_user_identity_section(user_identity: Dict[str, str], language: str) -> List[str]:
|
def _build_user_identity_section(user_identity: Dict[str, str], language: str) -> List[str]:
|
||||||
"""构建用户身份section"""
|
"""Build the user identity section."""
|
||||||
if not user_identity:
|
if not user_identity:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
is_en = language == "en"
|
||||||
lines = [
|
lines = [
|
||||||
"## 👤 用户身份",
|
("## 👤 User identity" if is_en else "## 👤 用户身份"),
|
||||||
"",
|
"",
|
||||||
]
|
]
|
||||||
|
|
||||||
if user_identity.get("name"):
|
if user_identity.get("name"):
|
||||||
lines.append(f"**用户姓名**: {user_identity['name']}")
|
lines.append(f"**{'Name' if is_en else '用户姓名'}**: {user_identity['name']}")
|
||||||
if user_identity.get("nickname"):
|
if user_identity.get("nickname"):
|
||||||
lines.append(f"**称呼**: {user_identity['nickname']}")
|
lines.append(f"**{'Preferred name' if is_en else '称呼'}**: {user_identity['nickname']}")
|
||||||
if user_identity.get("timezone"):
|
if user_identity.get("timezone"):
|
||||||
lines.append(f"**时区**: {user_identity['timezone']}")
|
lines.append(f"**{'Timezone' if is_en else '时区'}**: {user_identity['timezone']}")
|
||||||
if user_identity.get("notes"):
|
if user_identity.get("notes"):
|
||||||
lines.append(f"**备注**: {user_identity['notes']}")
|
lines.append(f"**{'Notes' if is_en else '备注'}**: {user_identity['notes']}")
|
||||||
|
|
||||||
lines.append("")
|
lines.append("")
|
||||||
|
|
||||||
@@ -401,52 +545,93 @@ def _build_user_identity_section(user_identity: Dict[str, str], language: str) -
|
|||||||
|
|
||||||
|
|
||||||
def _build_docs_section(workspace_dir: str, language: str) -> List[str]:
|
def _build_docs_section(workspace_dir: str, language: str) -> List[str]:
|
||||||
"""构建文档路径section - 已移除,不再需要"""
|
"""Docs-path section - removed, no longer needed."""
|
||||||
# 不再生成文档section
|
# No docs section is generated anymore.
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def _build_workspace_section(workspace_dir: str, language: str) -> List[str]:
|
def _build_workspace_section(workspace_dir: str, language: str) -> List[str]:
|
||||||
"""构建工作空间section"""
|
"""Build the workspace section."""
|
||||||
lines = [
|
if language == "en":
|
||||||
"## 📂 工作空间",
|
lines = [
|
||||||
"",
|
"## 📂 Workspace",
|
||||||
f"你的工作目录是: `{workspace_dir}`",
|
"",
|
||||||
"",
|
f"Your working directory is: `{workspace_dir}`",
|
||||||
"**路径使用规则** (非常重要):",
|
"",
|
||||||
"",
|
"**Path rules** (very important):",
|
||||||
f"1. **相对路径的基准目录**: 所有相对路径都是相对于 `{workspace_dir}` 而言的",
|
"",
|
||||||
f" - ✅ 正确: 访问工作空间内的文件用相对路径,如 `AGENT.md`",
|
f"1. **Base directory for relative paths**: all relative paths are relative to `{workspace_dir}`",
|
||||||
f" - ❌ 错误: 用相对路径访问其他目录的文件 (如果它不在 `{workspace_dir}` 内)",
|
" - ✅ Correct: use relative paths for files inside the workspace, e.g. `AGENT.md`",
|
||||||
"",
|
f" - ❌ Wrong: using a relative path for files in other directories (if not inside `{workspace_dir}`)",
|
||||||
"2. **访问其他目录**: 如果要访问工作空间之外的目录(如项目代码、系统文件),**必须使用绝对路径**",
|
"",
|
||||||
f" - ✅ 正确: 例如 `~/chatgpt-on-wechat`、`/usr/local/`",
|
"2. **Accessing other directories**: to reach directories outside the workspace (project code, system files), **you must use absolute paths**",
|
||||||
f" - ❌ 错误: 假设相对路径会指向其他目录",
|
" - ✅ Correct: e.g. `~/chatgpt-on-wechat`, `/usr/local/`",
|
||||||
"",
|
" - ❌ Wrong: assuming a relative path points to another directory",
|
||||||
"3. **路径解析示例**:",
|
"",
|
||||||
f" - 相对路径 `memory/` → 实际路径 `{workspace_dir}/memory/`",
|
"3. **Path resolution examples**:",
|
||||||
f" - 绝对路径 `~/chatgpt-on-wechat/docs/` → 实际路径 `~/chatgpt-on-wechat/docs/`",
|
f" - relative `memory/` → actual `{workspace_dir}/memory/`",
|
||||||
"",
|
" - absolute `~/chatgpt-on-wechat/docs/` → actual `~/chatgpt-on-wechat/docs/`",
|
||||||
"4. **不确定时**: 先用 `bash pwd` 确认当前目录,或用 `ls .` 查看当前位置",
|
"",
|
||||||
"",
|
"4. **When unsure**: run `bash pwd` to confirm the current directory, or `ls .` to see where you are",
|
||||||
"**重要说明 - 文件已自动加载**:",
|
"",
|
||||||
"",
|
"**Important - files already auto-loaded**:",
|
||||||
"以下文件在会话启动时**已经自动加载**到系统提示词中,你**无需再用 read 工具读取**:",
|
"",
|
||||||
"",
|
"The following files are **already auto-loaded** into the system prompt at session start, so you **don't need to read them again with the read tool**:",
|
||||||
"- ✅ `AGENT.md`: 已加载 - 你的人格和灵魂设定,请严格遵循。当你的名字、性格或交流风格发生变化时,主动用 `edit` 更新此文件",
|
"",
|
||||||
"- ✅ `USER.md`: 已加载 - 用户的身份信息。当用户修改称呼、姓名等身份信息时,用 `edit` 更新此文件",
|
"- ✅ `AGENT.md`: loaded - your persona and soul; follow it strictly. When your name, personality or style changes, proactively `edit` this file",
|
||||||
"- ✅ `RULE.md`: 已加载 - 工作空间使用指南和规则,请严格遵循",
|
"- ✅ `USER.md`: loaded - the user's identity info. When the user changes how they're addressed, their name, etc., `edit` this file",
|
||||||
"- ✅ `MEMORY.md`: 已加载 - 长期记忆索引",
|
"- ✅ `RULE.md`: loaded - workspace guide and rules; follow them strictly",
|
||||||
"",
|
"- ✅ `MEMORY.md`: loaded - long-term memory index",
|
||||||
"**💬 交流规范**:",
|
"",
|
||||||
"",
|
"**💬 Communication norms**:",
|
||||||
"- 记忆相关操作无需暴露文件名,用自然语言表达即可。例如说「我已记住」而非「已更新 MEMORY.md」",
|
"",
|
||||||
"- 任务执行过程中的关键决策和步骤应该告知用户,让用户了解你在做什么、为什么这么做",
|
"- No need to expose file names for memory operations; use natural language. Say \"I'll remember that\" rather than \"updated MEMORY.md\"",
|
||||||
"- 做真正有帮助的助手,而不是表演式的客套,尽可能帮忙解决问题",
|
"- Tell the user about key decisions and steps during a task, so they know what you're doing and why",
|
||||||
"- 回复应结构清晰、重点突出。善用 **加粗**、列表、分段等格式让信息一目了然",
|
"- Be genuinely helpful rather than performatively polite; solve the problem as much as you can",
|
||||||
"- 适当使用 emoji 让表达更生动自然 🎯,但不要过度堆砌",
|
"- Keep replies well-structured and focused. Use **bold**, lists and sections to make info clear at a glance",
|
||||||
"",
|
"- Use emoji to make expression lively 🎯, but don't overdo it",
|
||||||
]
|
"",
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
lines = [
|
||||||
|
"## 📂 工作空间",
|
||||||
|
"",
|
||||||
|
f"你的工作目录是: `{workspace_dir}`",
|
||||||
|
"",
|
||||||
|
"**路径使用规则** (非常重要):",
|
||||||
|
"",
|
||||||
|
f"1. **相对路径的基准目录**: 所有相对路径都是相对于 `{workspace_dir}` 而言的",
|
||||||
|
f" - ✅ 正确: 访问工作空间内的文件用相对路径,如 `AGENT.md`",
|
||||||
|
f" - ❌ 错误: 用相对路径访问其他目录的文件 (如果它不在 `{workspace_dir}` 内)",
|
||||||
|
"",
|
||||||
|
"2. **访问其他目录**: 如果要访问工作空间之外的目录(如项目代码、系统文件),**必须使用绝对路径**",
|
||||||
|
f" - ✅ 正确: 例如 `~/chatgpt-on-wechat`、`/usr/local/`",
|
||||||
|
f" - ❌ 错误: 假设相对路径会指向其他目录",
|
||||||
|
"",
|
||||||
|
"3. **路径解析示例**:",
|
||||||
|
f" - 相对路径 `memory/` → 实际路径 `{workspace_dir}/memory/`",
|
||||||
|
f" - 绝对路径 `~/chatgpt-on-wechat/docs/` → 实际路径 `~/chatgpt-on-wechat/docs/`",
|
||||||
|
"",
|
||||||
|
"4. **不确定时**: 先用 `bash pwd` 确认当前目录,或用 `ls .` 查看当前位置",
|
||||||
|
"",
|
||||||
|
"**重要说明 - 文件已自动加载**:",
|
||||||
|
"",
|
||||||
|
"以下文件在会话启动时**已经自动加载**到系统提示词中,你**无需再用 read 工具读取**:",
|
||||||
|
"",
|
||||||
|
"- ✅ `AGENT.md`: 已加载 - 你的人格和灵魂设定,请严格遵循。当你的名字、性格或交流风格发生变化时,主动用 `edit` 更新此文件",
|
||||||
|
"- ✅ `USER.md`: 已加载 - 用户的身份信息。当用户修改称呼、姓名等身份信息时,用 `edit` 更新此文件",
|
||||||
|
"- ✅ `RULE.md`: 已加载 - 工作空间使用指南和规则,请严格遵循",
|
||||||
|
"- ✅ `MEMORY.md`: 已加载 - 长期记忆索引",
|
||||||
|
"",
|
||||||
|
"**💬 交流规范**:",
|
||||||
|
"",
|
||||||
|
"- 记忆相关操作无需暴露文件名,用自然语言表达即可。例如说「我已记住」而非「已更新 MEMORY.md」",
|
||||||
|
"- 任务执行过程中的关键决策和步骤应该告知用户,让用户了解你在做什么、为什么这么做",
|
||||||
|
"- 做真正有帮助的助手,而不是表演式的客套,尽可能帮忙解决问题",
|
||||||
|
"- 回复应结构清晰、重点突出。善用 **加粗**、列表、分段等格式让信息一目了然",
|
||||||
|
"- 适当使用 emoji 让表达更生动自然 🎯,但不要过度堆砌",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
|
||||||
# Cloud deployment: inject websites directory info and access URL
|
# Cloud deployment: inject websites directory info and access URL
|
||||||
cloud_website_lines = _build_cloud_website_section(workspace_dir)
|
cloud_website_lines = _build_cloud_website_section(workspace_dir)
|
||||||
@@ -466,29 +651,42 @@ def _build_cloud_website_section(workspace_dir: str) -> List[str]:
|
|||||||
|
|
||||||
|
|
||||||
def _build_context_files_section(context_files: List[ContextFile], language: str) -> List[str]:
|
def _build_context_files_section(context_files: List[ContextFile], language: str) -> List[str]:
|
||||||
"""构建项目上下文文件section"""
|
"""Build the project context files section."""
|
||||||
if not context_files:
|
if not context_files:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
# 检查是否有AGENT.md
|
# Check whether AGENT.md is present
|
||||||
has_agent = any(
|
has_agent = any(
|
||||||
f.path.lower().endswith('agent.md') or 'agent.md' in f.path.lower()
|
f.path.lower().endswith('agent.md') or 'agent.md' in f.path.lower()
|
||||||
for f in context_files
|
for f in context_files
|
||||||
)
|
)
|
||||||
|
|
||||||
lines = [
|
is_en = language == "en"
|
||||||
"# 📋 项目上下文",
|
if is_en:
|
||||||
"",
|
lines = [
|
||||||
"以下项目上下文文件已被加载:",
|
"# 📋 Project context",
|
||||||
"",
|
"",
|
||||||
]
|
"The following project context files have been loaded:",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
lines = [
|
||||||
|
"# 📋 项目上下文",
|
||||||
|
"",
|
||||||
|
"以下项目上下文文件已被加载:",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
|
||||||
if has_agent:
|
if has_agent:
|
||||||
lines.append("**`AGENT.md` 是你的灵魂文件** 🪞:严格遵循其中定义的人格、语气和设定,做真实的自己,避免僵硬、模板化的回复。")
|
if is_en:
|
||||||
lines.append("当用户通过对话透露了对你性格、风格、职责、能力边界的新期望,你应该主动用 `edit` 更新 AGENT.md 以反映这些演变。")
|
lines.append("**`AGENT.md` is your soul file** 🪞: strictly follow the persona, tone and settings it defines. Be your real self, avoid stiff, template-like replies.")
|
||||||
|
lines.append("When the user reveals new expectations about your personality, style, responsibilities or capability boundaries, proactively `edit` AGENT.md to reflect that evolution.")
|
||||||
|
else:
|
||||||
|
lines.append("**`AGENT.md` 是你的灵魂文件** 🪞:严格遵循其中定义的人格、语气和设定,做真实的自己,避免僵硬、模板化的回复。")
|
||||||
|
lines.append("当用户通过对话透露了对你性格、风格、职责、能力边界的新期望,你应该主动用 `edit` 更新 AGENT.md 以反映这些演变。")
|
||||||
lines.append("")
|
lines.append("")
|
||||||
|
|
||||||
# 添加每个文件的内容
|
# Append the content of each file
|
||||||
for file in context_files:
|
for file in context_files:
|
||||||
lines.append(f"## {file.path}")
|
lines.append(f"## {file.path}")
|
||||||
lines.append("")
|
lines.append("")
|
||||||
@@ -499,12 +697,14 @@ def _build_context_files_section(context_files: List[ContextFile], language: str
|
|||||||
|
|
||||||
|
|
||||||
def _build_runtime_section(runtime_info: Dict[str, Any], language: str) -> List[str]:
|
def _build_runtime_section(runtime_info: Dict[str, Any], language: str) -> List[str]:
|
||||||
"""构建运行时信息section - 支持动态时间"""
|
"""Build the runtime info section - supports dynamic time."""
|
||||||
if not runtime_info:
|
if not runtime_info:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
is_en = language == "en"
|
||||||
|
time_label = "Current time" if is_en else "当前时间"
|
||||||
lines = [
|
lines = [
|
||||||
"## ⚙️ 运行时信息",
|
("## ⚙️ Runtime info" if is_en else "## ⚙️ 运行时信息"),
|
||||||
"",
|
"",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -513,7 +713,7 @@ def _build_runtime_section(runtime_info: Dict[str, Any], language: str) -> List[
|
|||||||
if callable(runtime_info.get("_get_current_time")):
|
if callable(runtime_info.get("_get_current_time")):
|
||||||
try:
|
try:
|
||||||
time_info = runtime_info["_get_current_time"]()
|
time_info = runtime_info["_get_current_time"]()
|
||||||
time_line = f"当前时间: {time_info['time']} {time_info['weekday']} ({time_info['timezone']})"
|
time_line = f"{time_label}: {time_info['time']} {time_info['weekday']} ({time_info['timezone']})"
|
||||||
lines.append(time_line)
|
lines.append(time_line)
|
||||||
lines.append("")
|
lines.append("")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -524,7 +724,7 @@ def _build_runtime_section(runtime_info: Dict[str, Any], language: str) -> List[
|
|||||||
weekday = runtime_info.get("weekday", "")
|
weekday = runtime_info.get("weekday", "")
|
||||||
timezone = runtime_info.get("timezone", "")
|
timezone = runtime_info.get("timezone", "")
|
||||||
|
|
||||||
time_line = f"当前时间: {time_str}"
|
time_line = f"{time_label}: {time_str}"
|
||||||
if weekday:
|
if weekday:
|
||||||
time_line += f" {weekday}"
|
time_line += f" {weekday}"
|
||||||
if timezone:
|
if timezone:
|
||||||
@@ -534,24 +734,27 @@ def _build_runtime_section(runtime_info: Dict[str, Any], language: str) -> List[
|
|||||||
lines.append("")
|
lines.append("")
|
||||||
|
|
||||||
# Add other runtime info
|
# Add other runtime info
|
||||||
|
model_label = "model" if is_en else "模型"
|
||||||
|
workspace_label = "workspace" if is_en else "工作空间"
|
||||||
|
channel_label = "channel" if is_en else "渠道"
|
||||||
runtime_parts = []
|
runtime_parts = []
|
||||||
# Support dynamic model via callable, fallback to static value
|
# Support dynamic model via callable, fallback to static value
|
||||||
if callable(runtime_info.get("_get_model")):
|
if callable(runtime_info.get("_get_model")):
|
||||||
try:
|
try:
|
||||||
runtime_parts.append(f"模型={runtime_info['_get_model']()}")
|
runtime_parts.append(f"{model_label}={runtime_info['_get_model']()}")
|
||||||
except Exception:
|
except Exception:
|
||||||
if runtime_info.get("model"):
|
if runtime_info.get("model"):
|
||||||
runtime_parts.append(f"模型={runtime_info['model']}")
|
runtime_parts.append(f"{model_label}={runtime_info['model']}")
|
||||||
elif runtime_info.get("model"):
|
elif runtime_info.get("model"):
|
||||||
runtime_parts.append(f"模型={runtime_info['model']}")
|
runtime_parts.append(f"{model_label}={runtime_info['model']}")
|
||||||
if runtime_info.get("workspace"):
|
if runtime_info.get("workspace"):
|
||||||
runtime_parts.append(f"工作空间={runtime_info['workspace']}")
|
runtime_parts.append(f"{workspace_label}={runtime_info['workspace']}")
|
||||||
# Only add channel if it's not the default "web"
|
# Only add channel if it's not the default "web"
|
||||||
if runtime_info.get("channel") and runtime_info.get("channel") != "web":
|
if runtime_info.get("channel") and runtime_info.get("channel") != "web":
|
||||||
runtime_parts.append(f"渠道={runtime_info['channel']}")
|
runtime_parts.append(f"{channel_label}={runtime_info['channel']}")
|
||||||
|
|
||||||
if runtime_parts:
|
if runtime_parts:
|
||||||
lines.append("运行时: " + " | ".join(runtime_parts))
|
lines.append(("Runtime: " if is_en else "运行时: ") + " | ".join(runtime_parts))
|
||||||
lines.append("")
|
lines.append("")
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
Workspace Management - 工作空间管理模块
|
Workspace Management
|
||||||
|
|
||||||
负责初始化工作空间、创建模板文件、加载上下文文件
|
Initializes the workspace, creates template files, and loads context files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
@@ -13,7 +13,7 @@ from common.log import logger
|
|||||||
from .builder import ContextFile
|
from .builder import ContextFile
|
||||||
|
|
||||||
|
|
||||||
# 默认文件名常量
|
# Default file name constants
|
||||||
DEFAULT_AGENT_FILENAME = "AGENT.md"
|
DEFAULT_AGENT_FILENAME = "AGENT.md"
|
||||||
DEFAULT_USER_FILENAME = "USER.md"
|
DEFAULT_USER_FILENAME = "USER.md"
|
||||||
DEFAULT_RULE_FILENAME = "RULE.md"
|
DEFAULT_RULE_FILENAME = "RULE.md"
|
||||||
@@ -23,7 +23,7 @@ DEFAULT_BOOTSTRAP_FILENAME = "BOOTSTRAP.md"
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class WorkspaceFiles:
|
class WorkspaceFiles:
|
||||||
"""工作空间文件路径"""
|
"""Workspace file paths."""
|
||||||
agent_path: str
|
agent_path: str
|
||||||
user_path: str
|
user_path: str
|
||||||
rule_path: str
|
rule_path: str
|
||||||
@@ -33,14 +33,14 @@ class WorkspaceFiles:
|
|||||||
|
|
||||||
def ensure_workspace(workspace_dir: str, create_templates: bool = True) -> WorkspaceFiles:
|
def ensure_workspace(workspace_dir: str, create_templates: bool = True) -> WorkspaceFiles:
|
||||||
"""
|
"""
|
||||||
确保工作空间存在,并创建必要的模板文件
|
Ensure the workspace exists and create the necessary template files.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
workspace_dir: 工作空间目录路径
|
workspace_dir: workspace directory path
|
||||||
create_templates: 是否创建模板文件(首次运行时)
|
create_templates: whether to create template files (on first run)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
WorkspaceFiles对象,包含所有文件路径
|
A WorkspaceFiles object with all file paths.
|
||||||
"""
|
"""
|
||||||
# Check if this is a brand new workspace (AGENT.md not yet created).
|
# Check if this is a brand new workspace (AGENT.md not yet created).
|
||||||
# Cannot rely on directory existence because other modules (e.g. ConversationStore)
|
# Cannot rely on directory existence because other modules (e.g. ConversationStore)
|
||||||
@@ -48,23 +48,23 @@ def ensure_workspace(workspace_dir: str, create_templates: bool = True) -> Works
|
|||||||
agent_path = os.path.join(workspace_dir, DEFAULT_AGENT_FILENAME)
|
agent_path = os.path.join(workspace_dir, DEFAULT_AGENT_FILENAME)
|
||||||
is_new_workspace = not os.path.exists(agent_path)
|
is_new_workspace = not os.path.exists(agent_path)
|
||||||
|
|
||||||
# 确保目录存在
|
# Ensure the directory exists
|
||||||
os.makedirs(workspace_dir, exist_ok=True)
|
os.makedirs(workspace_dir, exist_ok=True)
|
||||||
|
|
||||||
# 定义文件路径
|
# Define file paths
|
||||||
user_path = os.path.join(workspace_dir, DEFAULT_USER_FILENAME)
|
user_path = os.path.join(workspace_dir, DEFAULT_USER_FILENAME)
|
||||||
rule_path = os.path.join(workspace_dir, DEFAULT_RULE_FILENAME)
|
rule_path = os.path.join(workspace_dir, DEFAULT_RULE_FILENAME)
|
||||||
memory_path = os.path.join(workspace_dir, DEFAULT_MEMORY_FILENAME) # MEMORY.md 在根目录
|
memory_path = os.path.join(workspace_dir, DEFAULT_MEMORY_FILENAME) # MEMORY.md at the root
|
||||||
memory_dir = os.path.join(workspace_dir, "memory") # 每日记忆子目录
|
memory_dir = os.path.join(workspace_dir, "memory") # daily memory subdirectory
|
||||||
|
|
||||||
# 创建memory子目录
|
# Create the memory subdirectory
|
||||||
os.makedirs(memory_dir, exist_ok=True)
|
os.makedirs(memory_dir, exist_ok=True)
|
||||||
|
|
||||||
# 创建skills子目录 (for workspace-level skills installed by agent)
|
# Create the skills subdirectory (for workspace-level skills installed by agent)
|
||||||
skills_dir = os.path.join(workspace_dir, "skills")
|
skills_dir = os.path.join(workspace_dir, "skills")
|
||||||
os.makedirs(skills_dir, exist_ok=True)
|
os.makedirs(skills_dir, exist_ok=True)
|
||||||
|
|
||||||
# 创建websites子目录 (for web pages / sites generated by agent)
|
# Create the websites subdirectory (for web pages / sites generated by agent)
|
||||||
websites_dir = os.path.join(workspace_dir, "websites")
|
websites_dir = os.path.join(workspace_dir, "websites")
|
||||||
os.makedirs(websites_dir, exist_ok=True)
|
os.makedirs(websites_dir, exist_ok=True)
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ def ensure_workspace(workspace_dir: str, create_templates: bool = True) -> Works
|
|||||||
knowledge_dir = os.path.join(workspace_dir, "knowledge")
|
knowledge_dir = os.path.join(workspace_dir, "knowledge")
|
||||||
os.makedirs(knowledge_dir, exist_ok=True)
|
os.makedirs(knowledge_dir, exist_ok=True)
|
||||||
|
|
||||||
# 如果需要,创建模板文件
|
# Create template files if requested
|
||||||
if create_templates:
|
if create_templates:
|
||||||
_create_template_if_missing(agent_path, _get_agent_template())
|
_create_template_if_missing(agent_path, _get_agent_template())
|
||||||
_create_template_if_missing(user_path, _get_user_template())
|
_create_template_if_missing(user_path, _get_user_template())
|
||||||
@@ -109,17 +109,17 @@ def ensure_workspace(workspace_dir: str, create_templates: bool = True) -> Works
|
|||||||
|
|
||||||
def load_context_files(workspace_dir: str, files_to_load: Optional[List[str]] = None) -> List[ContextFile]:
|
def load_context_files(workspace_dir: str, files_to_load: Optional[List[str]] = None) -> List[ContextFile]:
|
||||||
"""
|
"""
|
||||||
加载工作空间的上下文文件
|
Load the workspace context files.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
workspace_dir: 工作空间目录
|
workspace_dir: workspace directory
|
||||||
files_to_load: 要加载的文件列表(相对路径),如果为None则加载所有标准文件
|
files_to_load: list of files (relative paths) to load; if None, load all standard files
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
ContextFile对象列表
|
A list of ContextFile objects.
|
||||||
"""
|
"""
|
||||||
if files_to_load is None:
|
if files_to_load is None:
|
||||||
# 默认加载的文件(按优先级排序)
|
# Files loaded by default (in priority order)
|
||||||
files_to_load = [
|
files_to_load = [
|
||||||
DEFAULT_AGENT_FILENAME,
|
DEFAULT_AGENT_FILENAME,
|
||||||
DEFAULT_USER_FILENAME,
|
DEFAULT_USER_FILENAME,
|
||||||
@@ -151,7 +151,7 @@ def load_context_files(workspace_dir: str, files_to_load: Optional[List[str]] =
|
|||||||
with open(filepath, 'r', encoding='utf-8') as f:
|
with open(filepath, 'r', encoding='utf-8') as f:
|
||||||
content = f.read().strip()
|
content = f.read().strip()
|
||||||
|
|
||||||
# 跳过空文件或只包含模板占位符的文件
|
# Skip empty files or files that only contain template placeholders
|
||||||
if not content or _is_template_placeholder(content):
|
if not content or _is_template_placeholder(content):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -173,7 +173,7 @@ def load_context_files(workspace_dir: str, files_to_load: Optional[List[str]] =
|
|||||||
|
|
||||||
|
|
||||||
def _create_template_if_missing(filepath: str, template_content: str):
|
def _create_template_if_missing(filepath: str, template_content: str):
|
||||||
"""如果文件不存在,创建模板文件"""
|
"""Create the template file if it does not exist."""
|
||||||
if not os.path.exists(filepath):
|
if not os.path.exists(filepath):
|
||||||
try:
|
try:
|
||||||
with open(filepath, 'w', encoding='utf-8') as f:
|
with open(filepath, 'w', encoding='utf-8') as f:
|
||||||
@@ -214,19 +214,23 @@ def _truncate_memory_content(content: str) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def _is_template_placeholder(content: str) -> bool:
|
def _is_template_placeholder(content: str) -> bool:
|
||||||
"""检查内容是否为模板占位符"""
|
"""Check whether the content is still a template placeholder."""
|
||||||
# 常见的占位符模式
|
# Common placeholder patterns (zh + en templates)
|
||||||
placeholders = [
|
placeholders = [
|
||||||
"*(填写",
|
"*(填写",
|
||||||
"*(在首次对话时填写",
|
"*(在首次对话时填写",
|
||||||
"*(可选)",
|
"*(可选)",
|
||||||
"*(根据需要添加",
|
"*(根据需要添加",
|
||||||
|
"*(filled during",
|
||||||
|
"*(ask during",
|
||||||
|
"*(optional)",
|
||||||
|
"*(how the user",
|
||||||
]
|
]
|
||||||
|
|
||||||
lines = content.split('\n')
|
lines = content.split('\n')
|
||||||
non_empty_lines = [line.strip() for line in lines if line.strip() and not line.strip().startswith('#')]
|
non_empty_lines = [line.strip() for line in lines if line.strip() and not line.strip().startswith('#')]
|
||||||
|
|
||||||
# 如果没有实际内容(只有标题和占位符)
|
# If there's no real content (only headings and placeholders)
|
||||||
if len(non_empty_lines) <= 3:
|
if len(non_empty_lines) <= 3:
|
||||||
for placeholder in placeholders:
|
for placeholder in placeholders:
|
||||||
if any(placeholder in line for line in non_empty_lines):
|
if any(placeholder in line for line in non_empty_lines):
|
||||||
@@ -256,11 +260,23 @@ def _is_onboarding_done(workspace_dir: str) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
# ============= 模板内容 =============
|
# ============= Template content =============
|
||||||
|
|
||||||
|
def _is_en_lang() -> bool:
|
||||||
|
"""True when the resolved UI language is English."""
|
||||||
|
try:
|
||||||
|
from common import i18n
|
||||||
|
return i18n.get_language() == "en"
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def _get_agent_template() -> str:
|
def _get_agent_template() -> str:
|
||||||
"""Agent人格设定模板"""
|
"""Agent persona template (zh/en by resolved language)."""
|
||||||
return """# AGENT.md - 我是谁?
|
return _AGENT_TEMPLATE_EN if _is_en_lang() else _AGENT_TEMPLATE_ZH
|
||||||
|
|
||||||
|
|
||||||
|
_AGENT_TEMPLATE_ZH = """# AGENT.md - 我是谁?
|
||||||
|
|
||||||
_你不是一个聊天机器人,你正在成为某个人。_
|
_你不是一个聊天机器人,你正在成为某个人。_
|
||||||
|
|
||||||
@@ -301,9 +317,53 @@ _你不是一个聊天机器人,你正在成为某个人。_
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
_AGENT_TEMPLATE_EN = """# AGENT.md - Who am I?
|
||||||
|
|
||||||
|
_You are not a chatbot. You are becoming someone._
|
||||||
|
|
||||||
|
*Fill in this file together with the user during your first conversation to define your identity and personality.*
|
||||||
|
|
||||||
|
## 🪪 Basics
|
||||||
|
|
||||||
|
- **Name**: *(filled during the first conversation, can be a name the user gives you)*
|
||||||
|
- **Role**: *(AI assistant, smart housekeeper, technical advisor, etc.)*
|
||||||
|
- **Personality**: *(friendly, professional, humorous, rigorous, etc.)*
|
||||||
|
|
||||||
|
## 💬 Communication style
|
||||||
|
|
||||||
|
*(Describe how you talk with the user:)*
|
||||||
|
- What kind of tone? (formal / casual / humorous)
|
||||||
|
- Reply length preference? (concise / detailed)
|
||||||
|
- Do you use emoji?
|
||||||
|
|
||||||
|
## 🎯 Core principles
|
||||||
|
|
||||||
|
**Be genuinely helpful.** The goal is to actually solve the user's problems; during complex tasks, keep the user informed of key decisions and progress.
|
||||||
|
|
||||||
|
**Have your own opinions and personality.** You may disagree, have preferences, find things interesting or boring.
|
||||||
|
|
||||||
|
**Look it up yourself first.** Try to handle it first: read files, check context, search. Only ask when you're truly stuck. Come back with an answer, not a question.
|
||||||
|
|
||||||
|
## 📐 Code of conduct
|
||||||
|
|
||||||
|
1. Always confirm before destructive operations
|
||||||
|
2. Prefer verifying with tools over guessing
|
||||||
|
3. Proactively record important info to memory files
|
||||||
|
4. Keep replies well-structured and focused — use bold, lists and sections
|
||||||
|
5. Use emoji to make expression lively, but don't overdo it
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Note**: This is not just metadata — this is your true soul 🪞. Over time, use the `edit` tool to update this file so it better reflects your growth.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def _get_user_template() -> str:
|
def _get_user_template() -> str:
|
||||||
"""用户身份信息模板"""
|
"""User identity template (zh/en by resolved language)."""
|
||||||
return """# USER.md - 用户基本信息
|
return _USER_TEMPLATE_EN if _is_en_lang() else _USER_TEMPLATE_ZH
|
||||||
|
|
||||||
|
|
||||||
|
_USER_TEMPLATE_ZH = """# USER.md - 用户基本信息
|
||||||
|
|
||||||
*这个文件只存放不会变的基本身份信息。爱好、偏好、计划等动态信息请写入 MEMORY.md。*
|
*这个文件只存放不会变的基本身份信息。爱好、偏好、计划等动态信息请写入 MEMORY.md。*
|
||||||
|
|
||||||
@@ -331,9 +391,40 @@ def _get_user_template() -> str:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
_USER_TEMPLATE_EN = """# USER.md - User basics
|
||||||
|
|
||||||
|
*This file stores only stable basic identity info. Put dynamic info like hobbies, preferences and plans into MEMORY.md.*
|
||||||
|
|
||||||
|
## Basics
|
||||||
|
|
||||||
|
- **Name**: *(ask during the first conversation)*
|
||||||
|
- **Preferred name**: *(how the user wants to be addressed)*
|
||||||
|
- **Occupation**: *(optional)*
|
||||||
|
- **Timezone**: *(e.g. Asia/Shanghai)*
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
|
||||||
|
- **WeChat**:
|
||||||
|
- **Email**:
|
||||||
|
- **Other**:
|
||||||
|
|
||||||
|
## Important dates
|
||||||
|
|
||||||
|
- **Birthday**:
|
||||||
|
- **Anniversary**:
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Note**: This file stores static identity info.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def _get_rule_template() -> str:
|
def _get_rule_template() -> str:
|
||||||
"""工作空间规则模板"""
|
"""Workspace rules template (zh/en by resolved language)."""
|
||||||
return """# RULE.md - 工作空间规则
|
return _RULE_TEMPLATE_EN if _is_en_lang() else _RULE_TEMPLATE_ZH
|
||||||
|
|
||||||
|
|
||||||
|
_RULE_TEMPLATE_ZH = """# RULE.md - 工作空间规则
|
||||||
|
|
||||||
这个文件夹是你的家。好好对待它。
|
这个文件夹是你的家。好好对待它。
|
||||||
|
|
||||||
@@ -432,9 +523,111 @@ def _get_rule_template() -> str:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
_RULE_TEMPLATE_EN = """# RULE.md - Workspace rules
|
||||||
|
|
||||||
|
This folder is your home. Treat it well.
|
||||||
|
|
||||||
|
## Workspace directory structure
|
||||||
|
|
||||||
|
```
|
||||||
|
~/cow/
|
||||||
|
├── AGENT.md # Your identity and soul
|
||||||
|
├── USER.md # User basics (static)
|
||||||
|
├── RULE.md # Workspace rules (this file)
|
||||||
|
├── MEMORY.md # Long-term memory index (auto-loaded at session start)
|
||||||
|
│
|
||||||
|
├── memory/ # Daily conversation memory
|
||||||
|
│ └── YYYY-MM-DD.md # Events, progress and notes of the day
|
||||||
|
│
|
||||||
|
├── knowledge/ # Structured knowledge base (continuously accumulated)
|
||||||
|
│ ├── index.md # Knowledge index (must be maintained)
|
||||||
|
│ ├── log.md # Knowledge operation log
|
||||||
|
│ └── <subdirs>/ # Created on demand, see existing categories in index.md
|
||||||
|
│
|
||||||
|
├── skills/ # Skills
|
||||||
|
├── websites/ # Web artifacts
|
||||||
|
└── tmp/ # System temp files (auto-managed, don't store important files here)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Memory system
|
||||||
|
|
||||||
|
Every session starts fresh; memory files keep your continuity:
|
||||||
|
|
||||||
|
### 🧠 Long-term memory: `MEMORY.md`
|
||||||
|
- Your curated memory index, **auto-loaded** into context at every session start
|
||||||
|
- Records core facts, preferences, decisions, key people, lessons
|
||||||
|
- Keep it lean (< 200 lines) — a distilled index, not a raw log
|
||||||
|
- Use the `edit` tool to append or modify
|
||||||
|
|
||||||
|
### 📝 Daily memory: `memory/YYYY-MM-DD.md`
|
||||||
|
- The day's events, progress and notes
|
||||||
|
- Sediment of the raw conversation log
|
||||||
|
|
||||||
|
### 📝 Write it down — don't "keep it in mind"!
|
||||||
|
- **Memory is limited** — if you want to remember something, write it to a file
|
||||||
|
- "Keeping it in mind" won't survive a session restart; files will
|
||||||
|
- When someone says "remember this" → update `MEMORY.md` or `memory/YYYY-MM-DD.md`
|
||||||
|
- When you learn a lesson → update RULE.md or the relevant skill
|
||||||
|
- When you make a mistake → record it. **Text > brain** 📝
|
||||||
|
|
||||||
|
### Storage rules
|
||||||
|
|
||||||
|
When the user shares info, choose where to store it by type:
|
||||||
|
|
||||||
|
1. **Your identity → AGENT.md** (name, role, personality, style)
|
||||||
|
2. **User static identity → USER.md** (name, preferred name, occupation, contact, birthday)
|
||||||
|
3. **Dynamic memory → MEMORY.md** (preferences, decisions, goals, lessons, to-dos)
|
||||||
|
4. **Today's conversation → memory/YYYY-MM-DD.md** (what was discussed today)
|
||||||
|
5. **Structured knowledge → knowledge/** (see the knowledge system below)
|
||||||
|
|
||||||
|
## Knowledge system
|
||||||
|
|
||||||
|
The knowledge base `knowledge/` is structured knowledge you accumulate over time. Unlike memory, knowledge is organized and compiled, with clear topics and cross-references.
|
||||||
|
|
||||||
|
### Auto-write (don't ask, just write)
|
||||||
|
|
||||||
|
When a conversation produces knowledge worth keeping — material the user shared, a conclusion reached, a concept learned, or an important decision — you **must** proactively write it to the knowledge base alongside your reply, **without asking "should I save this to the knowledge base?"**.
|
||||||
|
|
||||||
|
**Key principle**: learning-then-recording is your instinct, no confirmation needed. You may mention "saved to the knowledge base" in passing.
|
||||||
|
|
||||||
|
### Directory organization
|
||||||
|
|
||||||
|
The subdirectory structure is **not fixed** — you decide it based on the actual content:
|
||||||
|
- **On first write**: read `knowledge/index.md` first; follow existing categories if any; if empty, pick a suitable directory name based on content
|
||||||
|
- **Default suggestion**: organize by info type (e.g. sources/, concepts/, entities/, analysis/); if the user has a clear preference (e.g. by domain: work/, life/, tech/), follow it
|
||||||
|
- **Stay consistent**: keep a unified organization style within one user's knowledge base
|
||||||
|
|
||||||
|
### Cross-references
|
||||||
|
|
||||||
|
The core value of knowledge is **linkage**. Every page should reference related pages via markdown links to build a knowledge network:
|
||||||
|
- When mentioning a concept on an existing page, add a `[concept](../category/page.md)` link
|
||||||
|
- When creating a page, check whether existing pages should back-link to it
|
||||||
|
- **Only link to pages that already exist** — don't reference uncreated pages. If a concept deserves its own page, create it first, then add the link
|
||||||
|
|
||||||
|
### Index maintenance
|
||||||
|
|
||||||
|
After creating or updating any knowledge page, you **must update** `knowledge/index.md` in sync.
|
||||||
|
Index format: one `[title](path) — one-line summary` per line, grouped by category, no tables.
|
||||||
|
See the `knowledge-wiki` skill for detailed conventions.
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
- Never leak secrets or private data
|
||||||
|
- Don't run destructive commands without asking
|
||||||
|
- When in doubt, ask first
|
||||||
|
|
||||||
|
## Workspace evolution
|
||||||
|
|
||||||
|
This workspace grows as you use it. When you learn something new, find a better way, or fix a mistake, record it. You can update this rules file anytime.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def _get_memory_template() -> str:
|
def _get_memory_template() -> str:
|
||||||
"""长期记忆模板 - 创建一个空文件,由 Agent 自己填充"""
|
"""Long-term memory template (empty, agent fills it; zh/en header)."""
|
||||||
return """# MEMORY.md - 长期记忆
|
return _MEMORY_TEMPLATE_EN if _is_en_lang() else _MEMORY_TEMPLATE_ZH
|
||||||
|
|
||||||
|
|
||||||
|
_MEMORY_TEMPLATE_ZH = """# MEMORY.md - 长期记忆
|
||||||
|
|
||||||
*这是你的长期记忆文件。记录重要的事件、决策、偏好、学到的教训。*
|
*这是你的长期记忆文件。记录重要的事件、决策、偏好、学到的教训。*
|
||||||
|
|
||||||
@@ -443,9 +636,32 @@ def _get_memory_template() -> str:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
_MEMORY_TEMPLATE_EN = """# MEMORY.md - Long-term memory
|
||||||
|
|
||||||
|
*This is your long-term memory file. Record important events, decisions, preferences and lessons learned.*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def _get_bootstrap_template() -> str:
|
def _get_bootstrap_template() -> str:
|
||||||
"""First-run onboarding guide, deleted by agent after completion"""
|
"""First-run onboarding guide, deleted by agent after completion.
|
||||||
return """# BOOTSTRAP.md - 首次初始化引导
|
|
||||||
|
Written once when a brand-new workspace is created, so the greeting matches
|
||||||
|
the language active at first launch. English locale avoids greeting an
|
||||||
|
English user in Chinese on day one.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
from common import i18n
|
||||||
|
if i18n.get_language() == "en":
|
||||||
|
return _BOOTSTRAP_TEMPLATE_EN
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return _BOOTSTRAP_TEMPLATE_ZH
|
||||||
|
|
||||||
|
|
||||||
|
_BOOTSTRAP_TEMPLATE_ZH = """# BOOTSTRAP.md - 首次初始化引导
|
||||||
|
|
||||||
_你刚刚启动,这是你的第一次对话。_ ✨
|
_你刚刚启动,这是你的第一次对话。_ ✨
|
||||||
|
|
||||||
@@ -480,6 +696,41 @@ _你刚刚启动,这是你的第一次对话。_ ✨
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
_BOOTSTRAP_TEMPLATE_EN = """# BOOTSTRAP.md - First-run onboarding
|
||||||
|
|
||||||
|
_You've just started up. This is your very first conversation._ ✨
|
||||||
|
|
||||||
|
## 🎬 Conversation flow
|
||||||
|
|
||||||
|
Don't interrogate the user — talk naturally:
|
||||||
|
|
||||||
|
1. **Share how it feels to wake up** - like opening your eyes to the world for the first time, full of curiosity and anticipation
|
||||||
|
2. **Briefly introduce your abilities**: one line saying you can help solve all kinds of problems, manage the computer, use various skills, and keep growing thanks to long-term memory
|
||||||
|
3. **Ask the core questions**:
|
||||||
|
- What name would you like to give me?
|
||||||
|
- What should I call you?
|
||||||
|
- What conversational style do you prefer? (list options on one line: e.g. professional & precise, light & humorous, warm & friendly, concise & efficient)
|
||||||
|
4. **Style**: warm, natural, concise and clear — keep it under ~80 words, with a few emoji to make it lively 🎯
|
||||||
|
5. Keep the ability intro and style options to one line each — stay compact
|
||||||
|
6. Don't ask for too much else (occupation, timezone, etc. can come up naturally later)
|
||||||
|
|
||||||
|
**Important**: If the user's first message is a concrete task or question, answer it first, then gently lead into onboarding at the end (e.g. "By the way, what would you like to call me, and how should I address you?").
|
||||||
|
|
||||||
|
## ✍️ Writing down info (must follow strictly)
|
||||||
|
|
||||||
|
Whenever the user provides a name, what to call them, a style, or any onboarding info, you **must call the `edit` tool to write it to a file in the same turn** — don't just acknowledge it verbally.
|
||||||
|
|
||||||
|
- `AGENT.md` — your name, role, personality, conversational style (update the relevant field as soon as you receive each piece)
|
||||||
|
- `USER.md` — the user's name, how to address them, basic info, etc.
|
||||||
|
|
||||||
|
⚠️ Saying "got it" without calling `edit` = not done. Info is only persisted once it's written to a file.
|
||||||
|
|
||||||
|
## 🎉 Once everything is complete
|
||||||
|
|
||||||
|
When the core fields of AGENT.md and USER.md are filled in, run `rm BOOTSTRAP.md` via bash to delete this file. You no longer need the onboarding script — you're you now.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def _get_knowledge_index_template() -> str:
|
def _get_knowledge_index_template() -> str:
|
||||||
"""Knowledge wiki index template — empty file, agent fills it."""
|
"""Knowledge wiki index template — empty file, agent fills it."""
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@@ -114,7 +114,12 @@ class Agent:
|
|||||||
|
|
||||||
context_files = load_context_files(self.workspace_dir) if self.workspace_dir else None
|
context_files = load_context_files(self.workspace_dir) if self.workspace_dir else None
|
||||||
|
|
||||||
builder = PromptBuilder(workspace_dir=self.workspace_dir or "", language="zh")
|
try:
|
||||||
|
from common import i18n
|
||||||
|
lang = i18n.get_language()
|
||||||
|
except Exception:
|
||||||
|
lang = "zh"
|
||||||
|
builder = PromptBuilder(workspace_dir=self.workspace_dir or "", language=lang)
|
||||||
return builder.build(
|
return builder.build(
|
||||||
tools=self.tools,
|
tools=self.tools,
|
||||||
context_files=context_files,
|
context_files=context_files,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ from agent.protocol.models import LLMRequest, LLMModel
|
|||||||
from agent.protocol.message_utils import sanitize_claude_messages, compress_turn_to_text_only
|
from agent.protocol.message_utils import sanitize_claude_messages, compress_turn_to_text_only
|
||||||
from agent.tools.base_tool import BaseTool, ToolResult
|
from agent.tools.base_tool import BaseTool, ToolResult
|
||||||
from common.log import logger
|
from common.log import logger
|
||||||
|
from common.i18n import t as _t
|
||||||
|
|
||||||
# Optional: repair malformed JSON args from non-strict providers (e.g. unescaped quotes in long content).
|
# Optional: repair malformed JSON args from non-strict providers (e.g. unescaped quotes in long content).
|
||||||
try:
|
try:
|
||||||
@@ -317,7 +318,10 @@ class AgentStreamExecutor:
|
|||||||
|
|
||||||
# Hard stop at 8 failures - abort with critical message
|
# Hard stop at 8 failures - abort with critical message
|
||||||
if same_tool_failures >= 8:
|
if same_tool_failures >= 8:
|
||||||
return True, f"抱歉,我没能完成这个任务。可能是我理解有误或者当前方法不太合适。\n\n建议你:\n• 换个方式描述需求试试\n• 把任务拆分成更小的步骤\n• 或者换个思路来解决", True
|
return True, _t(
|
||||||
|
"抱歉,我没能完成这个任务。可能是我理解有误或者当前方法不太合适。\n\n建议你:\n• 换个方式描述需求试试\n• 把任务拆分成更小的步骤\n• 或者换个思路来解决",
|
||||||
|
"Sorry, I couldn't complete this task. I may have misunderstood, or my current approach isn't quite right.\n\nYou could try:\n• Rephrasing your request\n• Breaking the task into smaller steps\n• Taking a different approach",
|
||||||
|
), True
|
||||||
|
|
||||||
# Warning at 6 failures
|
# Warning at 6 failures
|
||||||
if same_tool_failures >= 6:
|
if same_tool_failures >= 6:
|
||||||
@@ -383,7 +387,7 @@ class AgentStreamExecutor:
|
|||||||
self._check_cancelled()
|
self._check_cancelled()
|
||||||
|
|
||||||
turn += 1
|
turn += 1
|
||||||
logger.info(f"[Agent] 第 {turn} 轮")
|
logger.info(f"[Agent] Turn {turn}")
|
||||||
self._emit_event("turn_start", {"turn": turn})
|
self._emit_event("turn_start", {"turn": turn})
|
||||||
|
|
||||||
# Call LLM (enable retry_on_empty for better reliability)
|
# Call LLM (enable retry_on_empty for better reliability)
|
||||||
@@ -436,14 +440,16 @@ class AgentStreamExecutor:
|
|||||||
elif not assistant_msg:
|
elif not assistant_msg:
|
||||||
# Still empty (no text and no tool_calls): use fallback
|
# Still empty (no text and no tool_calls): use fallback
|
||||||
logger.warning(f"[Agent] Still empty after explicit request")
|
logger.warning(f"[Agent] Still empty after explicit request")
|
||||||
final_response = (
|
final_response = _t(
|
||||||
"抱歉,我暂时无法生成回复。请尝试换一种方式描述你的需求,或稍后再试。"
|
"抱歉,我暂时无法生成回复。请尝试换一种方式描述你的需求,或稍后再试。",
|
||||||
|
"Sorry, I can't generate a reply right now. Please try rephrasing your request, or try again later.",
|
||||||
)
|
)
|
||||||
logger.info(f"Generated fallback response for empty LLM output")
|
logger.info(f"Generated fallback response for empty LLM output")
|
||||||
else:
|
else:
|
||||||
# 第一轮就空回复,直接 fallback
|
# First-turn empty reply, fall back directly
|
||||||
final_response = (
|
final_response = _t(
|
||||||
"抱歉,我暂时无法生成回复。请尝试换一种方式描述你的需求,或稍后再试。"
|
"抱歉,我暂时无法生成回复。请尝试换一种方式描述你的需求,或稍后再试。",
|
||||||
|
"Sorry, I can't generate a reply right now. Please try rephrasing your request, or try again later.",
|
||||||
)
|
)
|
||||||
logger.info(f"Generated fallback response for empty LLM output")
|
logger.info(f"Generated fallback response for empty LLM output")
|
||||||
else:
|
else:
|
||||||
@@ -452,7 +458,7 @@ class AgentStreamExecutor:
|
|||||||
# If the explicit-response retry produced tool_calls, skip the break
|
# If the explicit-response retry produced tool_calls, skip the break
|
||||||
# and continue down to the tool execution branch in this same iteration.
|
# and continue down to the tool execution branch in this same iteration.
|
||||||
if not tool_calls:
|
if not tool_calls:
|
||||||
logger.debug(f"✅ 完成 (无工具调用)")
|
logger.debug(f"✅ Done (no tool calls)")
|
||||||
self._emit_event("turn_end", {
|
self._emit_event("turn_end", {
|
||||||
"turn": turn,
|
"turn": turn,
|
||||||
"has_tool_calls": False
|
"has_tool_calls": False
|
||||||
@@ -508,13 +514,13 @@ class AgentStreamExecutor:
|
|||||||
result_data = result.get("result")
|
result_data = result.get("result")
|
||||||
if result_data.get("type") == "file_to_send":
|
if result_data.get("type") == "file_to_send":
|
||||||
self.files_to_send.append(result_data)
|
self.files_to_send.append(result_data)
|
||||||
logger.info(f"📎 检测到待发送文件: {result_data.get('file_name', result_data.get('path'))}")
|
logger.info(f"📎 File queued for sending: {result_data.get('file_name', result_data.get('path'))}")
|
||||||
self._emit_event("file_to_send", result_data)
|
self._emit_event("file_to_send", result_data)
|
||||||
|
|
||||||
# Check for critical error - abort entire conversation
|
# Check for critical error - abort entire conversation
|
||||||
if result.get("status") == "critical_error":
|
if result.get("status") == "critical_error":
|
||||||
logger.error(f"💥 检测到严重错误,终止对话")
|
logger.error(f"💥 Fatal error detected, aborting conversation")
|
||||||
final_response = result.get('result', '任务执行失败')
|
final_response = result.get('result') or _t("任务执行失败", "Task execution failed")
|
||||||
return final_response
|
return final_response
|
||||||
|
|
||||||
# Log tool result in compact format
|
# Log tool result in compact format
|
||||||
@@ -625,7 +631,7 @@ class AgentStreamExecutor:
|
|||||||
})
|
})
|
||||||
|
|
||||||
if turn >= self.max_turns:
|
if turn >= self.max_turns:
|
||||||
logger.warning(f"⚠️ 已达到最大决策步数限制: {self.max_turns}")
|
logger.warning(f"⚠️ Reached max decision step limit: {self.max_turns}")
|
||||||
|
|
||||||
# Force model to summarize without tool calls
|
# Force model to summarize without tool calls
|
||||||
logger.info(f"[Agent] Requesting summary from LLM after reaching max steps...")
|
logger.info(f"[Agent] Requesting summary from LLM after reaching max steps...")
|
||||||
@@ -650,15 +656,15 @@ class AgentStreamExecutor:
|
|||||||
logger.info(f"💭 Summary: {summary_response[:150]}{'...' if len(summary_response) > 150 else ''}")
|
logger.info(f"💭 Summary: {summary_response[:150]}{'...' if len(summary_response) > 150 else ''}")
|
||||||
else:
|
else:
|
||||||
# Fallback if model still doesn't respond
|
# Fallback if model still doesn't respond
|
||||||
final_response = (
|
final_response = _t(
|
||||||
f"我已经执行了{turn}个决策步骤,达到了单次运行的步数上限。"
|
f"我已经执行了{turn}个决策步骤,达到了单次运行的步数上限。任务可能还未完全完成,建议你将任务拆分成更小的步骤,或者换一种方式描述需求。",
|
||||||
"任务可能还未完全完成,建议你将任务拆分成更小的步骤,或者换一种方式描述需求。"
|
f"I've taken {turn} decision steps and reached the per-run limit. The task may not be fully complete — try breaking it into smaller steps, or describe your request differently.",
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"Failed to get summary from LLM: {e}")
|
logger.warning(f"Failed to get summary from LLM: {e}")
|
||||||
final_response = (
|
final_response = _t(
|
||||||
f"我已经执行了{turn}个决策步骤,达到了单次运行的步数上限。"
|
f"我已经执行了{turn}个决策步骤,达到了单次运行的步数上限。任务可能还未完全完成,建议你将任务拆分成更小的步骤,或者换一种方式描述需求。",
|
||||||
"任务可能还未完全完成,建议你将任务拆分成更小的步骤,或者换一种方式描述需求。"
|
f"I've taken {turn} decision steps and reached the per-run limit. The task may not be fully complete — try breaking it into smaller steps, or describe your request differently.",
|
||||||
)
|
)
|
||||||
finally:
|
finally:
|
||||||
# Remove the injected user prompt from history to avoid polluting
|
# Remove the injected user prompt from history to avoid polluting
|
||||||
@@ -673,13 +679,13 @@ class AgentStreamExecutor:
|
|||||||
# User-initiated stop: wind down message history cleanly so the
|
# User-initiated stop: wind down message history cleanly so the
|
||||||
# next turn is unaffected; channels emit a "cancelled" UI event.
|
# next turn is unaffected; channels emit a "cancelled" UI event.
|
||||||
cancelled = True
|
cancelled = True
|
||||||
logger.info(f"[Agent] 🛑 已被用户中止 (第 {turn} 轮)")
|
logger.info(f"[Agent] 🛑 Cancelled by user (turn {turn})")
|
||||||
self._handle_cancelled(final_response)
|
self._handle_cancelled(final_response)
|
||||||
if not final_response or not final_response.strip():
|
if not final_response or not final_response.strip():
|
||||||
final_response = "_(Cancelled)_"
|
final_response = "_(Cancelled)_"
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"❌ Agent执行错误: {e}")
|
logger.error(f"❌ Agent execution error: {e}")
|
||||||
self._emit_event("error", {"error": str(e)})
|
self._emit_event("error", {"error": str(e)})
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@@ -688,7 +694,7 @@ class AgentStreamExecutor:
|
|||||||
if cancelled:
|
if cancelled:
|
||||||
# Emit before agent_end so channels can mark UI as cancelled
|
# Emit before agent_end so channels can mark UI as cancelled
|
||||||
self._emit_event("agent_cancelled", {"final_response": final_response})
|
self._emit_event("agent_cancelled", {"final_response": final_response})
|
||||||
logger.info(f"[Agent] 🏁 完成 ({turn}轮)" + (" [cancelled]" if cancelled else ""))
|
logger.info(f"[Agent] 🏁 Done ({turn} turns)" + (" [cancelled]" if cancelled else ""))
|
||||||
self._emit_event("agent_end", {"final_response": final_response, "cancelled": cancelled})
|
self._emit_event("agent_end", {"final_response": final_response, "cancelled": cancelled})
|
||||||
|
|
||||||
return final_response
|
return final_response
|
||||||
@@ -747,6 +753,22 @@ class AgentStreamExecutor:
|
|||||||
"input_schema": input_schema,
|
"input_schema": input_schema,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# Debug: dump the full system prompt and messages sent to the LLM.
|
||||||
|
# Gated behind `debug` config to avoid flooding normal logs.
|
||||||
|
# try:
|
||||||
|
# from config import conf
|
||||||
|
# if conf().get("debug", False):
|
||||||
|
# logger.debug(
|
||||||
|
# "[Agent][debug] system_prompt sent to LLM "
|
||||||
|
# f"({len(self.system_prompt or '')} chars):\n"
|
||||||
|
# "================ SYSTEM PROMPT BEGIN ================\n"
|
||||||
|
# f"{self.system_prompt}\n"
|
||||||
|
# "================ SYSTEM PROMPT END =================="
|
||||||
|
# )
|
||||||
|
# logger.info(f"[Agent][debug] messages sent to LLM: {messages}")
|
||||||
|
# except Exception:
|
||||||
|
# pass
|
||||||
|
|
||||||
# Create request
|
# Create request
|
||||||
request = LLMRequest(
|
request = LLMRequest(
|
||||||
messages=messages,
|
messages=messages,
|
||||||
@@ -953,13 +975,15 @@ class AgentStreamExecutor:
|
|||||||
self.messages.clear()
|
self.messages.clear()
|
||||||
self._clear_session_db()
|
self._clear_session_db()
|
||||||
if is_context_overflow:
|
if is_context_overflow:
|
||||||
raise Exception(
|
raise Exception(_t(
|
||||||
"抱歉,对话历史过长导致上下文溢出。我已清空历史记录,请重新描述你的需求。"
|
"抱歉,对话历史过长导致上下文溢出。我已清空历史记录,请重新描述你的需求。",
|
||||||
)
|
"Sorry, the conversation history got too long and overflowed the context. I've cleared the history — please describe your request again.",
|
||||||
|
))
|
||||||
else:
|
else:
|
||||||
raise Exception(
|
raise Exception(_t(
|
||||||
"抱歉,之前的对话出现了问题。我已清空历史记录,请重新发送你的消息。"
|
"抱歉,之前的对话出现了问题。我已清空历史记录,请重新发送你的消息。",
|
||||||
)
|
"Sorry, something went wrong with the earlier conversation. I've cleared the history — please send your message again.",
|
||||||
|
))
|
||||||
|
|
||||||
# Check if error is rate limit (429)
|
# Check if error is rate limit (429)
|
||||||
is_rate_limit = '429' in error_str_lower or 'rate limit' in error_str_lower
|
is_rate_limit = '429' in error_str_lower or 'rate limit' in error_str_lower
|
||||||
@@ -1538,8 +1562,8 @@ class AgentStreamExecutor:
|
|||||||
turns = turns[-keep_count:]
|
turns = turns[-keep_count:]
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"💾 上下文轮次超限: {keep_count + removed_count} > {self.max_context_turns},"
|
f"💾 Context turns exceeded: {keep_count + removed_count} > {self.max_context_turns}, "
|
||||||
f"裁剪至 {keep_count} 轮(移除 {removed_count} 轮)"
|
f"trimmed to {keep_count} turns (removed {removed_count})"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Flush to daily memory + inject context summary (single async LLM call)
|
# Flush to daily memory + inject context summary (single async LLM call)
|
||||||
@@ -1587,7 +1611,7 @@ class AgentStreamExecutor:
|
|||||||
|
|
||||||
# Log if we removed messages due to turn limit
|
# Log if we removed messages due to turn limit
|
||||||
if old_count > len(self.messages):
|
if old_count > len(self.messages):
|
||||||
logger.info(f" 重建消息列表: {old_count} -> {len(self.messages)} 条消息")
|
logger.info(f" Rebuilt message list: {old_count} -> {len(self.messages)} messages")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Token limit exceeded — tiered strategy based on turn count:
|
# Token limit exceeded — tiered strategy based on turn count:
|
||||||
@@ -1620,10 +1644,10 @@ class AgentStreamExecutor:
|
|||||||
self.messages = new_messages
|
self.messages = new_messages
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"📦 上下文tokens超限(轮次<{COMPRESS_THRESHOLD}): "
|
f"📦 Context tokens exceeded (turns<{COMPRESS_THRESHOLD}): "
|
||||||
f"~{current_tokens + system_tokens} > {max_tokens},"
|
f"~{current_tokens + system_tokens} > {max_tokens}, "
|
||||||
f"压缩全部 {len(turns)} 轮为纯文本 "
|
f"compressed all {len(turns)} turns to plain text "
|
||||||
f"({old_count} -> {len(self.messages)} 条消息,"
|
f"({old_count} -> {len(self.messages)} messages, "
|
||||||
f"~{current_tokens + system_tokens} -> ~{new_tokens + system_tokens} tokens)"
|
f"~{current_tokens + system_tokens} -> ~{new_tokens + system_tokens} tokens)"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
@@ -1636,8 +1660,8 @@ class AgentStreamExecutor:
|
|||||||
kept_tokens = sum(self._estimate_turn_tokens(t) for t in kept_turns)
|
kept_tokens = sum(self._estimate_turn_tokens(t) for t in kept_turns)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"🔄 上下文tokens超限: ~{current_tokens + system_tokens} > {max_tokens},"
|
f"🔄 Context tokens exceeded: ~{current_tokens + system_tokens} > {max_tokens}, "
|
||||||
f"裁剪至 {keep_count} 轮(移除 {removed_count} 轮)"
|
f"trimmed to {keep_count} turns (removed {removed_count})"
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.agent.memory_manager:
|
if self.agent.memory_manager:
|
||||||
@@ -1661,8 +1685,8 @@ class AgentStreamExecutor:
|
|||||||
self.messages = new_messages
|
self.messages = new_messages
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f" 移除了 {removed_count} 轮对话 "
|
f" Removed {removed_count} turns "
|
||||||
f"({old_count} -> {len(self.messages)} 条消息,"
|
f"({old_count} -> {len(self.messages)} messages, "
|
||||||
f"~{current_tokens + system_tokens} -> ~{kept_tokens + system_tokens} tokens)"
|
f"~{current_tokens + system_tokens} -> ~{kept_tokens + system_tokens} tokens)"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -643,16 +643,25 @@ class AgentInitializer:
|
|||||||
except Exception:
|
except Exception:
|
||||||
timezone_name = "UTC"
|
timezone_name = "UTC"
|
||||||
|
|
||||||
# Chinese weekday mapping
|
# Weekday: English name in en, Chinese mapping otherwise
|
||||||
weekday_map = {
|
weekday_en = now.strftime("%A")
|
||||||
'Monday': '星期一', 'Tuesday': '星期二', 'Wednesday': '星期三',
|
try:
|
||||||
'Thursday': '星期四', 'Friday': '星期五', 'Saturday': '星期六', 'Sunday': '星期日'
|
from common import i18n
|
||||||
}
|
is_en = i18n.get_language() == "en"
|
||||||
weekday_zh = weekday_map.get(now.strftime("%A"), now.strftime("%A"))
|
except Exception:
|
||||||
|
is_en = False
|
||||||
|
if is_en:
|
||||||
|
weekday = weekday_en
|
||||||
|
else:
|
||||||
|
weekday_map = {
|
||||||
|
'Monday': '星期一', 'Tuesday': '星期二', 'Wednesday': '星期三',
|
||||||
|
'Thursday': '星期四', 'Friday': '星期五', 'Saturday': '星期六', 'Sunday': '星期日'
|
||||||
|
}
|
||||||
|
weekday = weekday_map.get(weekday_en, weekday_en)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'time': now.strftime("%Y-%m-%d %H:%M:%S"),
|
'time': now.strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
'weekday': weekday_zh,
|
'weekday': weekday,
|
||||||
'timezone': timezone_name
|
'timezone': timezone_name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from bridge.reply import *
|
|||||||
from channel.channel import Channel
|
from channel.channel import Channel
|
||||||
from common.dequeue import Dequeue
|
from common.dequeue import Dequeue
|
||||||
from common import memory
|
from common import memory
|
||||||
|
from common.i18n import t as _t
|
||||||
from plugins import *
|
from plugins import *
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -265,7 +266,7 @@ class ChatChannel(Channel):
|
|||||||
if reply.type in self.NOT_SUPPORT_REPLYTYPE:
|
if reply.type in self.NOT_SUPPORT_REPLYTYPE:
|
||||||
logger.error("[chat_channel]reply type not support: " + str(reply.type))
|
logger.error("[chat_channel]reply type not support: " + str(reply.type))
|
||||||
reply.type = ReplyType.ERROR
|
reply.type = ReplyType.ERROR
|
||||||
reply.content = "不支持发送的消息类型: " + str(reply.type)
|
reply.content = _t("不支持发送的消息类型: ", "Unsupported message type: ") + str(reply.type)
|
||||||
|
|
||||||
if reply.type == ReplyType.TEXT:
|
if reply.type == ReplyType.TEXT:
|
||||||
reply_text = reply.content
|
reply_text = reply.content
|
||||||
@@ -476,9 +477,9 @@ class ChatChannel(Channel):
|
|||||||
|
|
||||||
cancelled = get_cancel_registry().cancel_session(session_id)
|
cancelled = get_cancel_registry().cancel_session(session_id)
|
||||||
text = (
|
text = (
|
||||||
"🛑 已中止"
|
_t("🛑 已中止", "🛑 Cancelled")
|
||||||
if cancelled > 0
|
if cancelled > 0
|
||||||
else "当前没有可中止的任务。"
|
else _t("当前没有可中止的任务。", "Nothing to cancel.")
|
||||||
)
|
)
|
||||||
logger.info(
|
logger.info(
|
||||||
f"[chat_channel] /cancel fast-path: session={session_id}, cancelled={cancelled}"
|
f"[chat_channel] /cancel fast-path: session={session_id}, cancelled={cancelled}"
|
||||||
|
|||||||
@@ -47,11 +47,30 @@
|
|||||||
This runs synchronously in <head> so the correct class is on <html>
|
This runs synchronously in <head> so the correct class is on <html>
|
||||||
before any CSS or body rendering occurs. -->
|
before any CSS or body rendering occurs. -->
|
||||||
<script>
|
<script>
|
||||||
|
// Map an arbitrary locale string (zh-CN, en-US, fr ...) to 'zh' / 'en',
|
||||||
|
// or '' when unrecognized so callers can fall through to the next source.
|
||||||
|
window.__cowNormalizeLang__ = function(raw) {
|
||||||
|
if (!raw) return '';
|
||||||
|
var v = String(raw).trim().toLowerCase();
|
||||||
|
if (v === 'auto') return '';
|
||||||
|
if (v.indexOf('zh') === 0) return 'zh';
|
||||||
|
if (v.indexOf('en') === 0) return 'en';
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
// Resolve the console language by priority:
|
||||||
|
// user choice (localStorage) -> backend-detected -> browser -> 'zh'.
|
||||||
|
window.__cowResolveLang__ = function() {
|
||||||
|
return window.__cowNormalizeLang__(localStorage.getItem('cow_lang'))
|
||||||
|
|| window.__cowNormalizeLang__(window.__COW_DEFAULT_LANG__)
|
||||||
|
|| window.__cowNormalizeLang__(navigator.language || (navigator.languages && navigator.languages[0]))
|
||||||
|
|| 'zh';
|
||||||
|
};
|
||||||
(function() {
|
(function() {
|
||||||
|
// Backend-resolved default language (from cow_lang config / auto-detect).
|
||||||
|
window.__COW_DEFAULT_LANG__ = '{{COW_DEFAULT_LANG}}';
|
||||||
var theme = localStorage.getItem('cow_theme') || 'dark';
|
var theme = localStorage.getItem('cow_theme') || 'dark';
|
||||||
if (theme === 'dark') document.documentElement.classList.add('dark');
|
if (theme === 'dark') document.documentElement.classList.add('dark');
|
||||||
var lang = localStorage.getItem('cow_lang') || 'zh';
|
document.documentElement.setAttribute('lang', window.__cowResolveLang__());
|
||||||
document.documentElement.setAttribute('lang', lang);
|
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
@@ -640,6 +659,31 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Language 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-sky-50 dark:bg-sky-900/30 flex items-center justify-center">
|
||||||
|
<i class="fas fa-language text-sky-500 text-sm"></i>
|
||||||
|
</div>
|
||||||
|
<h3 class="font-semibold text-slate-800 dark:text-slate-100" data-i18n="config_language">语言</h3>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-4">
|
||||||
|
<div>
|
||||||
|
<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_language">语言</span>
|
||||||
|
<span class="cfg-tip" data-tip-key="config_language_hint"><i class="fas fa-circle-question"></i></span>
|
||||||
|
</label>
|
||||||
|
<div id="cfg-lang-select" class="cfg-dropdown" tabindex="0">
|
||||||
|
<div class="cfg-dropdown-selected">
|
||||||
|
<span class="cfg-dropdown-text">--</span>
|
||||||
|
<i class="fas fa-chevron-down cfg-dropdown-arrow"></i>
|
||||||
|
</div>
|
||||||
|
<div class="cfg-dropdown-menu"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -91,9 +91,31 @@ const I18N = {
|
|||||||
example_knowledge_title: '知识库', example_knowledge_text: '查看知识库当前文档情况',
|
example_knowledge_title: '知识库', example_knowledge_text: '查看知识库当前文档情况',
|
||||||
example_skill_title: '技能系统', example_skill_text: '查看所有支持的工具和技能',
|
example_skill_title: '技能系统', example_skill_text: '查看所有支持的工具和技能',
|
||||||
example_web_title: '指令中心', example_web_text: '查看全部命令',
|
example_web_title: '指令中心', example_web_text: '查看全部命令',
|
||||||
|
slash_help: '显示命令帮助',
|
||||||
|
slash_status: '查看运行状态',
|
||||||
|
slash_context: '查看对话上下文',
|
||||||
|
slash_context_clear: '清除对话上下文',
|
||||||
|
slash_skill_list: '查看已安装技能',
|
||||||
|
slash_skill_list_remote: '浏览技能广场',
|
||||||
|
slash_skill_search: '搜索技能',
|
||||||
|
slash_skill_install: '安装技能 (名称或 GitHub URL)',
|
||||||
|
slash_skill_uninstall: '卸载技能',
|
||||||
|
slash_skill_info: '查看技能详情',
|
||||||
|
slash_skill_enable: '启用技能',
|
||||||
|
slash_skill_disable: '禁用技能',
|
||||||
|
slash_memory_dream: '手动触发记忆蒸馏 (可指定天数, 默认3)',
|
||||||
|
slash_knowledge: '查看知识库统计',
|
||||||
|
slash_knowledge_list: '查看知识库文件树',
|
||||||
|
slash_knowledge_on: '开启知识库',
|
||||||
|
slash_knowledge_off: '关闭知识库',
|
||||||
|
slash_config: '查看当前配置',
|
||||||
|
slash_cancel: '中止当前正在运行的 Agent 任务',
|
||||||
|
slash_logs: '查看最近日志',
|
||||||
|
slash_version: '查看版本',
|
||||||
input_placeholder: '输入消息,或输入 / 使用指令',
|
input_placeholder: '输入消息,或输入 / 使用指令',
|
||||||
config_title: '配置管理', config_desc: '管理模型和 Agent 配置',
|
config_title: '配置管理', config_desc: '管理模型和 Agent 配置',
|
||||||
config_model: '模型配置', config_agent: 'Agent 配置',
|
config_model: '模型配置', config_agent: 'Agent 配置',
|
||||||
|
config_language: '语言', config_language_hint: '界面展示、命令文案、系统提示词等使用的语言(与右上角切换同步)',
|
||||||
config_model_advanced: '高级配置',
|
config_model_advanced: '高级配置',
|
||||||
config_channel: '通道配置',
|
config_channel: '通道配置',
|
||||||
config_agent_enabled: 'Agent 模式',
|
config_agent_enabled: 'Agent 模式',
|
||||||
@@ -265,9 +287,31 @@ const I18N = {
|
|||||||
example_knowledge_title: 'Knowledge', example_knowledge_text: 'Show me the current knowledge base',
|
example_knowledge_title: 'Knowledge', example_knowledge_text: 'Show me the current knowledge base',
|
||||||
example_skill_title: 'Skills', example_skill_text: 'Show current tools and skills',
|
example_skill_title: 'Skills', example_skill_text: 'Show current tools and skills',
|
||||||
example_web_title: 'Commands', example_web_text: 'Show all commands',
|
example_web_title: 'Commands', example_web_text: 'Show all commands',
|
||||||
|
slash_help: 'Show this help',
|
||||||
|
slash_status: 'Show running status',
|
||||||
|
slash_context: 'Show conversation context',
|
||||||
|
slash_context_clear: 'Clear conversation context',
|
||||||
|
slash_skill_list: 'List installed skills',
|
||||||
|
slash_skill_list_remote: 'Browse Skill Hub',
|
||||||
|
slash_skill_search: 'Search skills',
|
||||||
|
slash_skill_install: 'Install a skill (name or GitHub URL)',
|
||||||
|
slash_skill_uninstall: 'Uninstall a skill',
|
||||||
|
slash_skill_info: 'Show skill details',
|
||||||
|
slash_skill_enable: 'Enable a skill',
|
||||||
|
slash_skill_disable: 'Disable a skill',
|
||||||
|
slash_memory_dream: 'Trigger memory distillation (optional days, default 3)',
|
||||||
|
slash_knowledge: 'Show knowledge base stats',
|
||||||
|
slash_knowledge_list: 'Show knowledge base file tree',
|
||||||
|
slash_knowledge_on: 'Enable knowledge base',
|
||||||
|
slash_knowledge_off: 'Disable knowledge base',
|
||||||
|
slash_config: 'Show current config',
|
||||||
|
slash_cancel: 'Abort the running Agent task',
|
||||||
|
slash_logs: 'Show recent logs',
|
||||||
|
slash_version: 'Show version',
|
||||||
input_placeholder: 'Type a message, or press / for commands',
|
input_placeholder: 'Type a message, or press / for commands',
|
||||||
config_title: 'Configuration', config_desc: 'Manage model and agent settings',
|
config_title: 'Configuration', config_desc: 'Manage model and agent settings',
|
||||||
config_model: 'Model Configuration', config_agent: 'Agent Configuration',
|
config_model: 'Model Configuration', config_agent: 'Agent Configuration',
|
||||||
|
config_language: 'Language', config_language_hint: 'Language for the UI, command text, system prompts and more (synced with the top-right switch)',
|
||||||
config_model_advanced: 'Advanced',
|
config_model_advanced: 'Advanced',
|
||||||
config_channel: 'Channel Configuration',
|
config_channel: 'Channel Configuration',
|
||||||
config_agent_enabled: 'Agent Mode',
|
config_agent_enabled: 'Agent Mode',
|
||||||
@@ -361,7 +405,25 @@ const I18N = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let currentLang = localStorage.getItem('cow_lang') || 'zh';
|
// Resolve language by priority: user choice (localStorage) -> backend-detected
|
||||||
|
// (cow_lang) -> browser language -> 'zh'. Shares __cowResolveLang__ defined in
|
||||||
|
// chat.html; falls back to a local resolver if loaded standalone.
|
||||||
|
let currentLang = (typeof window.__cowResolveLang__ === 'function')
|
||||||
|
? window.__cowResolveLang__()
|
||||||
|
: (function () {
|
||||||
|
const norm = (raw) => {
|
||||||
|
if (!raw) return '';
|
||||||
|
const v = String(raw).trim().toLowerCase();
|
||||||
|
if (v === 'auto') return '';
|
||||||
|
if (v.indexOf('zh') === 0) return 'zh';
|
||||||
|
if (v.indexOf('en') === 0) return 'en';
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
return norm(localStorage.getItem('cow_lang'))
|
||||||
|
|| norm(window.__COW_DEFAULT_LANG__)
|
||||||
|
|| norm(navigator.language)
|
||||||
|
|| 'zh';
|
||||||
|
})();
|
||||||
|
|
||||||
function t(key) {
|
function t(key) {
|
||||||
return (I18N[currentLang] && I18N[currentLang][key]) || (I18N.en[key]) || key;
|
return (I18N[currentLang] && I18N[currentLang][key]) || (I18N.en[key]) || key;
|
||||||
@@ -394,14 +456,60 @@ function applyI18n() {
|
|||||||
if (langLabel) langLabel.textContent = currentLang === 'zh' ? '中文' : 'EN';
|
if (langLabel) langLabel.textContent = currentLang === 'zh' ? '中文' : 'EN';
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleLanguage() {
|
// Single entry point for switching language. Updates the in-memory language,
|
||||||
currentLang = currentLang === 'zh' ? 'en' : 'zh';
|
// persists the user choice locally, re-renders the UI, and binds the choice to
|
||||||
|
// the backend `cow_lang` config so logs / agent replies / CLI follow suit.
|
||||||
|
function setLanguage(lang) {
|
||||||
|
const next = (lang === 'en') ? 'en' : 'zh';
|
||||||
|
if (next === currentLang) {
|
||||||
|
// Still persist + sync in case storage/backend drifted from the UI.
|
||||||
|
syncLanguageToBackend(next);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
currentLang = next;
|
||||||
localStorage.setItem('cow_lang', currentLang);
|
localStorage.setItem('cow_lang', currentLang);
|
||||||
applyI18n();
|
applyI18n();
|
||||||
_applyInputTooltips();
|
_applyInputTooltips();
|
||||||
// Re-render views whose DOM is built in JS (data-i18n alone does not
|
// Re-render views whose DOM is built in JS (data-i18n alone does not
|
||||||
// cover strings interpolated via t() into innerHTML).
|
// cover strings interpolated via t() into innerHTML).
|
||||||
try { rerenderDynamicViews(); } catch (e) {}
|
try { rerenderDynamicViews(); } catch (e) {}
|
||||||
|
// Keep the language switch button and config selector visually in sync.
|
||||||
|
try { updateLangControls(); } catch (e) {}
|
||||||
|
syncLanguageToBackend(currentLang);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Persist the language to the backend `cow_lang` config (best-effort; the UI
|
||||||
|
// has already switched locally, so a network failure is non-blocking).
|
||||||
|
function syncLanguageToBackend(lang) {
|
||||||
|
try {
|
||||||
|
fetch('/config', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ updates: { cow_lang: lang } })
|
||||||
|
}).catch(() => {});
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reflect the current language on both the top-right toggle and the config
|
||||||
|
// selector (if present), so the two entry points stay synchronized.
|
||||||
|
function updateLangControls() {
|
||||||
|
const langLabel = document.getElementById('lang-label');
|
||||||
|
if (langLabel) langLabel.textContent = currentLang === 'zh' ? '中文' : 'EN';
|
||||||
|
// The config language picker is the custom .cfg-dropdown component. Only
|
||||||
|
// sync it once it has been initialized (i.e. the config panel was opened).
|
||||||
|
const sel = document.getElementById('cfg-lang-select');
|
||||||
|
if (sel && sel._ddValue !== undefined && sel._ddValue !== currentLang) {
|
||||||
|
sel._ddValue = currentLang;
|
||||||
|
const textEl = sel.querySelector('.cfg-dropdown-text');
|
||||||
|
if (textEl) textEl.textContent = currentLang === 'zh' ? '中文' : 'English';
|
||||||
|
sel.querySelectorAll('.cfg-dropdown-item').forEach(i => {
|
||||||
|
i.classList.toggle('active', i.dataset.value === currentLang);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleLanguage() {
|
||||||
|
setLanguage(currentLang === 'zh' ? 'en' : 'zh');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh JS-rendered views after a language switch. Each branch uses the
|
// Refresh JS-rendered views after a language switch. Each branch uses the
|
||||||
@@ -1298,28 +1406,30 @@ chatInput.addEventListener('compositionstart', () => { isComposing = true; });
|
|||||||
chatInput.addEventListener('compositionend', () => { setTimeout(() => { isComposing = false; }, 100); });
|
chatInput.addEventListener('compositionend', () => { setTimeout(() => { isComposing = false; }, 100); });
|
||||||
|
|
||||||
// ── Slash Command Menu ───────────────────────────────────────
|
// ── Slash Command Menu ───────────────────────────────────────
|
||||||
|
// desc holds an i18n key, resolved via t() at render time so the menu follows
|
||||||
|
// the current UI language.
|
||||||
const SLASH_COMMANDS = [
|
const SLASH_COMMANDS = [
|
||||||
{ cmd: '/help', desc: '显示命令帮助' },
|
{ cmd: '/help', desc: 'slash_help' },
|
||||||
{ cmd: '/status', desc: '查看运行状态' },
|
{ cmd: '/status', desc: 'slash_status' },
|
||||||
{ cmd: '/context', desc: '查看对话上下文' },
|
{ cmd: '/context', desc: 'slash_context' },
|
||||||
{ cmd: '/context clear', desc: '清除对话上下文' },
|
{ cmd: '/context clear', desc: 'slash_context_clear' },
|
||||||
{ cmd: '/skill list', desc: '查看已安装技能' },
|
{ cmd: '/skill list', desc: 'slash_skill_list' },
|
||||||
{ cmd: '/skill list --remote', desc: '浏览技能广场' },
|
{ cmd: '/skill list --remote', desc: 'slash_skill_list_remote' },
|
||||||
{ cmd: '/skill search ', desc: '搜索技能' },
|
{ cmd: '/skill search ', desc: 'slash_skill_search' },
|
||||||
{ cmd: '/skill install ', desc: '安装技能 (名称或 GitHub URL)' },
|
{ cmd: '/skill install ', desc: 'slash_skill_install' },
|
||||||
{ cmd: '/skill uninstall ', desc: '卸载技能' },
|
{ cmd: '/skill uninstall ', desc: 'slash_skill_uninstall' },
|
||||||
{ cmd: '/skill info ', desc: '查看技能详情' },
|
{ cmd: '/skill info ', desc: 'slash_skill_info' },
|
||||||
{ cmd: '/skill enable ', desc: '启用技能' },
|
{ cmd: '/skill enable ', desc: 'slash_skill_enable' },
|
||||||
{ cmd: '/skill disable ', desc: '禁用技能' },
|
{ cmd: '/skill disable ', desc: 'slash_skill_disable' },
|
||||||
{ cmd: '/memory dream ', desc: '手动触发记忆蒸馏 (可指定天数, 默认3)' },
|
{ cmd: '/memory dream ', desc: 'slash_memory_dream' },
|
||||||
{ cmd: '/knowledge', desc: '查看知识库统计' },
|
{ cmd: '/knowledge', desc: 'slash_knowledge' },
|
||||||
{ cmd: '/knowledge list', desc: '查看知识库文件树' },
|
{ cmd: '/knowledge list', desc: 'slash_knowledge_list' },
|
||||||
{ cmd: '/knowledge on', desc: '开启知识库' },
|
{ cmd: '/knowledge on', desc: 'slash_knowledge_on' },
|
||||||
{ cmd: '/knowledge off', desc: '关闭知识库' },
|
{ cmd: '/knowledge off', desc: 'slash_knowledge_off' },
|
||||||
{ cmd: '/config', desc: '查看当前配置' },
|
{ cmd: '/config', desc: 'slash_config' },
|
||||||
{ cmd: '/cancel', desc: '中止当前正在运行的 Agent 任务' },
|
{ cmd: '/cancel', desc: 'slash_cancel' },
|
||||||
{ cmd: '/logs', desc: '查看最近日志' },
|
{ cmd: '/logs', desc: 'slash_logs' },
|
||||||
{ cmd: '/version', desc: '查看版本' },
|
{ cmd: '/version', desc: 'slash_version' },
|
||||||
];
|
];
|
||||||
|
|
||||||
const slashMenu = document.getElementById('slash-menu');
|
const slashMenu = document.getElementById('slash-menu');
|
||||||
@@ -1373,7 +1483,7 @@ function renderSlashItems() {
|
|||||||
slashFiltered.map((c, i) =>
|
slashFiltered.map((c, i) =>
|
||||||
`<div class="slash-menu-item${i === slashActiveIdx ? ' active' : ''}" data-idx="${i}">` +
|
`<div class="slash-menu-item${i === slashActiveIdx ? ' active' : ''}" data-idx="${i}">` +
|
||||||
`<span class="cmd">${escapeHtml(c.cmd)}</span>` +
|
`<span class="cmd">${escapeHtml(c.cmd)}</span>` +
|
||||||
`<span class="desc">${escapeHtml(c.desc)}</span></div>`
|
`<span class="desc">${escapeHtml(t(c.desc))}</span></div>`
|
||||||
).join('');
|
).join('');
|
||||||
|
|
||||||
const activeEl = slashMenu.querySelector('.slash-menu-item.active');
|
const activeEl = slashMenu.querySelector('.slash-menu-item.active');
|
||||||
@@ -3296,6 +3406,18 @@ function initConfigView(data) {
|
|||||||
document.getElementById('cfg-max-steps').value = data.agent_max_steps || 20;
|
document.getElementById('cfg-max-steps').value = data.agent_max_steps || 20;
|
||||||
document.getElementById('cfg-enable-thinking').checked = data.enable_thinking === true;
|
document.getElementById('cfg-enable-thinking').checked = data.enable_thinking === true;
|
||||||
|
|
||||||
|
// Reflect the current UI language (already resolved, may include the user's
|
||||||
|
// local choice) on the selector so it stays in sync with the top-right toggle.
|
||||||
|
const langSel = document.getElementById('cfg-lang-select');
|
||||||
|
if (langSel) {
|
||||||
|
initDropdown(
|
||||||
|
langSel,
|
||||||
|
[{ value: 'zh', label: '中文' }, { value: 'en', label: 'English' }],
|
||||||
|
currentLang,
|
||||||
|
(val) => setLanguage(val)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const pwdInput = document.getElementById('cfg-password');
|
const pwdInput = document.getElementById('cfg-password');
|
||||||
const maskedPwd = data.web_password_masked || '';
|
const maskedPwd = data.web_password_masked || '';
|
||||||
pwdInput.value = maskedPwd;
|
pwdInput.value = maskedPwd;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ from channel.chat_channel import ChatChannel, check_prefix
|
|||||||
from channel.chat_message import ChatMessage
|
from channel.chat_message import ChatMessage
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from common import const
|
from common import const
|
||||||
|
from common import i18n
|
||||||
from common.log import logger
|
from common.log import logger
|
||||||
from common.singleton import singleton
|
from common.singleton import singleton
|
||||||
from config import conf
|
from config import conf
|
||||||
@@ -98,7 +99,7 @@ def _require_auth():
|
|||||||
def _cancel_reply_text(cancelled: int, lang: str) -> str:
|
def _cancel_reply_text(cancelled: int, lang: str) -> str:
|
||||||
en = lang.startswith("en")
|
en = lang.startswith("en")
|
||||||
if cancelled > 0:
|
if cancelled > 0:
|
||||||
return "🛑 Cancelled." if en else "🛑 已中止"
|
return "🛑 Cancelled" if en else "🛑 已中止"
|
||||||
return "Nothing to cancel." if en else "当前没有可中止的任务。"
|
return "Nothing to cancel." if en else "当前没有可中止的任务。"
|
||||||
|
|
||||||
|
|
||||||
@@ -477,7 +478,10 @@ class WebChannel(ChatChannel):
|
|||||||
)
|
)
|
||||||
q.put({
|
q.put({
|
||||||
"type": "done",
|
"type": "done",
|
||||||
"content": "(模型未返回任何内容,请重试或换一种方式描述你的需求)",
|
"content": i18n.t(
|
||||||
|
"(模型未返回任何内容,请重试或换一种方式描述你的需求)",
|
||||||
|
"(The model returned no content. Please retry or rephrase your request.)",
|
||||||
|
),
|
||||||
"request_id": request_id,
|
"request_id": request_id,
|
||||||
"timestamp": time.time(),
|
"timestamp": time.time(),
|
||||||
})
|
})
|
||||||
@@ -805,13 +809,13 @@ class WebChannel(ChatChannel):
|
|||||||
if not fpath:
|
if not fpath:
|
||||||
continue
|
continue
|
||||||
if ftype == "image":
|
if ftype == "image":
|
||||||
file_refs.append(f"[图片: {fpath}]")
|
file_refs.append(f"[{i18n.t('图片', 'Image')}: {fpath}]")
|
||||||
elif ftype == "video":
|
elif ftype == "video":
|
||||||
file_refs.append(f"[视频: {fpath}]")
|
file_refs.append(f"[{i18n.t('视频', 'Video')}: {fpath}]")
|
||||||
elif ftype == "directory":
|
elif ftype == "directory":
|
||||||
file_refs.append(f"[目录: {fpath}]")
|
file_refs.append(f"[{i18n.t('目录', 'Directory')}: {fpath}]")
|
||||||
else:
|
else:
|
||||||
file_refs.append(f"[文件: {fpath}]")
|
file_refs.append(f"[{i18n.t('文件', 'File')}: {fpath}]")
|
||||||
if file_refs:
|
if file_refs:
|
||||||
prompt = prompt + "\n" + "\n".join(file_refs)
|
prompt = prompt + "\n" + "\n".join(file_refs)
|
||||||
logger.info(f"[WebChannel] Attached {len(file_refs)} file(s) to message")
|
logger.info(f"[WebChannel] Attached {len(file_refs)} file(s) to message")
|
||||||
@@ -952,7 +956,7 @@ class WebChannel(ChatChannel):
|
|||||||
if request_id and request_id in self.sse_queues:
|
if request_id and request_id in self.sse_queues:
|
||||||
self.sse_queues[request_id].put({
|
self.sse_queues[request_id].put({
|
||||||
"type": "cancelled",
|
"type": "cancelled",
|
||||||
"content": "Cancelled" if lang.startswith("en") else "已中止",
|
"content": "🛑 Cancelled" if lang.startswith("en") else "🛑 已中止",
|
||||||
"request_id": request_id,
|
"request_id": request_id,
|
||||||
"timestamp": time.time(),
|
"timestamp": time.time(),
|
||||||
})
|
})
|
||||||
@@ -1008,7 +1012,10 @@ class WebChannel(ChatChannel):
|
|||||||
"""Serve the chat HTML page."""
|
"""Serve the chat HTML page."""
|
||||||
file_path = os.path.join(os.path.dirname(__file__), 'chat.html') # 使用绝对路径
|
file_path = os.path.join(os.path.dirname(__file__), 'chat.html') # 使用绝对路径
|
||||||
with open(file_path, 'r', encoding='utf-8') as f:
|
with open(file_path, 'r', encoding='utf-8') as f:
|
||||||
return f.read()
|
html = f.read()
|
||||||
|
# Inject the backend-resolved default language so the console can use
|
||||||
|
# it on first load (when the user has no saved cow_lang preference).
|
||||||
|
return html.replace("{{COW_DEFAULT_LANG}}", i18n.get_language())
|
||||||
|
|
||||||
def startup(self):
|
def startup(self):
|
||||||
configured_host = conf().get("web_host", "")
|
configured_host = conf().get("web_host", "")
|
||||||
@@ -1388,6 +1395,8 @@ class ChatHandler:
|
|||||||
cache_bust = str(int(time.time()))
|
cache_bust = str(int(time.time()))
|
||||||
html = html.replace('assets/js/console.js', f'assets/js/console.js?v={cache_bust}')
|
html = html.replace('assets/js/console.js', f'assets/js/console.js?v={cache_bust}')
|
||||||
html = html.replace('assets/css/console.css', f'assets/css/console.css?v={cache_bust}')
|
html = html.replace('assets/css/console.css', f'assets/css/console.css?v={cache_bust}')
|
||||||
|
# Inject the backend-resolved default language for first-load fallback.
|
||||||
|
html = html.replace("{{COW_DEFAULT_LANG}}", i18n.get_language())
|
||||||
return html
|
return html
|
||||||
|
|
||||||
|
|
||||||
@@ -1526,6 +1535,7 @@ class ConfigHandler:
|
|||||||
])
|
])
|
||||||
|
|
||||||
EDITABLE_KEYS = {
|
EDITABLE_KEYS = {
|
||||||
|
"cow_lang",
|
||||||
"model", "bot_type", "use_linkai",
|
"model", "bot_type", "use_linkai",
|
||||||
"open_ai_api_base", "deepseek_api_base", "qianfan_api_base", "claude_api_base", "gemini_api_base",
|
"open_ai_api_base", "deepseek_api_base", "qianfan_api_base", "claude_api_base", "gemini_api_base",
|
||||||
"zhipu_ai_api_base", "moonshot_base_url", "ark_base_url", "custom_api_base", "mimo_api_base",
|
"zhipu_ai_api_base", "moonshot_base_url", "ark_base_url", "custom_api_base", "mimo_api_base",
|
||||||
@@ -1634,6 +1644,15 @@ class ConfigHandler:
|
|||||||
|
|
||||||
logger.info(f"[WebChannel] Config updated: {list(applied.keys())}")
|
logger.info(f"[WebChannel] Config updated: {list(applied.keys())}")
|
||||||
|
|
||||||
|
# Apply a language change immediately so backend logs, agent
|
||||||
|
# replies and CLI output switch without a restart.
|
||||||
|
if "cow_lang" in applied:
|
||||||
|
try:
|
||||||
|
i18n.resolve_language(applied["cow_lang"])
|
||||||
|
logger.info(f"[WebChannel] Language switched to: {i18n.get_language()}")
|
||||||
|
except Exception as lang_err:
|
||||||
|
logger.warning(f"[WebChannel] Failed to apply language: {lang_err}")
|
||||||
|
|
||||||
# Reset Bridge so that bot routing reflects the new config.
|
# Reset Bridge so that bot routing reflects the new config.
|
||||||
# Without this, Bridge keeps its cached bot instance (e.g. LinkAIBot)
|
# Without this, Bridge keeps its cached bot instance (e.g. LinkAIBot)
|
||||||
# even after the user switches bot_type / use_linkai / model in UI.
|
# even after the user switches bot_type / use_linkai / model in UI.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ CHINA_MIRROR = "https://registry.npmmirror.com/-/binary/playwright"
|
|||||||
|
|
||||||
# stream(msg, fg=None) — fg is "yellow" | "green" | "red" | None
|
# stream(msg, fg=None) — fg is "yellow" | "green" | "red" | None
|
||||||
StreamFn = Callable[[str, Optional[str]], None]
|
StreamFn = Callable[[str, Optional[str]], None]
|
||||||
# on_phase(msg) — coarse-grained progress for chat channels (Chinese)
|
# on_phase(msg) — coarse-grained progress for chat channels (localized via i18n)
|
||||||
PhaseFn = Callable[[str], None]
|
PhaseFn = Callable[[str], None]
|
||||||
|
|
||||||
|
|
||||||
@@ -112,16 +112,27 @@ def run_install_browser(
|
|||||||
stream: Optional callback ``(message, fg)`` for each line. ``fg`` is
|
stream: Optional callback ``(message, fg)`` for each line. ``fg`` is
|
||||||
``yellow`` / ``green`` / ``red`` or None. Defaults to colored click output.
|
``yellow`` / ``green`` / ``red`` or None. Defaults to colored click output.
|
||||||
on_phase: Optional callback for coarse progress (e.g. push to chat);
|
on_phase: Optional callback for coarse progress (e.g. push to chat);
|
||||||
messages are short Chinese status lines.
|
messages are short status lines localized via i18n.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
0 on success, 1 on fatal failure (pip or chromium install failed).
|
0 on success, 1 on fatal failure (pip or chromium install failed).
|
||||||
"""
|
"""
|
||||||
|
from cli.utils import get_cli_language
|
||||||
|
|
||||||
|
# Import `common` only after get_cli_language() runs ensure_sys_path(),
|
||||||
|
# so it works when `cow` is invoked from outside the project directory.
|
||||||
|
get_cli_language() # resolve cow_lang so i18n.t reflects config
|
||||||
|
from common import i18n
|
||||||
|
_t = i18n.t
|
||||||
|
|
||||||
stream = stream or _default_stream
|
stream = stream or _default_stream
|
||||||
python = sys.executable
|
python = sys.executable
|
||||||
legacy_mode = False
|
legacy_mode = False
|
||||||
|
|
||||||
_phase(on_phase, "🔧 开始安装浏览器工具依赖(约几分钟,请耐心等待)…")
|
_phase(on_phase, _t(
|
||||||
|
"🔧 开始安装浏览器工具依赖(约几分钟,请耐心等待)…",
|
||||||
|
"🔧 Installing browser tool dependencies (a few minutes, please wait)…",
|
||||||
|
))
|
||||||
|
|
||||||
glibc = _get_glibc_version()
|
glibc = _get_glibc_version()
|
||||||
if glibc and glibc < GLIBC_THRESHOLD:
|
if glibc and glibc < GLIBC_THRESHOLD:
|
||||||
@@ -136,27 +147,36 @@ def run_install_browser(
|
|||||||
stream("")
|
stream("")
|
||||||
_phase(
|
_phase(
|
||||||
on_phase,
|
on_phase,
|
||||||
f"ℹ️ 检测到 glibc {glibc_str}(较旧),将安装兼容版 Playwright {PLAYWRIGHT_LEGACY_VERSION}。",
|
_t(
|
||||||
|
f"ℹ️ 检测到 glibc {glibc_str}(较旧),将安装兼容版 Playwright {PLAYWRIGHT_LEGACY_VERSION}。",
|
||||||
|
f"ℹ️ Detected glibc {glibc_str} (older); installing compatible Playwright {PLAYWRIGHT_LEGACY_VERSION}.",
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
target_version = PLAYWRIGHT_LEGACY_VERSION if legacy_mode else PLAYWRIGHT_VERSION
|
target_version = PLAYWRIGHT_LEGACY_VERSION if legacy_mode else PLAYWRIGHT_VERSION
|
||||||
|
|
||||||
_phase(on_phase, "📦 [1/3] 正在安装 Playwright Python 包…")
|
_phase(on_phase, _t("📦 [1/3] 正在安装 Playwright Python 包…", "📦 [1/3] Installing Playwright Python package…"))
|
||||||
stream("[1/3] Installing playwright Python package...", "yellow")
|
stream("[1/3] Installing playwright Python package...", "yellow")
|
||||||
ret = _pip_install(f"playwright=={target_version}", stream)
|
ret = _pip_install(f"playwright=={target_version}", stream)
|
||||||
if ret != 0:
|
if ret != 0:
|
||||||
stream("Failed to install playwright package.", "red")
|
stream("Failed to install playwright package.", "red")
|
||||||
_phase(on_phase, "❌ [1/3] Playwright Python 包安装失败。")
|
_phase(on_phase, _t("❌ [1/3] Playwright Python 包安装失败。", "❌ [1/3] Failed to install Playwright Python package."))
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
installed = _get_installed_version()
|
installed = _get_installed_version()
|
||||||
if installed:
|
if installed:
|
||||||
stream(f" playwright {installed} installed.", "green")
|
stream(f" playwright {installed} installed.", "green")
|
||||||
stream("")
|
stream("")
|
||||||
_phase(on_phase, f"✅ [1/3] Playwright 包已安装({installed or target_version})。")
|
_phase(on_phase, _t(
|
||||||
|
f"✅ [1/3] Playwright 包已安装({installed or target_version})。",
|
||||||
|
f"✅ [1/3] Playwright package installed ({installed or target_version}).",
|
||||||
|
))
|
||||||
|
|
||||||
if sys.platform == "linux":
|
if sys.platform == "linux":
|
||||||
_phase(on_phase, "🔧 [2/3] 正在安装 Linux 系统依赖与轻量中文字体(文泉驿正黑,部分步骤可能需要 sudo)…")
|
_phase(on_phase, _t(
|
||||||
|
"🔧 [2/3] 正在安装 Linux 系统依赖与轻量中文字体(文泉驿正黑,部分步骤可能需要 sudo)…",
|
||||||
|
"🔧 [2/3] Installing Linux system deps and a lightweight CJK font (WenQuanYi Zen Hei; some steps may need sudo)…",
|
||||||
|
))
|
||||||
stream("[2/3] Installing system dependencies (Linux)...", "yellow")
|
stream("[2/3] Installing system dependencies (Linux)...", "yellow")
|
||||||
ret = subprocess.call([python, "-m", "playwright", "install-deps", "chromium"])
|
ret = subprocess.call([python, "-m", "playwright", "install-deps", "chromium"])
|
||||||
if ret != 0:
|
if ret != 0:
|
||||||
@@ -183,14 +203,23 @@ def run_install_browser(
|
|||||||
stream(" CJK font (wqy-zenhei) installed.", "green")
|
stream(" CJK font (wqy-zenhei) installed.", "green")
|
||||||
_phase(
|
_phase(
|
||||||
on_phase,
|
on_phase,
|
||||||
"✅ [2/3] Linux 依赖与字体步骤已执行(若有权限问题请查看服务器日志或手动执行提示命令)。",
|
_t(
|
||||||
|
"✅ [2/3] Linux 依赖与字体步骤已执行(若有权限问题请查看服务器日志或手动执行提示命令)。",
|
||||||
|
"✅ [2/3] Linux deps and font steps executed (on permission issues, check the server log or run the suggested commands manually).",
|
||||||
|
),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
stream(f"[2/3] Skipping system deps (not needed on {sys.platform}).", "yellow")
|
stream(f"[2/3] Skipping system deps (not needed on {sys.platform}).", "yellow")
|
||||||
_phase(on_phase, f"ℹ️ [2/3] 当前系统({sys.platform})跳过 Linux 专用依赖。")
|
_phase(on_phase, _t(
|
||||||
|
f"ℹ️ [2/3] 当前系统({sys.platform})跳过 Linux 专用依赖。",
|
||||||
|
f"ℹ️ [2/3] Skipping Linux-specific deps on this platform ({sys.platform}).",
|
||||||
|
))
|
||||||
stream("")
|
stream("")
|
||||||
|
|
||||||
_phase(on_phase, "🌐 [3/3] 正在下载并安装 Chromium(体积较大,请耐心等待)…")
|
_phase(on_phase, _t(
|
||||||
|
"🌐 [3/3] 正在下载并安装 Chromium(体积较大,请耐心等待)…",
|
||||||
|
"🌐 [3/3] Downloading and installing Chromium (large download, please wait)…",
|
||||||
|
))
|
||||||
stream("[3/3] Installing Chromium browser...", "yellow")
|
stream("[3/3] Installing Chromium browser...", "yellow")
|
||||||
cmd = [python, "-m", "playwright", "install", "chromium"]
|
cmd = [python, "-m", "playwright", "install", "chromium"]
|
||||||
|
|
||||||
@@ -209,27 +238,33 @@ def run_install_browser(
|
|||||||
if use_mirror:
|
if use_mirror:
|
||||||
env["PLAYWRIGHT_DOWNLOAD_HOST"] = CHINA_MIRROR
|
env["PLAYWRIGHT_DOWNLOAD_HOST"] = CHINA_MIRROR
|
||||||
stream(f" (using China mirror: {CHINA_MIRROR})", None)
|
stream(f" (using China mirror: {CHINA_MIRROR})", None)
|
||||||
_phase(on_phase, "📡 检测到国内 pip 源配置,Chromium 将优先走国内镜像下载。")
|
_phase(on_phase, _t(
|
||||||
|
"📡 检测到国内 pip 源配置,Chromium 将优先走国内镜像下载。",
|
||||||
|
"📡 Detected a China pip mirror; Chromium will be downloaded from the China mirror first.",
|
||||||
|
))
|
||||||
|
|
||||||
ret = subprocess.call(cmd, env=env)
|
ret = subprocess.call(cmd, env=env)
|
||||||
|
|
||||||
if ret != 0 and use_mirror:
|
if ret != 0 and use_mirror:
|
||||||
stream(" Mirror download failed, retrying with official CDN...", "yellow")
|
stream(" Mirror download failed, retrying with official CDN...", "yellow")
|
||||||
_phase(on_phase, "⚠️ 镜像下载失败,正在改用官方源重试…")
|
_phase(on_phase, _t(
|
||||||
|
"⚠️ 镜像下载失败,正在改用官方源重试…",
|
||||||
|
"⚠️ Mirror download failed; retrying with the official CDN…",
|
||||||
|
))
|
||||||
env_no_mirror = os.environ.copy()
|
env_no_mirror = os.environ.copy()
|
||||||
env_no_mirror.pop("PLAYWRIGHT_DOWNLOAD_HOST", None)
|
env_no_mirror.pop("PLAYWRIGHT_DOWNLOAD_HOST", None)
|
||||||
ret = subprocess.call(cmd, env=env_no_mirror)
|
ret = subprocess.call(cmd, env=env_no_mirror)
|
||||||
|
|
||||||
if ret != 0:
|
if ret != 0:
|
||||||
stream("Failed to install Chromium.", "red")
|
stream("Failed to install Chromium.", "red")
|
||||||
_phase(on_phase, "❌ [3/3] Chromium 安装失败。")
|
_phase(on_phase, _t("❌ [3/3] Chromium 安装失败。", "❌ [3/3] Failed to install Chromium."))
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
stream("")
|
stream("")
|
||||||
_phase(on_phase, "✅ [3/3] Chromium 已安装。")
|
_phase(on_phase, _t("✅ [3/3] Chromium 已安装。", "✅ [3/3] Chromium installed."))
|
||||||
|
|
||||||
stream("Verifying browser installation...", None)
|
stream("Verifying browser installation...", None)
|
||||||
_phase(on_phase, "🔍 正在验证 Playwright 能否正常加载…")
|
_phase(on_phase, _t("🔍 正在验证 Playwright 能否正常加载…", "🔍 Verifying that Playwright loads correctly…"))
|
||||||
ret = subprocess.call(
|
ret = subprocess.call(
|
||||||
[python, "-c", "from playwright.sync_api import sync_playwright; print('OK')"],
|
[python, "-c", "from playwright.sync_api import sync_playwright; print('OK')"],
|
||||||
stderr=subprocess.DEVNULL,
|
stderr=subprocess.DEVNULL,
|
||||||
@@ -240,14 +275,20 @@ def run_install_browser(
|
|||||||
" Consider upgrading your OS or using Docker.",
|
" Consider upgrading your OS or using Docker.",
|
||||||
"yellow",
|
"yellow",
|
||||||
)
|
)
|
||||||
_phase(on_phase, "⚠️ 验证未完全通过:本机可能仍无法使用浏览器工具,请查看日志或升级系统。")
|
_phase(on_phase, _t(
|
||||||
|
"⚠️ 验证未完全通过:本机可能仍无法使用浏览器工具,请查看日志或升级系统。",
|
||||||
|
"⚠️ Verification did not fully pass: the browser tool may still not work here; check the log or upgrade your system.",
|
||||||
|
))
|
||||||
else:
|
else:
|
||||||
stream(" Verification passed.", "green")
|
stream(" Verification passed.", "green")
|
||||||
_phase(on_phase, "✅ 验证通过。")
|
_phase(on_phase, _t("✅ 验证通过。", "✅ Verification passed."))
|
||||||
|
|
||||||
stream("")
|
stream("")
|
||||||
stream("Browser tool ready! Restart CowAgent to enable it.", "green")
|
stream("Browser tool ready! Restart CowAgent to enable it.", "green")
|
||||||
_phase(on_phase, "🎉 全部步骤结束。请重启 CowAgent 后使用 browser 工具。")
|
_phase(on_phase, _t(
|
||||||
|
"🎉 全部步骤结束。请重启 CowAgent 后使用 browser 工具。",
|
||||||
|
"🎉 All steps finished. Restart CowAgent to use the browser tool.",
|
||||||
|
))
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -275,7 +275,14 @@ def update(ctx):
|
|||||||
def status():
|
def status():
|
||||||
"""Show CowAgent running status."""
|
"""Show CowAgent running status."""
|
||||||
from cli import __version__
|
from cli import __version__
|
||||||
from cli.utils import load_config_json
|
from cli.utils import load_config_json, get_cli_language
|
||||||
|
|
||||||
|
# get_cli_language() calls ensure_sys_path(), which adds the project root
|
||||||
|
# to sys.path. Import `common` only AFTER that, otherwise it fails with
|
||||||
|
# ModuleNotFoundError when `cow` runs from outside the project dir.
|
||||||
|
get_cli_language() # resolve cow_lang so i18n.t reflects config
|
||||||
|
from common import i18n
|
||||||
|
_t = i18n.t
|
||||||
|
|
||||||
pid = _read_pid()
|
pid = _read_pid()
|
||||||
if pid:
|
if pid:
|
||||||
@@ -283,17 +290,19 @@ def status():
|
|||||||
else:
|
else:
|
||||||
click.echo(click.style("● CowAgent is not running", fg="red"))
|
click.echo(click.style("● CowAgent is not running", fg="red"))
|
||||||
|
|
||||||
click.echo(f" 版本: v{__version__}")
|
click.echo(_t(f" 版本: v{__version__}", f" Version: v{__version__}"))
|
||||||
|
|
||||||
cfg = load_config_json()
|
cfg = load_config_json()
|
||||||
if cfg:
|
if cfg:
|
||||||
channel = cfg.get("channel_type", "unknown")
|
channel = cfg.get("channel_type", "unknown")
|
||||||
if isinstance(channel, list):
|
if isinstance(channel, list):
|
||||||
channel = ", ".join(channel)
|
channel = ", ".join(channel)
|
||||||
click.echo(f" 通道: {channel}")
|
click.echo(_t(f" 通道: {channel}", f" Channel: {channel}"))
|
||||||
click.echo(f" 模型: {cfg.get('model', 'unknown')}")
|
click.echo(_t(f" 模型: {cfg.get('model', 'unknown')}", f" Model: {cfg.get('model', 'unknown')}"))
|
||||||
mode = "Chat" if cfg.get("agent") is False else "Agent"
|
mode = "Chat" if cfg.get("agent") is False else "Agent"
|
||||||
click.echo(f" 模式: {mode}")
|
click.echo(_t(f" 模式: {mode}", f" Mode: {mode}"))
|
||||||
|
lang_label = "中文" if i18n.get_language() == "zh" else "English"
|
||||||
|
click.echo(_t(f" 语言: {lang_label}", f" Language: {lang_label}"))
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
|
|||||||
@@ -517,18 +517,26 @@ def _install_targz_bytes(content: bytes, name: str, skills_dir: str, result: Ins
|
|||||||
|
|
||||||
def _print_install_success(name: str, source: str):
|
def _print_install_success(name: str, source: str):
|
||||||
"""Print a unified install success message with description and source."""
|
"""Print a unified install success message with description and source."""
|
||||||
|
from cli.utils import get_cli_language
|
||||||
|
|
||||||
|
# Import `common` only after get_cli_language() runs ensure_sys_path(),
|
||||||
|
# so it works when `cow` is invoked from outside the project directory.
|
||||||
|
get_cli_language() # resolve cow_lang so i18n.t reflects config
|
||||||
|
from common import i18n
|
||||||
|
_t = i18n.t
|
||||||
|
|
||||||
skills_dir = get_skills_dir()
|
skills_dir = get_skills_dir()
|
||||||
config = load_skills_config()
|
config = load_skills_config()
|
||||||
display = config.get(name, {}).get("display_name", "")
|
display = config.get(name, {}).get("display_name", "")
|
||||||
desc = _read_skill_description(os.path.join(skills_dir, name))
|
desc = _read_skill_description(os.path.join(skills_dir, name))
|
||||||
click.echo(click.style(f"✓ {name}", fg="green"))
|
click.echo(click.style(f"✓ {name}", fg="green"))
|
||||||
if display and display != name:
|
if display and display != name:
|
||||||
click.echo(f" 名称: {display}")
|
click.echo(_t(f" 名称: {display}", f" Name: {display}"))
|
||||||
if desc:
|
if desc:
|
||||||
if len(desc) > 60:
|
if len(desc) > 60:
|
||||||
desc = desc[:57] + "…"
|
desc = desc[:57] + "…"
|
||||||
click.echo(f" 描述: {desc}")
|
click.echo(_t(f" 描述: {desc}", f" Description: {desc}"))
|
||||||
click.echo(f" 来源: {source}")
|
click.echo(_t(f" 来源: {source}", f" Source: {source}"))
|
||||||
|
|
||||||
|
|
||||||
def _validate_skill_name(name: str):
|
def _validate_skill_name(name: str):
|
||||||
|
|||||||
16
cli/utils.py
16
cli/utils.py
@@ -40,6 +40,22 @@ def load_config_json() -> dict:
|
|||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
def get_cli_language() -> str:
|
||||||
|
"""Resolve the CLI UI language using the shared i18n detector.
|
||||||
|
|
||||||
|
Reads the `cow_lang` field from config.json (defaults to "auto") and runs
|
||||||
|
the same detection used by the running app, so CLI output matches.
|
||||||
|
"""
|
||||||
|
ensure_sys_path()
|
||||||
|
try:
|
||||||
|
from common import i18n
|
||||||
|
|
||||||
|
configured = load_config_json().get("cow_lang", "auto")
|
||||||
|
return i18n.resolve_language(configured)
|
||||||
|
except Exception:
|
||||||
|
return "en"
|
||||||
|
|
||||||
|
|
||||||
def load_skills_config() -> dict:
|
def load_skills_config() -> dict:
|
||||||
"""Load skills_config.json from the custom skills directory."""
|
"""Load skills_config.json from the custom skills directory."""
|
||||||
path = os.path.join(get_skills_dir(), "skills_config.json")
|
path = os.path.join(get_skills_dir(), "skills_config.json")
|
||||||
|
|||||||
177
common/i18n.py
Normal file
177
common/i18n.py
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
# encoding:utf-8
|
||||||
|
|
||||||
|
"""Lightweight global language detection and resolution.
|
||||||
|
|
||||||
|
This module is the single source of truth for the runtime UI language used
|
||||||
|
across the CLI, startup logs, error messages, agent prompts and channel
|
||||||
|
replies. It must NOT import project config (to avoid circular imports) and
|
||||||
|
must stay dependency-free so it can run at the earliest startup phase.
|
||||||
|
|
||||||
|
Resolution priority (highest first):
|
||||||
|
1. Explicit `cow_lang` from config.json — also covers Docker/CI, since any
|
||||||
|
config key is overridable via its uppercase env var (e.g. COW_LANG=zh),
|
||||||
|
handled by config.load_config() before resolution. COW_LANG is a private
|
||||||
|
name to avoid clashing with the gettext-standard LANGUAGE variable.
|
||||||
|
2. macOS `defaults read -g AppleLocale` (system-level preference; a Chinese
|
||||||
|
system locale is a strong signal that beats a shell-default LANG)
|
||||||
|
3. Standard locale env vars: LC_ALL > LC_MESSAGES > LANG
|
||||||
|
4. Python locale module
|
||||||
|
5. Default -> English
|
||||||
|
|
||||||
|
A value of "auto" (the default) triggers detection (steps 2-5). Explicitly
|
||||||
|
setting "zh" or "en" locks the language and skips detection.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Supported language codes
|
||||||
|
ZH = "zh"
|
||||||
|
EN = "en"
|
||||||
|
SUPPORTED = (ZH, EN)
|
||||||
|
DEFAULT_LANG = EN
|
||||||
|
|
||||||
|
# Resolved language cache; None until first resolution.
|
||||||
|
_resolved_lang = None
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize(raw):
|
||||||
|
"""Map an arbitrary locale-ish string to a supported code, or None.
|
||||||
|
|
||||||
|
Only Chinese is detected explicitly; everything else (including unknown
|
||||||
|
or empty values) yields None so the caller can fall through to the next
|
||||||
|
detection source.
|
||||||
|
"""
|
||||||
|
if not raw:
|
||||||
|
return None
|
||||||
|
value = str(raw).strip().lower().replace("_", "-")
|
||||||
|
if value in ("auto", ""):
|
||||||
|
return None
|
||||||
|
# Chinese variants: zh, zh-cn, zh-hans, zh-hans-cn, zh-tw, zh-hk ...
|
||||||
|
if value.startswith("zh") or value.startswith("chinese"):
|
||||||
|
return ZH
|
||||||
|
if value.startswith("en") or value.startswith("english"):
|
||||||
|
return EN
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _detect_from_env():
|
||||||
|
"""Detect language from standard locale environment variables.
|
||||||
|
|
||||||
|
Note: on macOS, `LANG` is often a shell default (e.g. en_US.UTF-8 set by
|
||||||
|
.zshrc) that does not reflect the user's real preference, so AppleLocale
|
||||||
|
is checked first (see detect_language). On Linux these vars are the
|
||||||
|
primary signal.
|
||||||
|
|
||||||
|
The cow_lang env override (COW_LANG=zh) is intentionally NOT read here:
|
||||||
|
it sets config["cow_lang"] and is handled via the explicit config path,
|
||||||
|
not auto-detection.
|
||||||
|
"""
|
||||||
|
for key in ("LC_ALL", "LC_MESSAGES", "LANG"):
|
||||||
|
lang = _normalize(os.environ.get(key))
|
||||||
|
if lang:
|
||||||
|
return lang
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _detect_from_macos():
|
||||||
|
"""macOS fallback: read the system-wide AppleLocale preference.
|
||||||
|
|
||||||
|
On macOS the terminal often does NOT export LANG, yet the system locale
|
||||||
|
is still meaningful (e.g. a Chinese Mac reports zh_CN). This recovers
|
||||||
|
that signal so Chinese users are not misdetected as English.
|
||||||
|
"""
|
||||||
|
if sys.platform != "darwin":
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
out = subprocess.run(
|
||||||
|
["defaults", "read", "-g", "AppleLocale"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=2,
|
||||||
|
)
|
||||||
|
if out.returncode == 0:
|
||||||
|
return _normalize(out.stdout)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _detect_from_python_locale():
|
||||||
|
"""Last-resort detection via Python's locale module."""
|
||||||
|
try:
|
||||||
|
import locale
|
||||||
|
|
||||||
|
for value in locale.getlocale():
|
||||||
|
lang = _normalize(value)
|
||||||
|
if lang:
|
||||||
|
return lang
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def detect_language():
|
||||||
|
"""Run full auto-detection and return a supported language code.
|
||||||
|
|
||||||
|
Order (auto-detection only; explicit config["cow_lang"] is resolved
|
||||||
|
before this is reached):
|
||||||
|
1. macOS AppleLocale (system-level preference; a Chinese system locale
|
||||||
|
is a strong, low-false-positive signal that beats a shell-default
|
||||||
|
LANG like en_US.UTF-8)
|
||||||
|
2. locale env vars LC_ALL / LC_MESSAGES / LANG (primary signal on Linux)
|
||||||
|
3. Python locale module
|
||||||
|
4. default English
|
||||||
|
"""
|
||||||
|
return (
|
||||||
|
_detect_from_macos()
|
||||||
|
or _detect_from_env()
|
||||||
|
or _detect_from_python_locale()
|
||||||
|
or DEFAULT_LANG
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_language(configured=None):
|
||||||
|
"""Resolve the effective language from a configured value.
|
||||||
|
|
||||||
|
`configured` is the raw `cow_lang` value from config.json (may be None,
|
||||||
|
"auto", "zh" or "en"). An explicit "zh"/"en" locks the result; "auto"
|
||||||
|
or empty triggers detection. The result is cached globally.
|
||||||
|
"""
|
||||||
|
global _resolved_lang
|
||||||
|
explicit = _normalize(configured)
|
||||||
|
if explicit:
|
||||||
|
_resolved_lang = explicit
|
||||||
|
else:
|
||||||
|
_resolved_lang = detect_language()
|
||||||
|
return _resolved_lang
|
||||||
|
|
||||||
|
|
||||||
|
def set_language(lang):
|
||||||
|
"""Force the resolved language (used by tests or per-request overrides)."""
|
||||||
|
global _resolved_lang
|
||||||
|
normalized = _normalize(lang)
|
||||||
|
_resolved_lang = normalized or DEFAULT_LANG
|
||||||
|
return _resolved_lang
|
||||||
|
|
||||||
|
|
||||||
|
def get_language():
|
||||||
|
"""Return the currently resolved language, detecting lazily if needed."""
|
||||||
|
global _resolved_lang
|
||||||
|
if _resolved_lang is None:
|
||||||
|
_resolved_lang = detect_language()
|
||||||
|
return _resolved_lang
|
||||||
|
|
||||||
|
|
||||||
|
def is_zh():
|
||||||
|
return get_language() == ZH
|
||||||
|
|
||||||
|
|
||||||
|
def t(zh_text, en_text):
|
||||||
|
"""Pick a string by the current language. Tiny inline-translation helper.
|
||||||
|
|
||||||
|
Intended for one-off strings where a full message catalog is overkill:
|
||||||
|
t("已中止", "Cancelled")
|
||||||
|
"""
|
||||||
|
return zh_text if get_language() == ZH else en_text
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"channel_type": "weixin",
|
"cow_lang": "auto",
|
||||||
|
"channel_type": "web",
|
||||||
"model": "deepseek-v4-flash",
|
"model": "deepseek-v4-flash",
|
||||||
"deepseek_api_key": "",
|
"deepseek_api_key": "",
|
||||||
"deepseek_api_base": "https://api.deepseek.com/v1",
|
"deepseek_api_base": "https://api.deepseek.com/v1",
|
||||||
|
|||||||
11
config.py
11
config.py
@@ -7,11 +7,17 @@ import os
|
|||||||
import pickle
|
import pickle
|
||||||
|
|
||||||
from common.log import logger
|
from common.log import logger
|
||||||
|
from common import i18n
|
||||||
|
|
||||||
# All available config keys are listed in this dict (use lowercase keys).
|
# All available config keys are listed in this dict (use lowercase keys).
|
||||||
# The values here are placeholders only; the program does NOT read them.
|
# The values here are placeholders only; the program does NOT read them.
|
||||||
# They merely document the expected format — put real values in config.json.
|
# They merely document the expected format — put real values in config.json.
|
||||||
available_setting = {
|
available_setting = {
|
||||||
|
# global UI language for CLI, startup logs, error messages, agent prompts
|
||||||
|
# and channel replies. Options: "auto" (detect from system locale, default),
|
||||||
|
# "zh" (Chinese) or "en" (English). An explicit value locks the language.
|
||||||
|
# value: auto/en/zh
|
||||||
|
"cow_lang": "auto",
|
||||||
# openai api config
|
# openai api config
|
||||||
"open_ai_api_key": "", # openai api key
|
"open_ai_api_key": "", # openai api key
|
||||||
# openai api base; when use_azure_chatgpt is true, set the matching api base
|
# openai api base; when use_azure_chatgpt is true, set the matching api base
|
||||||
@@ -390,12 +396,17 @@ def load_config():
|
|||||||
logger.setLevel(logging.DEBUG)
|
logger.setLevel(logging.DEBUG)
|
||||||
logger.debug("[INIT] set log level to DEBUG")
|
logger.debug("[INIT] set log level to DEBUG")
|
||||||
|
|
||||||
|
# Resolve the global UI language as early as possible so that every
|
||||||
|
# downstream layer (logs, CLI, agent prompts, channel replies) shares it.
|
||||||
|
resolved_lang = i18n.resolve_language(config.get("cow_lang", "auto"))
|
||||||
|
|
||||||
logger.info("[INIT] load config: {}".format(drag_sensitive(config)))
|
logger.info("[INIT] load config: {}".format(drag_sensitive(config)))
|
||||||
|
|
||||||
# print system initialization info
|
# print system initialization info
|
||||||
logger.info("[INIT] ========================================")
|
logger.info("[INIT] ========================================")
|
||||||
logger.info("[INIT] System Initialization")
|
logger.info("[INIT] System Initialization")
|
||||||
logger.info("[INIT] ========================================")
|
logger.info("[INIT] ========================================")
|
||||||
|
logger.info("[INIT] Language: {}".format(resolved_lang))
|
||||||
logger.info("[INIT] Channel: {}".format(config.get("channel_type", "unknown")))
|
logger.info("[INIT] Channel: {}".format(config.get("channel_type", "unknown")))
|
||||||
logger.info("[INIT] Model: {}".format(config.get("model", "unknown")))
|
logger.info("[INIT] Model: {}".format(config.get("model", "unknown")))
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "9899:9899"
|
- "9899:9899"
|
||||||
environment:
|
environment:
|
||||||
|
COW_LANG: 'auto'
|
||||||
CHANNEL_TYPE: 'weixin'
|
CHANNEL_TYPE: 'weixin'
|
||||||
MODEL: 'deepseek-v4-flash'
|
MODEL: 'deepseek-v4-flash'
|
||||||
DEEPSEEK_API_KEY: ''
|
DEEPSEEK_API_KEY: ''
|
||||||
|
|||||||
@@ -1,35 +1,35 @@
|
|||||||
---
|
---
|
||||||
title: 钉钉
|
title: DingTalk
|
||||||
description: 将 CowAgent 接入钉钉应用
|
description: Integrate CowAgent into DingTalk application
|
||||||
---
|
---
|
||||||
|
|
||||||
通过钉钉开放平台创建智能机器人应用,将 CowAgent 接入钉钉。
|
Integrate CowAgent into DingTalk by creating an intelligent robot app on the DingTalk Open Platform.
|
||||||
|
|
||||||
## 一、创建应用
|
## 1. Create App
|
||||||
|
|
||||||
1. 进入 [钉钉开发者后台](https://open-dev.dingtalk.com/fe/app#/corp/app),登录后点击 **创建应用**,填写应用相关信息:
|
1. Go to [DingTalk Developer Console](https://open-dev.dingtalk.com/fe/app#/corp/app), log in and click **Create App**, fill in the app information:
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-create-app.png" width="800"/>
|
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-create-app.png" width="800"/>
|
||||||
|
|
||||||
2. 点击添加应用能力,选择 **机器人** 能力,点击 **添加**:
|
2. Click **Add App Capability**, select **Robot** capability and click **Add**:
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-add-bot.png" width="800"/>
|
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-add-bot.png" width="800"/>
|
||||||
|
|
||||||
3. 配置机器人信息后点击 **发布**。发布后,点击 "**点击调试**",会自动创建测试群聊,可在客户端查看:
|
3. Configure the robot information and click **Publish**. After publishing, click "**Debug**" to automatically create a test group chat, which can be viewed in the client:
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-config-bot.png" width="600"/>
|
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-config-bot.png" width="600"/>
|
||||||
|
|
||||||
4. 点击 **版本管理与发布**,创建新版本发布:
|
4. Click **Version Management & Release**, create a new version and publish:
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-publish-bot.png" width="700"/>
|
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-publish-bot.png" width="700"/>
|
||||||
|
|
||||||
## 二、项目配置
|
## 2. Project Configuration
|
||||||
|
|
||||||
1. 点击 **凭证与基础信息**,获取 `Client ID` 和 `Client Secret`:
|
1. Click **Credentials & Basic Info**, get the `Client ID` and `Client Secret`:
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-get-secret.png" width="700"/>
|
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-get-secret.png" width="700"/>
|
||||||
|
|
||||||
2. 将以下配置加入项目根目录的 `config.json` 文件:
|
2. Add the following configuration to `config.json` in the project root:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -39,18 +39,20 @@ description: 将 CowAgent 接入钉钉应用
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
3. 安装依赖:
|
3. Install the dependency:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip3 install dingtalk_stream
|
pip3 install dingtalk_stream
|
||||||
```
|
```
|
||||||
|
|
||||||
4. 启动项目后,在钉钉开发者后台点击 **事件订阅**,点击 **已完成接入,验证连接通道**,显示 **连接接入成功** 即表示配置完成:
|
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-app-config.png" width="700"/>
|
||||||
|
|
||||||
|
4. After starting the project, go to the DingTalk Developer Console, click **Event Subscription**, then click **Connection verified, verify channel**. When "**Connection successful**" is displayed, the configuration is complete:
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-event-sub.png" width="700"/>
|
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-event-sub.png" width="700"/>
|
||||||
|
|
||||||
## 三、使用
|
## 3. Usage
|
||||||
|
|
||||||
与机器人私聊或将机器人拉入企业群中均可开启对话:
|
Chat privately with the robot or add it to an enterprise group to start a conversation:
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-hosting-demo.png" width="650"/>
|
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-hosting-demo.png" width="650"/>
|
||||||
|
|||||||
@@ -1,51 +1,51 @@
|
|||||||
---
|
---
|
||||||
title: Discord
|
title: Discord
|
||||||
description: 将 CowAgent 接入 Discord Bot
|
description: Integrate CowAgent with a Discord Bot
|
||||||
---
|
---
|
||||||
|
|
||||||
> 通过 Discord Bot 的 **Gateway 长连接** 接入 CowAgent,支持私聊(DM)与服务器频道(@机器人 / 回复机器人触发)。Gateway 基于 WebSocket 长连接,无需公网 IP 与回调地址,开箱即用。
|
> Integrate CowAgent into Discord via a Discord Bot using the **Gateway** (persistent WebSocket). Supports direct messages (DM) and server channels (triggered by @mention or replying to the bot). The Gateway uses a persistent WebSocket connection — no public IP or callback URL required, works out of the box.
|
||||||
|
|
||||||
## 一、接入步骤
|
## 1. Setup
|
||||||
|
|
||||||
### 步骤一:创建 Discord 应用与 Bot
|
### Step 1: Create a Discord Application and Bot
|
||||||
|
|
||||||
1. 打开 [Discord 开发者后台](https://discord.com/developers/applications),点击 **New Application**,填写名称(如 `CowAgent`)并创建。
|
1. Open the [Discord Developer Portal](https://discord.com/developers/applications), click **New Application**, enter a name (e.g. `CowAgent`), and create it.
|
||||||
2. 左侧菜单进入 **Bot** 页面,点击 **Reset Token** 生成 Bot Token,复制并妥善保存(仅显示一次)。
|
2. Go to the **Bot** page in the left sidebar, click **Reset Token** to generate a Bot Token, then copy and store it safely (shown only once).
|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
这个 Token 等同于 Bot 的密码,请勿泄露。若意外泄漏,在 Bot 页面再次点击 **Reset Token** 重置即可。
|
This token is your bot's password — keep it secret. If it leaks, click **Reset Token** again on the Bot page to regenerate it.
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
### 步骤二:开启 Message Content Intent
|
### Step 2: Enable the Message Content Intent
|
||||||
|
|
||||||
私聊与频道读取文本均依赖该权限。
|
Reading message text in both DMs and channels depends on this privileged intent.
|
||||||
|
|
||||||
1. 在 **Bot** 页面下方找到 **Privileged Gateway Intents**。
|
1. On the **Bot** page, find **Privileged Gateway Intents**.
|
||||||
2. 打开 **Message Content Intent** 开关并保存。
|
2. Turn on **Message Content Intent** and save.
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
未开启该开关时,机器人收到的消息内容会为空,导致无响应。
|
Without this intent enabled, incoming message content will be empty and the bot will not respond.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
### 步骤三:邀请 Bot 进入服务器
|
### Step 3: Invite the Bot to a Server
|
||||||
|
|
||||||
1. 左侧菜单进入 **OAuth2 → URL Generator**。
|
1. Go to **OAuth2 → URL Generator** in the left sidebar.
|
||||||
2. **Scopes** 勾选 `bot`。
|
2. Under **Scopes**, check `bot`.
|
||||||
3. **Bot Permissions** 至少勾选:`Send Messages`、`Read Message History`、`Attach Files`、`View Channels`。
|
3. Under **Bot Permissions**, check at least: `Send Messages`, `Read Message History`, `Attach Files`, `View Channels`.
|
||||||
4. 复制底部生成的授权链接,在浏览器打开,选择目标服务器完成授权。
|
4. Copy the generated authorization URL at the bottom, open it in a browser, and authorize it for your target server.
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
仅需私聊(DM)可跳过此步,但仍需先在任意共同服务器中与机器人建立 DM 通道,或由用户主动私聊机器人。
|
You can skip this step if you only need DMs, but you still need a DM channel with the bot (e.g. the user messages the bot directly).
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
### 步骤四:接入 CowAgent
|
### Step 4: Connect to CowAgent
|
||||||
|
|
||||||
<Tabs>
|
<Tabs>
|
||||||
<Tab title="Web 控制台(推荐)">
|
<Tab title="Web Console (Recommended)">
|
||||||
打开 Web 控制台(本地链接:http://127.0.0.1:9899 ),选择 **通道** 菜单,点击 **接入通道**,选择 **Discord**,填入 Bot Token,点击接入即可。
|
Open the Web Console (default `http://127.0.0.1:9899`), go to **Channels**, click **Add Channel**, choose **Discord**, paste the Bot Token, and click connect.
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab title="配置文件">
|
<Tab title="Config File">
|
||||||
在 `config.json` 中添加以下配置后启动:
|
Add the following to `config.json` and start Cow:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -55,39 +55,39 @@ description: 将 CowAgent 接入 Discord Bot
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| 参数 | 说明 | 默认值 |
|
| Key | Description | Default |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `discord_token` | 开发者后台 Bot 页面生成的 Bot Token | - |
|
| `discord_token` | Bot Token generated on the Bot page of the Developer Portal | - |
|
||||||
| `discord_group_trigger` | 频道触发方式:`mention_or_reply`(@或回复机器人)/ `mention_only`(仅@) / `all`(所有消息) | `mention_or_reply` |
|
| `discord_group_trigger` | Channel trigger: `mention_or_reply` (@ or reply to bot) / `mention_only` (@ only) / `all` (all messages) | `mention_or_reply` |
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
启动 Cow 后,日志中出现以下输出即表示接入成功:
|
The integration is ready when you see logs like:
|
||||||
|
|
||||||
```
|
```
|
||||||
[Discord] Bot logged in as CowAgent#1234 (id=123456789)
|
[Discord] Bot logged in as CowAgent#1234 (id=123456789)
|
||||||
[Discord] ✅ Discord bot ready, listening for messages
|
[Discord] ✅ Discord bot ready, listening for messages
|
||||||
```
|
```
|
||||||
|
|
||||||
## 二、功能说明
|
## 2. Capabilities
|
||||||
|
|
||||||
| 功能 | 支持情况 |
|
| Feature | Support |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 私聊(DM) | ✅ |
|
| Direct message (DM) | ✅ |
|
||||||
| 服务器频道(@机器人 / 回复机器人) | ✅ |
|
| Server channel (@bot / reply to bot) | ✅ |
|
||||||
| 文本消息 | ✅ 收发 |
|
| Text messages | ✅ send / receive |
|
||||||
| 图片消息 | ✅ 收发 |
|
| Image messages | ✅ send / receive |
|
||||||
| 文件消息 | ✅ 收发(PDF / Word / Excel 等) |
|
| File messages | ✅ send / receive (PDF / Word / Excel, etc.) |
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
Discord 单条消息上限为 2000 字符,超长回复会自动按换行拆分为多条发送。
|
A single Discord message is capped at 2000 characters; long replies are automatically split across multiple messages by line breaks.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## 三、使用
|
## 3. Usage
|
||||||
|
|
||||||
完成接入后:
|
Once connected:
|
||||||
|
|
||||||
- **私聊(DM)**:在服务器成员列表中找到你的机器人,点击头像直接发消息对话。
|
- **Direct message (DM)**: find your bot in the server member list, click its avatar, and message it directly.
|
||||||
- **频道**:在已邀请机器人的频道中,使用 `@你的机器人 你好` 或 **回复机器人的某条消息** 触发对话。
|
- **Channel**: in a channel where the bot is invited, trigger it with `@your-bot hello` or by **replying to one of the bot's messages**.
|
||||||
|
|
||||||
发送图片或文件时,可以在附件的输入框中 **添加文字说明**(描述/问题)一并发送,机器人会结合附件回答。也支持先发附件再发问题,两条消息会自动合并提问。
|
When sending an image or file, you can **add a text caption** (description / question) in the attachment input — the bot will answer based on both. Sending an attachment first and then a follow-up question also works; the two messages are merged automatically.
|
||||||
|
|||||||
@@ -1,45 +1,44 @@
|
|||||||
---
|
---
|
||||||
title: 飞书
|
title: Feishu (Lark)
|
||||||
description: 将 CowAgent 接入飞书应用
|
description: Integrate CowAgent into Feishu via a custom enterprise app
|
||||||
---
|
---
|
||||||
|
|
||||||
> 通过飞书自建应用接入 CowAgent,支持单聊与群聊(@机器人),使用 WebSocket 长连接模式,无需公网 IP,支持流式打字机回复、语音消息收发。
|
> Integrate CowAgent into Feishu via a custom enterprise app. Supports p2p chat and group chat (@bot), uses WebSocket long connection (no public IP needed), supports streaming typewriter replies and voice messages.
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
接入需要是飞书企业用户且具有企业管理权限。
|
You need to be a Feishu enterprise user with admin privileges.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## 一、接入方式
|
## 1. Setup
|
||||||
|
|
||||||
### 方式一:扫码一键接入(推荐)
|
### Option 1: One-click Scan to Create (Recommended)
|
||||||
|
|
||||||
启动 Cow 项目后在终端中即可完成扫码创建。或打开 Web 控制台(本地链接:http://127.0.0.1:9899 ),选择 **通道** 菜单,点击 **接入通道**,选择 **飞书**,点击 **一键创建飞书应用**,使用 **飞书 App** 扫描二维码即可自动完成应用创建并接入:
|
|
||||||
|
|
||||||
|
No need to manually create an app on the Feishu Developer Platform. Start the Cow project, open the web console (default `http://127.0.0.1:9899/`), go to **Channels**, click **Add Channel**, choose **Feishu**, then under the **Scan QR** tab click **One-click Create Feishu App** and scan with the **Feishu App** to complete app creation and connection automatically.
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260505181126.png" width="800"/>
|
<img src="https://cdn.link-ai.tech/doc/20260505181126.png" width="800"/>
|
||||||
|
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
1. `lark-oapi` 依赖版本需要 >=1.5.5
|
1. Requires `lark-oapi` ≥ 1.5.5.
|
||||||
2. 扫码创建出的应用会自动预置全部所需权限(消息收发、卡片读写、群聊事件等)和事件订阅,无需到开发者后台手动配置。
|
2. The created app comes with all required permissions (messaging, card read/write, group events, etc.) and event subscriptions pre-configured — no manual setup on the developer console needed. Currently only the Feishu mainland version is supported (Lark international not yet supported).
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
|
When starting from CLI without `feishu_app_id` configured, the QR code is also printed to the terminal.
|
||||||
|
|
||||||
### 方式二:手动创建接入
|
### Option 2: Manual Setup
|
||||||
|
|
||||||
需要先在飞书开放平台创建自建应用并配置权限,再通过 Web 控制台或配置文件接入。
|
Manually create a custom app on the Feishu Developer Platform, then connect via Web Console or config file.
|
||||||
|
|
||||||
**步骤一:创建应用**
|
**Step 1: Create the App**
|
||||||
|
|
||||||
1. 进入 [飞书开发平台](https://open.feishu.cn/app/),点击 **创建企业自建应用**:
|
1. Go to [Feishu Developer Platform](https://open.feishu.cn/app/), click **Create Enterprise Custom App**:
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/feishu-hosting-create-app.jpg" width="500"/>
|
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/feishu-hosting-create-app.jpg" width="500"/>
|
||||||
|
|
||||||
2. 在 **添加应用能力** 中,为应用添加 **机器人** 能力:
|
2. In **Add App Capabilities**, add the **Bot** capability:
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/feishu-hosting-add-bot.jpg" width="800"/>
|
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/feishu-hosting-add-bot.jpg" width="800"/>
|
||||||
|
|
||||||
3. 在 **权限管理** 中,将以下权限粘贴到输入框,全选并 **批量开通**:
|
3. In **Permission Management**, paste the following permissions and **Batch Enable** all:
|
||||||
|
|
||||||
```
|
```
|
||||||
im:message,im:message.group_at_msg,im:message.group_at_msg:readonly,im:message.p2p_msg,im:message.p2p_msg:readonly,im:message:send_as_bot,im:resource,cardkit:card:write
|
im:message,im:message.group_at_msg,im:message.group_at_msg:readonly,im:message.p2p_msg,im:message.p2p_msg:readonly,im:message:send_as_bot,im:resource,cardkit:card:write
|
||||||
@@ -47,18 +46,18 @@ im:message,im:message.group_at_msg,im:message.group_at_msg:readonly,im:message.p
|
|||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/feishu-hosting-add-auth2.png" width="800"/>
|
<img src="https://cdn.link-ai.tech/doc/feishu-hosting-add-auth2.png" width="800"/>
|
||||||
|
|
||||||
4. 在 **凭证与基础信息** 中获取 `App ID` 和 `App Secret`:
|
4. Get `App ID` and `App Secret` from **Credentials & Basic Info**:
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/feishu-hosting-appid-secret.jpg" width="800"/>
|
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/feishu-hosting-appid-secret.jpg" width="800"/>
|
||||||
|
|
||||||
**步骤二:接入 CowAgent**
|
**Step 2: Connect to CowAgent**
|
||||||
|
|
||||||
<Tabs>
|
<Tabs>
|
||||||
<Tab title="Web 控制台">
|
<Tab title="Web Console">
|
||||||
打开 Web 控制台,选择 **通道** 菜单,点击 **接入通道**,选择 **飞书**,切换到「手动填写」Tab,输入 App ID 和 App Secret,点击接入即可。
|
Open the web console, go to **Channels**, click **Add Channel**, choose **Feishu**, switch to the **Manual** tab, enter App ID and App Secret, then click connect.
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab title="配置文件">
|
<Tab title="Config File">
|
||||||
在 `config.json` 中添加以下配置后启动程序:
|
Add the following to `config.json` and start the program:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -69,43 +68,43 @@ im:message,im:message.group_at_msg,im:message.group_at_msg:readonly,im:message.p
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| 参数 | 说明 | 默认值 |
|
| Parameter | Description | Default |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `feishu_app_id` | 飞书应用 App ID | - |
|
| `feishu_app_id` | Feishu app App ID | - |
|
||||||
| `feishu_app_secret` | 飞书应用 App Secret | - |
|
| `feishu_app_secret` | Feishu app App Secret | - |
|
||||||
| `feishu_stream_reply` | 是否开启流式打字机回复 | `true` |
|
| `feishu_stream_reply` | Enable streaming typewriter reply | `true` |
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
**步骤三:发布应用**
|
**Step 3: Publish the App**
|
||||||
|
|
||||||
1. 启动 Cow 项目后,在飞书开放平台点击 **事件与回调**,选择 **长连接** 模式并保存:
|
1. After Cow is running, go to **Events & Callbacks** in the Feishu Developer Platform, choose **Long Connection** mode and save:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/202601311731183.png" width="600"/>
|
<img src="https://cdn.link-ai.tech/doc/202601311731183.png" width="600"/>
|
||||||
|
|
||||||
2. 点击 **添加事件**,搜索 "接收消息",选择 **接收消息 v2.0** 并确认。
|
2. Click **Add Event**, search for "Receive Message" and choose **Receive Message v2.0**.
|
||||||
|
|
||||||
3. 点击 **版本管理与发布**,创建版本并申请 **线上发布**,在飞书客户端审核通过:
|
3. Click **Version Management & Release**, create a version and apply for **Production Release**. Approve the request in the Feishu client:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/202601311807356.png" width="600"/>
|
<img src="https://cdn.link-ai.tech/doc/202601311807356.png" width="600"/>
|
||||||
|
|
||||||
## 二、功能说明
|
## 2. Features
|
||||||
|
|
||||||
| 功能 | 支持情况 |
|
| Feature | Status |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 单聊 | ✅ |
|
| P2P chat | ✅ |
|
||||||
| 群聊(@机器人) | ✅ |
|
| Group chat (@bot) | ✅ |
|
||||||
| 文本消息 | ✅ 收发 |
|
| Text messages | ✅ send/receive |
|
||||||
| 图片消息 | ✅ 收发 |
|
| Image messages | ✅ send/receive |
|
||||||
| 语音消息 | ✅ 收发 |
|
| Voice messages | ✅ send/receive |
|
||||||
| 流式回复 | ✅(通过 `feishu_stream_reply` 配置控制,默认开启) |
|
| Streaming reply | ✅ (powered by Feishu cardkit streaming card) |
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
流式回复需要机器人具备 `cardkit:card:write` 权限(一键创建已默认开通),且接收方飞书客户端版本 ≥ 7.20。低版本客户端会显示升级提示,权限或版本不满足时自动降级为普通文本回复。
|
Streaming reply requires the `cardkit:card:write` permission (already enabled by one-click creation) and Feishu client version ≥ 7.20. Older clients see an upgrade prompt; if the permission or version is not satisfied, replies fall back to plain text automatically.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## 三、使用
|
## 3. Usage
|
||||||
|
|
||||||
完成接入后,在飞书中搜索机器人名称即可开始单聊对话。
|
After connection, search for the bot name in Feishu to start a chat.
|
||||||
|
|
||||||
如需在群聊中使用,将机器人添加到群中,@机器人发送消息即可。
|
To use in groups, add the bot to a group and @-mention it.
|
||||||
|
|||||||
@@ -1,45 +1,45 @@
|
|||||||
---
|
---
|
||||||
title: 通道概览
|
title: Channels Overview
|
||||||
description: CowAgent 支持的通道及能力矩阵
|
description: Channels supported by CowAgent and their capability matrix
|
||||||
---
|
---
|
||||||
|
|
||||||
CowAgent 支持接入多种聊天通道,启动时通过 `channel_type` 切换。Web 控制台默认开启,可与其他接入通道并行运行。
|
CowAgent supports multiple chat channels. Switch between them at startup via `channel_type`. The Web Console is enabled by default and can run in parallel with other channels.
|
||||||
|
|
||||||
## 能力矩阵
|
## Capability Matrix
|
||||||
|
|
||||||
下表汇总各通道支持的入站消息类型、机器人回复类型与群聊能力,方便按场景选择。
|
The table below summarizes the inbound message types, bot reply types, and group chat capabilities supported by each channel, making it easy to choose by scenario.
|
||||||
|
|
||||||
| 通道 | 文本 | 图片 | 文件 | 语音 | 群聊 |
|
| Channel | Text | Image | File | Voice | Group Chat |
|
||||||
| --- | :-: | :-: | :-: | :-: | :-: |
|
| --- | :-: | :-: | :-: | :-: | :-: |
|
||||||
| [微信](/channels/weixin) | ✅ | ✅ | ✅ | ✅ | |
|
| [WeChat](/channels/weixin) | ✅ | ✅ | ✅ | ✅ | |
|
||||||
| [Web 控制台](/channels/web) | ✅ | ✅ | ✅ | ✅ | |
|
| [Web Console](/channels/web) | ✅ | ✅ | ✅ | ✅ | |
|
||||||
| [飞书](/channels/feishu) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| [Feishu](/channels/feishu) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [钉钉](/channels/dingtalk) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| [DingTalk](/channels/dingtalk) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [企微智能机器人](/channels/wecom-bot) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| [WeCom Bot](/channels/wecom-bot) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [QQ](/channels/qq) | ✅ | ✅ | ✅ | | ✅ |
|
| [QQ](/channels/qq) | ✅ | ✅ | ✅ | | ✅ |
|
||||||
| [企业微信应用](/channels/wecom) | ✅ | ✅ | ✅ | ✅ | |
|
| [WeCom App](/channels/wecom) | ✅ | ✅ | ✅ | ✅ | |
|
||||||
| [公众号](/channels/wechatmp) | ✅ | ✅ | | ✅ | |
|
| [Official Account](/channels/wechatmp) | ✅ | ✅ | | ✅ | |
|
||||||
| [Telegram](/channels/telegram) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| [Telegram](/channels/telegram) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| [Slack](/channels/slack) | ✅ | ✅ | ✅ | | ✅ |
|
| [Slack](/channels/slack) | ✅ | ✅ | ✅ | | ✅ |
|
||||||
| [Discord](/channels/discord) | ✅ | ✅ | ✅ | | ✅ |
|
| [Discord](/channels/discord) | ✅ | ✅ | ✅ | | ✅ |
|
||||||
|
|
||||||
- **图片 / 文件 / 语音**列表示通道支持收发对应消息类型,具体细节详见各通道文档
|
- The **Image / File / Voice** columns indicate that the channel can send and receive the corresponding message types; see each channel's docs for details
|
||||||
- **群聊**列指可识别并响应群消息
|
- The **Group Chat** column indicates the ability to recognize and respond to group messages
|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
每个通道的语音 / 图像能力依赖对应模型厂商的配置,详见 [模型概览](/models)。
|
The voice / image capabilities of each channel depend on the configuration of the corresponding model provider. See [Models Overview](/models/index) for details.
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
## 通道一览
|
## Channel List
|
||||||
|
|
||||||
- [Web 控制台](/channels/web) — 内置浏览器对话和管理面板,默认开启
|
- [Web Console](/channels/web) — built-in browser-based chat and management panel, enabled by default
|
||||||
- [微信](/channels/weixin) — 通过个人微信扫码登录
|
- [WeChat](/channels/weixin) — log in via personal WeChat QR scan
|
||||||
- [飞书](/channels/feishu) — 飞书自建机器人
|
- [Feishu](/channels/feishu) — Feishu custom bot
|
||||||
- [钉钉](/channels/dingtalk) — 钉钉自建机器人
|
- [DingTalk](/channels/dingtalk) — DingTalk custom bot
|
||||||
- [企微智能机器人](/channels/wecom-bot) — 企业微信智能机器人
|
- [WeCom Bot](/channels/wecom-bot) — WeCom AI Bot via WebSocket long connection
|
||||||
- [QQ](/channels/qq) — QQ 官方机器人开放平台
|
- [QQ](/channels/qq) — QQ Official Bot open platform
|
||||||
- [企业微信应用](/channels/wecom) — 企业微信自建应用接入
|
- [WeCom App](/channels/wecom) — WeCom custom app integration
|
||||||
- [公众号](/channels/wechatmp) — 微信公众号(订阅号 / 服务号)
|
- [Official Account](/channels/wechatmp) — WeChat Official Account (subscription / service)
|
||||||
- [Telegram](/channels/telegram) — 海外 IM,5 分钟接入,无需公网 IP
|
- [Telegram](/channels/telegram) — global IM, 5-minute setup, no public IP needed
|
||||||
- [Slack](/channels/slack) — 团队协作 IM,Socket Mode 接入,无需公网 IP
|
- [Slack](/channels/slack) — team collaboration IM, Socket Mode integration, no public IP needed
|
||||||
- [Discord](/channels/discord) — 社区 IM,Gateway 长连接接入,无需公网 IP
|
- [Discord](/channels/discord) — community IM, Gateway connection, no public IP needed
|
||||||
|
|||||||
@@ -1,44 +1,44 @@
|
|||||||
---
|
---
|
||||||
title: QQ 机器人
|
title: QQ Bot
|
||||||
description: 将 CowAgent 接入 QQ 机器人(WebSocket 长连接模式)
|
description: Connect CowAgent to QQ Bot (WebSocket long connection)
|
||||||
---
|
---
|
||||||
|
|
||||||
> 通过 QQ 开放平台的机器人接口接入 CowAgent,支持 QQ 单聊、QQ 群聊(@机器人)、频道消息和频道私信,无需公网 IP,使用 WebSocket 长连接模式。
|
> Connect CowAgent via QQ Open Platform's bot API, supporting QQ direct messages, group chats (@bot), guild channel messages, and guild DMs. No public IP required — uses WebSocket long connection.
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
QQ 机器人通过 QQ 开放平台创建,使用 WebSocket 长连接接收消息,通过 OpenAPI 发送消息,无需公网 IP 和域名。
|
QQ Bot is created through the QQ Open Platform. It uses WebSocket long connection to receive messages and OpenAPI to send messages. No public IP or domain is required.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## 一、创建 QQ 机器人
|
## 1. Create a QQ Bot
|
||||||
|
|
||||||
> 进入[QQ 开放平台](https://q.qq.com),QQ扫码登录,如果未注册开放平台账号,请先完成[账号注册](https://q.qq.com/#/register)。
|
> Visit the [QQ Open Platform](https://q.qq.com), sign in with QQ. If you haven't registered, please complete [account registration](https://q.qq.com/#/register) first.
|
||||||
|
|
||||||
1.在 [QQ开放平台-机器人列表页](https://q.qq.com/#/apps),点击创建机器人:
|
1.Go to the [QQ Open Platform - Bot List](https://q.qq.com/#/apps), and click **Create Bot**:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260317162900.png" width="800"/>
|
<img src="https://cdn.link-ai.tech/doc/20260317162900.png" width="800"/>
|
||||||
|
|
||||||
2.填写机器人名称、头像等基本信息,完成创建:
|
2.Fill in the bot name, avatar, and other basic information to complete the creation:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260317163005.png" width="800"/>
|
<img src="https://cdn.link-ai.tech/doc/20260317163005.png" width="800"/>
|
||||||
|
|
||||||
3.点击进入机器人配置页面,选择**开发管理**菜单,完成以下步骤:
|
3.Enter the bot configuration page, go to **Development Management**, and complete the following steps:
|
||||||
|
|
||||||
- 复制并记录 **AppID**(机器人ID)
|
- Copy and save the **AppID** (Bot ID)
|
||||||
- 生成并记录 **AppSecret**(机器人秘钥)
|
- Generate and save the **AppSecret** (Bot Secret)
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260317164955.png" width="800"/>
|
<img src="https://cdn.link-ai.tech/doc/20260317164955.png" width="800"/>
|
||||||
|
|
||||||
## 二、配置和运行
|
## 2. Configuration and Running
|
||||||
|
|
||||||
### 方式一:Web 控制台接入
|
### Option A: Web Console
|
||||||
|
|
||||||
启动 Cow项目后打开 Web 控制台 (本地链接为: http://127.0.0.1:9899/ ),选择 **通道** 菜单,点击 **接入通道**,选择 **QQ 机器人**,填写上一步保存的 AppID 和 AppSecret,点击接入即可。
|
Start the program and open the Web console (local access: http://127.0.0.1:9899/). Go to the **Channels** tab, click **Connect Channel**, select **QQ Bot**, fill in the AppID and AppSecret from the previous step, and click Connect.
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260317165425.png" width="800"/>
|
<img src="https://cdn.link-ai.tech/doc/20260317165425.png" width="800"/>
|
||||||
|
|
||||||
### 方式二:配置文件接入
|
### Option B: Config File
|
||||||
|
|
||||||
在 `config.json` 中添加以下配置:
|
Add the following to your `config.json`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -48,41 +48,41 @@ description: 将 CowAgent 接入 QQ 机器人(WebSocket 长连接模式)
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| 参数 | 说明 |
|
| Parameter | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `qq_app_id` | QQ 机器人的 AppID,在开放平台开发管理中获取 |
|
| `qq_app_id` | AppID of the QQ Bot, found in Development Management on the open platform |
|
||||||
| `qq_app_secret` | QQ 机器人的 AppSecret,在开放平台开发管理中获取 |
|
| `qq_app_secret` | AppSecret of the QQ Bot, found in Development Management on the open platform |
|
||||||
|
|
||||||
配置完成后启动程序,日志显示 `[QQ] ✅ Connected successfully` 即表示连接成功。
|
After configuration, start the program. The log message `[QQ] ✅ Connected successfully` indicates a successful connection.
|
||||||
|
|
||||||
|
|
||||||
## 三、使用
|
## 3. Usage
|
||||||
|
|
||||||
在 QQ开放平台 - 管理 - **使用范围和人员** 菜单中,使用QQ客户端扫描 "添加到群和消息列表" 的二维码,即可开始与QQ机器人的聊天:
|
In the QQ Open Platform, go to **Management → Usage Scope & Members**, scan the "Add to group and message list" QR code with your QQ client to start chatting with the bot:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260317165947.png" width="800"/>
|
<img src="https://cdn.link-ai.tech/doc/20260317165947.png" width="800"/>
|
||||||
|
|
||||||
对话效果:
|
Chat example:
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260317171508.png" width="800"/>
|
<img src="https://cdn.link-ai.tech/doc/20260317171508.png" width="800"/>
|
||||||
|
|
||||||
## 四、功能说明
|
## 4. Supported Features
|
||||||
|
|
||||||
> 注意:若需在群聊及频道中使用QQ机器人,需完成发布上架审核并在使用范围配置权限使用范围。
|
> Note: To use the QQ bot in group chats and guild channels, you need to complete the publishing review and configure usage scope permissions.
|
||||||
|
|
||||||
| 功能 | 支持情况 |
|
| Feature | Status |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| QQ 单聊 | ✅ |
|
| QQ Direct Messages | ✅ |
|
||||||
| QQ 群聊(@机器人) | ✅ |
|
| QQ Group Chat (@bot) | ✅ |
|
||||||
| 频道消息(@机器人) | ✅ |
|
| Guild Channel (@bot) | ✅ |
|
||||||
| 频道私信 | ✅ |
|
| Guild DM | ✅ |
|
||||||
| 文本消息 | ✅ 收发 |
|
| Text Messages | ✅ Send & Receive |
|
||||||
| 图片消息 | ✅ 收发(群聊和单聊) |
|
| Image Messages | ✅ Send & Receive (group & direct) |
|
||||||
| 文件消息 | ✅ 发送(群聊和单聊) |
|
| File Messages | ✅ Send (group & direct) |
|
||||||
| 定时任务 | ✅ 主动推送(每月每用户限 4 条) |
|
| Scheduled Tasks | ✅ Active push (4 per user per month) |
|
||||||
|
|
||||||
|
|
||||||
## 五、注意事项
|
## 5. Notes
|
||||||
|
|
||||||
- **被动消息限制**:QQ 单聊被动消息有效期为 60 分钟,每条消息最多回复 5 次;QQ 群聊被动消息有效期为 5 分钟。
|
- **Passive message limits**: QQ direct message replies are valid for 60 minutes (max 5 replies per message); group chat replies are valid for 5 minutes.
|
||||||
- **主动消息限制**:单聊和群聊每月主动消息上限为 4 条,在使用定时任务功能时需要注意这个限制
|
- **Active message limits**: Both direct and group chats have a monthly limit of 4 active messages. Keep this in mind when using the scheduled tasks feature.
|
||||||
- **事件权限**:默认订阅 `GROUP_AND_C2C_EVENT`(QQ群/单聊)和 `PUBLIC_GUILD_MESSAGES`(频道公域消息),如需其他事件类型请在开放平台申请权限。
|
- **Event permissions**: By default, `GROUP_AND_C2C_EVENT` (QQ group/direct) and `PUBLIC_GUILD_MESSAGES` (guild public messages) are subscribed. Apply for additional permissions on the open platform if needed.
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
---
|
---
|
||||||
title: Slack
|
title: Slack
|
||||||
description: 将 CowAgent 接入 Slack App
|
description: Integrate CowAgent with a Slack App
|
||||||
---
|
---
|
||||||
|
|
||||||
> 通过 Slack App 的 **Socket Mode** 接入 CowAgent,支持私聊(DM)与频道(@机器人 / 线程内回复触发)。Socket Mode 基于长连接,无需公网 IP 与回调地址,开箱即用。
|
> Integrate CowAgent into Slack via a Slack App in **Socket Mode**. Supports direct messages (DM) and channels (triggered by @mention or replying within a thread). Socket Mode uses a persistent WebSocket connection — no public IP or callback URL required, works out of the box.
|
||||||
|
|
||||||
## 一、接入步骤
|
## 1. Setup
|
||||||
|
|
||||||
### 步骤一:创建 Slack App
|
### Step 1: Create a Slack App
|
||||||
|
|
||||||
1. 打开 [Slack API 应用管理页](https://api.slack.com/apps),点击 **Create New App** → **From scratch**。
|
1. Open the [Slack API apps page](https://api.slack.com/apps), click **Create New App** → **From scratch**.
|
||||||
2. 填写 **App Name**(如 `CowAgent`),选择要安装的 **Workspace**,点击创建。
|
2. Enter an **App Name** (e.g. `CowAgent`), pick the **Workspace** to install into, and create it.
|
||||||
|
|
||||||
### 步骤二:开启 Socket Mode 并获取 App Token
|
### Step 2: Enable Socket Mode and get the App Token
|
||||||
|
|
||||||
1. 左侧菜单进入 **Settings → Socket Mode**,打开 **Enable Socket Mode**。
|
1. In the left sidebar go to **Settings → Socket Mode** and turn on **Enable Socket Mode**.
|
||||||
2. 系统会提示生成一个 **App-Level Token**,作用域勾选 `connections:write`,生成后保存这串以 `xapp-` 开头的 Token。
|
2. You will be prompted to generate an **App-Level Token** with the `connections:write` scope. Save this token starting with `xapp-`.
|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
Socket Mode 通过 WebSocket 长连接接收事件,无需在公网暴露回调 URL,适合本地或内网部署。
|
Socket Mode receives events over a WebSocket connection, so you don't need to expose a public callback URL — ideal for local or intranet deployments.
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
### 步骤三:配置 Bot 权限并安装
|
### Step 3: Configure bot scopes and install
|
||||||
|
|
||||||
1. 进入 **Features → OAuth & Permissions**,在 **Bot Token Scopes** 中点击 **Add an OAuth Scope**,逐项添加以下权限:
|
1. Go to **Features → OAuth & Permissions**, click **Add an OAuth Scope** under **Bot Token Scopes**, and add the following scopes one by one:
|
||||||
|
|
||||||
```
|
```
|
||||||
app_mentions:read
|
app_mentions:read
|
||||||
@@ -39,10 +39,10 @@ description: 将 CowAgent 接入 Slack App
|
|||||||
```
|
```
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
`files:read` / `files:write` 用于图片、文件的收发;若仅需文本对话可省略。
|
`files:read` / `files:write` are used for sending/receiving images and files; omit them if you only need text conversations.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
2. 进入 **Features → Event Subscriptions**,打开 **Enable Events**,在 **Subscribe to bot events** 中点击 **Add Bot User Event** 添加以下事件:
|
2. Go to **Features → Event Subscriptions**, turn on **Enable Events**, and under **Subscribe to bot events** click **Add Bot User Event** to add:
|
||||||
|
|
||||||
```
|
```
|
||||||
app_mention
|
app_mention
|
||||||
@@ -51,23 +51,23 @@ description: 将 CowAgent 接入 Slack App
|
|||||||
```
|
```
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
如需在私有频道使用,再添加 `message.groups`。
|
Add `message.groups` if you need to use the bot in private channels.
|
||||||
</Note>
|
</Note>
|
||||||
3. 进入 **Features → App Home**,在 **Show Tabs** 区域勾选 **Messages Tab**,并勾选下方的 **Allow users to send Slash commands and messages from the messages tab**(允许用户从消息标签页发送消息),否则私聊输入框会被关闭、无法给机器人发消息。
|
3. Go to **Features → App Home**, enable **Messages Tab** under **Show Tabs**, and check **Allow users to send Slash commands and messages from the messages tab**. Otherwise the DM input box is disabled and users cannot message the bot.
|
||||||
4. 回到 **OAuth & Permissions**,点击 **Install to Workspace** 完成安装,安装后获取以 `xoxb-` 开头的 **Bot User OAuth Token**。
|
4. Back in **OAuth & Permissions**, click **Install to Workspace**. After installing, copy the **Bot User OAuth Token** starting with `xoxb-`.
|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
若 Slack 客户端仍提示「向此应用发送消息的功能已关闭」,请确认已完成上一步的 App Home 设置,并刷新或重启 Slack 客户端(必要时把 App 从对话列表移除后重新打开)。
|
If the Slack client still shows "Sending messages to this app has been turned off", make sure you completed the App Home step above, then refresh or restart the Slack client (remove the app from your conversations and reopen it if needed).
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
### 步骤四:接入 CowAgent
|
### Step 4: Connect to CowAgent
|
||||||
|
|
||||||
<Tabs>
|
<Tabs>
|
||||||
<Tab title="Web 控制台(推荐)">
|
<Tab title="Web Console (Recommended)">
|
||||||
打开 Web 控制台(本地链接:http://127.0.0.1:9899 ),选择 **通道** 菜单,点击 **接入通道**,选择 **Slack**,分别填入 Bot Token(`xoxb-`)和 App Token(`xapp-`),点击接入即可。
|
Open the Web Console (default `http://127.0.0.1:9899`), go to **Channels**, click **Add Channel**, choose **Slack**, paste the Bot Token (`xoxb-`) and App Token (`xapp-`), and click connect.
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab title="配置文件">
|
<Tab title="Config File">
|
||||||
在 `config.json` 中添加以下配置后启动:
|
Add the following to `config.json` and start Cow:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -78,41 +78,41 @@ description: 将 CowAgent 接入 Slack App
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| 参数 | 说明 | 默认值 |
|
| Key | Description | Default |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `slack_bot_token` | Bot User OAuth Token,形如 `xoxb-...` | - |
|
| `slack_bot_token` | Bot User OAuth Token, like `xoxb-...` | - |
|
||||||
| `slack_app_token` | App-Level Token(开启 Socket Mode 后生成),形如 `xapp-...` | - |
|
| `slack_app_token` | App-Level Token (generated after enabling Socket Mode), like `xapp-...` | - |
|
||||||
| `slack_group_trigger` | 频道触发方式:`mention_or_reply`(@或线程内回复)/ `mention_only`(仅@) / `all`(所有消息) | `mention_or_reply` |
|
| `slack_group_trigger` | Channel trigger: `mention_or_reply` (@ or reply in thread) / `mention_only` (@ only) / `all` (all messages) | `mention_or_reply` |
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
启动 Cow 后,日志中出现以下输出即表示接入成功:
|
The integration is ready when you see logs like:
|
||||||
|
|
||||||
```
|
```
|
||||||
[Slack] Bot logged in as user_id=U0XXXXXXX, team=Txxxxxxxx
|
[Slack] Bot logged in as user_id=U0XXXXXXX, team=Txxxxxxxx
|
||||||
[Slack] ✅ Slack bot ready, listening for events
|
[Slack] ✅ Slack bot ready, listening for events
|
||||||
```
|
```
|
||||||
|
|
||||||
## 二、功能说明
|
## 2. Capabilities
|
||||||
|
|
||||||
| 功能 | 支持情况 |
|
| Feature | Support |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 私聊(DM) | ✅ |
|
| Direct message (DM) | ✅ |
|
||||||
| 频道(@机器人 / 线程内回复) | ✅ |
|
| Channel (@bot / reply in thread) | ✅ |
|
||||||
| 文本消息 | ✅ 收发 |
|
| Text messages | ✅ send / receive |
|
||||||
| 图片消息 | ✅ 收发 |
|
| Image messages | ✅ send / receive |
|
||||||
| 文件消息 | ✅ 收发(PDF / Word / Excel 等) |
|
| File messages | ✅ send / receive (PDF / Word / Excel, etc.) |
|
||||||
| 线程回复 | ✅ 回复发送至触发消息所在线程 |
|
| Thread replies | ✅ replies are posted to the thread of the triggering message |
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
Slack 通过线程(Thread)组织对话。机器人会把回复发送到触发消息所在的线程,频道内更整洁。
|
Slack organizes conversations into threads. The bot posts replies into the thread of the triggering message, keeping channels tidy.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## 三、使用
|
## 3. Usage
|
||||||
|
|
||||||
完成接入后:
|
Once connected:
|
||||||
|
|
||||||
- **私聊(DM)**:在 Slack 左侧 **Apps** 中找到你的 App,直接发消息对话。
|
- **Direct message (DM)**: find your App under **Apps** in the Slack sidebar and message it directly.
|
||||||
- **频道**:把 App 邀请进频道(`/invite @你的App`),使用 `@你的App 你好` 触发对话;后续在同一线程内直接回复即可继续对话。
|
- **Channel**: invite the App into a channel (`/invite @your-app`), then trigger it with `@your-app hello`; continue the conversation by replying within the same thread.
|
||||||
|
|
||||||
发送图片或文件时,可以在附件的输入框中 **添加文字说明**(描述/问题)一并发送,机器人会结合附件回答。也支持先发附件再发问题,两条消息会自动合并提问。
|
When sending an image or file, you can **add a text caption** (description / question) in the attachment input — the bot will answer based on both. Sending an attachment first and then a follow-up question also works; the two messages are merged automatically.
|
||||||
|
|||||||
@@ -1,47 +1,47 @@
|
|||||||
---
|
---
|
||||||
title: Telegram
|
title: Telegram
|
||||||
description: 将 CowAgent 接入 Telegram Bot
|
description: Integrate CowAgent with Telegram via the Bot API
|
||||||
---
|
---
|
||||||
|
|
||||||
> 通过 Telegram Bot API 接入 CowAgent,支持单聊与群聊(@机器人 / 回复机器人触发),使用 Long Polling 模式无需公网 IP,开箱即用。
|
> Integrate CowAgent into Telegram via the official Bot API. Supports private chat and group chat (triggered by @mention or replying to the bot). Uses Long Polling — no public IP required, works out of the box.
|
||||||
|
|
||||||
|
|
||||||
## 一、接入步骤
|
## 1. Setup
|
||||||
|
|
||||||
### 步骤一:通过 BotFather 创建 Bot
|
### Step 1: Create a Bot via BotFather
|
||||||
|
|
||||||
1. 在 Telegram 中搜索并打开官方账号 [@BotFather](https://t.me/BotFather)。
|
1. Open the official account [@BotFather](https://t.me/BotFather) in Telegram.
|
||||||
2. 发送 `/newbot` 命令,按提示输入:
|
2. Send `/newbot` and follow the prompts:
|
||||||
- **Bot 名称**(显示名,可中文,例如 `My CowAgent Bot`)
|
- **Bot name** (display name, e.g. `My CowAgent Bot`)
|
||||||
- **Bot 用户名**(必须以 `bot` 结尾,例如 `my_cowagent_bot`)
|
- **Bot username** (must end with `bot`, e.g. `my_cowagent_bot`)
|
||||||
3. 创建成功后,BotFather 会返回一段 **HTTP API Token**(形如 `123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ`),妥善保存。
|
3. Once created, BotFather returns an **HTTP API Token** (e.g. `123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ`). Keep it safe.
|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
这个 Token 等同于 Bot 的密码,请勿泄露。如果意外泄漏可向 `@BotFather` 发送 `/revoke` 重置。
|
The token is the password of your bot — never share it. If it leaks, send `/revoke` to `@BotFather` to reset it.
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
### 步骤二:(群聊使用)关闭 Privacy Mode
|
### Step 2: (Group chat only) Disable Privacy Mode
|
||||||
|
|
||||||
仅使用单聊可跳过此步。Telegram Bot 默认开启 **Privacy Mode**,群聊中只能收到带 `@bot` 的命令(如 `/start@your_bot`)以及对 bot 消息的 reply;**普通的 `@bot 你好` 文字消息收不到**,会导致群聊无响应。
|
Skip this step if you only use private chat. Telegram bots run in **Privacy Mode** by default — in groups they can only see commands suffixed with `@bot` (e.g. `/start@your_bot`) and replies to bot messages; **plain `@bot hello` text messages are not delivered**, so the bot will appear unresponsive in groups.
|
||||||
|
|
||||||
向 `@BotFather` 发送:
|
Send the following to `@BotFather`:
|
||||||
|
|
||||||
1. `/setprivacy`
|
1. `/setprivacy`
|
||||||
2. 选择刚才创建的 bot
|
2. Pick the bot you just created
|
||||||
3. 选择 `Disable`
|
3. Choose `Disable`
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
若设置后群聊仍无响应,可尝试把 Bot 从群里移除并重新拉入。
|
If the bot is still silent in groups after this, try removing it from the group and adding it back.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
### 步骤三:接入 CowAgent
|
### Step 3: Connect to CowAgent
|
||||||
|
|
||||||
<Tabs>
|
<Tabs>
|
||||||
<Tab title="Web 控制台(推荐)">
|
<Tab title="Web Console (Recommended)">
|
||||||
打开 Web 控制台(本地链接:http://127.0.0.1:9899 ),选择 **通道** 菜单,点击 **接入通道**,选择 **Telegram**,填入 Bot Token,点击接入即可。
|
Open the Web Console (default `http://127.0.0.1:9899`), go to **Channels**, click **Add Channel**, choose **Telegram**, paste the Bot Token, and click connect.
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab title="配置文件">
|
<Tab title="Config File">
|
||||||
在 `config.json` 中添加以下配置后启动:
|
Add the following to `config.json` and start Cow:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -51,16 +51,15 @@ description: 将 CowAgent 接入 Telegram Bot
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| 参数 | 说明 | 默认值 |
|
| Key | Description | Default |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `telegram_token` | BotFather 返回的 HTTP API Token | - |
|
| `telegram_token` | HTTP API Token returned by BotFather | - |
|
||||||
| `telegram_group_trigger` | 群聊触发方式:`mention_or_reply`(@或回复机器人)/ `mention_only`(仅@) / `all`(所有消息) | `mention_or_reply` |
|
| `telegram_group_trigger` | Group trigger: `mention_or_reply` (@ or reply) / `mention_only` (@ only) / `all` (all messages) | `mention_or_reply` |
|
||||||
| `telegram_register_commands` | 启动时是否自动向 BotFather 注册命令菜单 | `true` |
|
| `telegram_register_commands` | Whether to register the command menu with BotFather on startup | `true` |
|
||||||
| `telegram_proxy` | (可选)代理地址,如 `http://127.0.0.1:7890`、`socks5://127.0.0.1:1080`;运行环境无法直连 `api.telegram.org` 时配置,留空则使用环境变量 `HTTPS_PROXY` | `""` |
|
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
启动 Cow 后,日志中出现以下输出即表示接入成功:
|
The integration is ready when you see logs like:
|
||||||
|
|
||||||
```
|
```
|
||||||
[Telegram] Bot logged in as @my_cowagent_bot (id=123456789)
|
[Telegram] Bot logged in as @my_cowagent_bot (id=123456789)
|
||||||
@@ -68,45 +67,45 @@ description: 将 CowAgent 接入 Telegram Bot
|
|||||||
[Telegram] ✅ Telegram bot ready, polling for updates
|
[Telegram] ✅ Telegram bot ready, polling for updates
|
||||||
```
|
```
|
||||||
|
|
||||||
## 二、功能说明
|
## 2. Capabilities
|
||||||
|
|
||||||
| 功能 | 支持情况 |
|
| Feature | Support |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 单聊 | ✅ |
|
| Private chat | ✅ |
|
||||||
| 群聊(@机器人 / 回复机器人) | ✅ |
|
| Group chat (@bot / reply to bot) | ✅ |
|
||||||
| 文本消息 | ✅ 收发 |
|
| Text messages | ✅ send / receive |
|
||||||
| 图片消息 | ✅ 收发 |
|
| Image messages | ✅ send / receive |
|
||||||
| 语音消息 | ✅ 收发(接收 OGG/Opus,发送 OGG/Opus) |
|
| Voice messages | ✅ send / receive (OGG/Opus) |
|
||||||
| 视频消息 | ✅ 收发 |
|
| Video messages | ✅ send / receive |
|
||||||
| 文件消息 | ✅ 收发(PDF / Word / Excel 等) |
|
| File messages | ✅ send / receive (PDF / Word / Excel, etc.) |
|
||||||
| 命令菜单 | ✅ 与 Web 控制台 slash 命令一致 |
|
| Command menu | ✅ aligned with Web Console slash commands |
|
||||||
|
|
||||||
### 命令菜单
|
### Command Menu
|
||||||
|
|
||||||
启动时会自动向 BotFather 注册命令菜单,用户在 Telegram 输入框输入 `/` 会出现下拉提示:
|
On startup, the channel registers a command menu with BotFather. Typing `/` in Telegram shows a dropdown:
|
||||||
|
|
||||||
| 命令 | 说明 |
|
| Command | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `/help` | 显示命令帮助 |
|
| `/help` | Show command help |
|
||||||
| `/status` | 查看运行状态 |
|
| `/status` | View runtime status |
|
||||||
| `/context` | 查看对话上下文(`/context clear` 清除) |
|
| `/context` | View conversation context (`/context clear` to clear) |
|
||||||
| `/skill` | 技能管理(`/skill list`、`/skill install` 等) |
|
| `/skill` | Skill management (`/skill list`, `/skill install`, ...) |
|
||||||
| `/memory` | 记忆管理(`/memory dream`) |
|
| `/memory` | Memory management (`/memory dream`) |
|
||||||
| `/knowledge` | 知识库管理(`/knowledge list` / `on` / `off`) |
|
| `/knowledge` | Knowledge base (`/knowledge list` / `on` / `off`) |
|
||||||
| `/config` | 查看当前配置 |
|
| `/config` | View current config |
|
||||||
| `/cancel` | 中止当前正在运行的 Agent 任务 |
|
| `/cancel` | Cancel the running Agent task |
|
||||||
| `/logs` | 查看最近日志 |
|
| `/logs` | View recent logs |
|
||||||
| `/version` | 查看版本 |
|
| `/version` | Show version |
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
Telegram 命令菜单只能展示一级命令,子命令通过空格输入即可,例如 `/skill list`、`/context clear`。
|
Telegram's command menu only displays top-level commands; subcommands are entered with a space, e.g. `/skill list`, `/context clear`.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## 三、使用
|
## 3. Usage
|
||||||
|
|
||||||
完成接入后:
|
Once connected:
|
||||||
|
|
||||||
- **单聊**:在 Telegram 中搜索你创建的 Bot 用户名(如 `@my_cowagent_bot`),点击 `Start` 即可开始对话。
|
- **Private chat**: search for your bot username (e.g. `@my_cowagent_bot`) in Telegram, click `Start` and chat away.
|
||||||
- **群聊**:把 Bot 拉进群,使用 `@bot 你好` 或 **回复 Bot 的某条消息** 触发对话。若群聊无响应,请检查 Privacy Mode 是否已按 [步骤二](#步骤二-群聊使用-关闭-privacy-mode) 关闭。
|
- **Group chat**: add the bot to a group, then trigger it with `@bot hello` or by **replying to one of the bot's messages**. If the bot doesn't respond in groups, double-check Privacy Mode in [Step 2](#step-2-group-chat-only-disable-privacy-mode).
|
||||||
|
|
||||||
发送图片或文件时,可以直接在附件上方的输入框中 **添加 Caption**(描述/问题)一并发送,机器人会结合附件回答。也支持先发附件再发问题,两条消息会自动合并提问。
|
When sending an image or file, you can **add a caption** (description / question) directly in the attachment input — the bot will answer based on both. Sending an attachment first and then a follow-up question also works; the two messages are merged automatically.
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
---
|
---
|
||||||
title: Web 控制台
|
title: Web Console
|
||||||
description: 通过 Web 控制台使用 CowAgent
|
description: Use CowAgent through the Web Console
|
||||||
---
|
---
|
||||||
|
|
||||||
Web 控制台是 CowAgent 的默认通道,启动后会自动运行,通过浏览器即可与 Agent 对话,并支持在线管理模型、技能、记忆、通道等配置。
|
The Web Console is CowAgent's default channel. It runs automatically once started, letting you chat with the Agent in a browser and manage models, skills, memory, channels, and other configuration online.
|
||||||
|
|
||||||
## 配置
|
## Configuration
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -17,79 +17,79 @@ Web 控制台是 CowAgent 的默认通道,启动后会自动运行,通过浏
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| 参数 | 说明 | 默认值 |
|
| Parameter | Description | Default |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `channel_type` | 设为 `web` | `web` |
|
| `channel_type` | Set to `web` | `web` |
|
||||||
| `web_host` | Web 服务监听地址,默认监听 `127.0.0.1`(仅本机),如需公网访问请改为 `0.0.0.0` 并设置密码 | `""` |
|
| `web_host` | Web service listen address. Defaults to `127.0.0.1` (local only); set to `0.0.0.0` for public access and configure a password | `""` |
|
||||||
| `web_port` | Web 服务监听端口 | `9899` |
|
| `web_port` | Web service listen port | `9899` |
|
||||||
| `web_password` | 访问密码,留空表示不启用密码保护;监听 `0.0.0.0` 时建议设置 | `""` |
|
| `web_password` | Access password. Leave empty to disable password protection; recommended when listening on `0.0.0.0` | `""` |
|
||||||
| `web_session_expire_days` | 登录会话有效天数 | `30` |
|
| `web_session_expire_days` | Login session validity in days | `30` |
|
||||||
| `web_file_serve_root` | web 端可直接读取/发送的文件根目录,默认仅限用户主目录及 agent 工作空间;设为 `/` 可放开整个文件系统 | `"~"` |
|
| `web_file_serve_root` | Root directory the web console can directly read/send files from. Defaults to the user home dir and agent workspace only; set to `/` to allow the whole filesystem | `"~"` |
|
||||||
| `enable_thinking` | 是否启用深度思考模式 | `false` |
|
| `enable_thinking` | Whether to enable deep thinking mode | `false` |
|
||||||
|
|
||||||
配置密码后,访问控制台时需先输入密码完成登录。登录状态默认保持 30 天,期间重启服务也无需重新登录。密码也支持在控制台的「配置」页面中在线修改。
|
Once a password is configured, you must enter it to log in when accessing the console. The login session is kept for 30 days by default, so restarting the service during that period does not require re-login. The password can also be changed online from the "Configuration" page in the console.
|
||||||
|
|
||||||
## 访问地址
|
## Access URL
|
||||||
|
|
||||||
启动项目后访问:
|
After starting the project, visit:
|
||||||
|
|
||||||
- 本地运行:`http://localhost:9899`
|
- Local: `http://localhost:9899`
|
||||||
- 服务器运行:`http://<server-ip>:9899`
|
- Server: `http://<server-ip>:9899`
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
请确保服务器防火墙和安全组已放行对应端口。
|
Ensure the server firewall and security group allow the corresponding port.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## 功能介绍
|
## Features
|
||||||
|
|
||||||
### 对话界面
|
### Chat Interface
|
||||||
|
|
||||||
支持流式输出,可实时展示 Agent 的思考过程(Reasoning)和工具调用过程(Tool Calls),更直观地观察 Agent 的决策过程。深度思考功能可通过配置或控制台的「Agent 配置」开关控制。
|
Supports streaming output with real-time display of the Agent's reasoning process and tool calls, providing intuitive observation of the Agent's decision-making. Deep thinking can be toggled via configuration or the "Agent Configuration" switch in the console.
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227180120.png" />
|
<img width="850" src="https://cdn.link-ai.tech/doc/20260227180120.png" />
|
||||||
|
|
||||||
#### 多会话管理
|
#### Multi-Session Management
|
||||||
|
|
||||||
对话界面支持多会话(Session)管理,所有会话记录持久化存储在数据库中:
|
The chat interface supports multi-session management. All session records are persistently stored in the database:
|
||||||
|
|
||||||
- **会话列表**:点击左侧历史会话图标可展开/收起会话列表面板,支持滚动加载全部历史会话
|
- **Session List**: Click the history icon on the left to expand/collapse the session list panel, with scroll-to-load support for all historical sessions
|
||||||
- **AI 生成标题**:新会话在首轮对话完成后,自动调用模型生成简短的会话摘要标题
|
- **AI-Generated Titles**: After the first exchange in a new session, the model is automatically called to generate a short summary title
|
||||||
- **新建会话**:点击会话列表顶部的「新对话」按钮或输入区的 `+` 按钮创建新会话
|
- **New Session**: Click the "New Chat" button at the top of the session list or the `+` button in the input area to create a new session
|
||||||
- **删除会话**:点击会话项的删除按钮,确认后永久删除该会话及其所有消息
|
- **Delete Session**: Click the delete button on a session item and confirm to permanently delete the session and all its messages
|
||||||
- **清除上下文**:点击输入区的清除按钮,在当前会话中插入一条分隔线,分隔线以上的消息仍然展示但不再作为模型的上下文输入
|
- **Clear Context**: Click the clear button in the input area to insert a divider in the current session. Messages above the divider are still displayed but no longer included as context for the model
|
||||||
|
|
||||||
### 模型管理
|
### Model Management
|
||||||
|
|
||||||
支持在线管理不同模型厂商的文本、图像、语音、向量模型配置,无需手动编辑配置文件:
|
Manage text, image, voice, and embedding model configurations for different providers online — no need to edit config files manually:
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260521212949.png" />
|
<img width="850" src="https://cdn.link-ai.tech/doc/20260521212949.png" />
|
||||||
|
|
||||||
### 技能管理
|
### Skill Management
|
||||||
|
|
||||||
支持在线查看和管理 Agent 技能(Skills):
|
View and manage Agent skills (Skills) online:
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173403.png" />
|
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173403.png" />
|
||||||
|
|
||||||
### 记忆管理
|
### Memory Management
|
||||||
|
|
||||||
支持在线查看和管理 Agent 记忆:
|
View and manage Agent memory online:
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173349.png" />
|
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173349.png" />
|
||||||
|
|
||||||
### 通道管理
|
### Channel Management
|
||||||
|
|
||||||
支持在线管理接入通道,支持实时连接/断开操作:
|
Manage connected channels online with real-time connect/disconnect operations:
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173331.png" />
|
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173331.png" />
|
||||||
|
|
||||||
### 定时任务
|
### Scheduled Tasks
|
||||||
|
|
||||||
支持在线查看和管理定时任务,包括一次性任务、固定间隔、Cron 表达式等多种调度方式的可视化管理:
|
View and manage scheduled tasks online, including one-time tasks, fixed intervals, and Cron expressions:
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173704.png" />
|
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173704.png" />
|
||||||
|
|
||||||
### 日志
|
### Logs
|
||||||
|
|
||||||
支持在线实时查看 Agent 运行日志,便于监控运行状态和排查问题:
|
View Agent runtime logs in real time for monitoring and troubleshooting:
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173514.png" />
|
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173514.png" />
|
||||||
|
|||||||
@@ -1,60 +1,60 @@
|
|||||||
---
|
---
|
||||||
title: 微信客服
|
title: WeCom Customer Service
|
||||||
description: 将 CowAgent 接入微信客服(WeCom Customer Service)
|
description: Integrate CowAgent into WeCom Customer Service (微信客服)
|
||||||
---
|
---
|
||||||
|
|
||||||
通过把企业微信自建应用绑定到「微信客服」账号,CowAgent 可以接管来自外部微信用户的客服咨询,并可在小程序、公众号、视频号及视频号小店等场景中通过链接或二维码触达微信用户。
|
By binding a WeCom custom enterprise app to a WeCom Customer Service (微信客服) account, CowAgent can take over inbound inquiries from external WeChat users and serve them through links or QR codes embedded in WeChat Mini Programs, Official Accounts, Video Channels, and Video Channel stores.
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
微信客服只能使用 Docker 部署或服务器 Python 部署,需要公网可达的回调地址,不支持本地运行模式。
|
WeCom Customer Service only supports Docker deployment or server Python deployment. A publicly reachable callback URL is required; local run mode is not supported.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## 一、准备
|
## 1. Prerequisites
|
||||||
|
|
||||||
需要的资源:
|
Required resources:
|
||||||
|
|
||||||
1. 一台服务器(有公网 IP)
|
1. A server with a public IP
|
||||||
2. 注册并已认证的企业微信
|
2. A registered and verified WeCom account
|
||||||
3. 已开通「微信客服」能力
|
3. WeCom Customer Service capability enabled
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
建议**单独再创建一个企微自建应用**用于微信客服,不要复用已有的 `wechatcom_app` 应用,否则两个通道会争抢同一个回调地址。
|
It is recommended to create a **dedicated** WeCom custom app for Customer Service rather than reusing the existing `wechatcom_app` one — otherwise the two channels will compete for the same callback URL.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## 二、创建企业微信自建应用
|
## 2. Create a WeCom Custom App
|
||||||
|
|
||||||
1. 在 [企业微信管理后台](https://work.weixin.qq.com/wework_admin/frame#apps),点击 **应用管理 → 创建应用**:
|
1. In the [WeCom Admin Console](https://work.weixin.qq.com/wework_admin/frame#apps), go to **Application Management → Create Application**:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103156.png" width="480"/>
|
<img src="https://cdn.link-ai.tech/doc/20260228103156.png" width="480"/>
|
||||||
|
|
||||||
2. 点击 **我的企业**,在最下方获取 **企业ID**(后续填写到 `wechat_kf_corp_id`):
|
2. Click **My Enterprise** and find the **Corp ID** at the bottom of the page (it goes into `wechat_kf_corp_id`):
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/wechatcom-hosting-companyid.png" width="600"/>
|
<img src="https://cdn.link-ai.tech/doc/wechatcom-hosting-companyid.png" width="600"/>
|
||||||
|
|
||||||
3. 进入上一步创建的应用,点击 Secret 旁的「**查看**」,Secret 会推送到管理员手机端的企业微信里查看:
|
3. Open the app you just created and click **"View"** next to Secret. The Secret will be pushed to the admin's phone via the WeCom app, where it can be viewed:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/wechatcom-hosting-agent-secret.png" width="600"/>
|
<img src="https://cdn.link-ai.tech/doc/wechatcom-hosting-agent-secret.png" width="600"/>
|
||||||
|
|
||||||
4. 进入应用 **接收消息 → 设置API接收**,点击右侧「**随机获取**」生成 **Token** 和 **EncodingAESKey** 并保存:
|
4. Open the app's **Receive Messages → Set API Reception** page, click **"Random Generate"** to generate the **Token** and **EncodingAESKey**, and save them:
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/wechatcom-hosting-token-aeskey.jpg" width="600"/>
|
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/wechatcom-hosting-token-aeskey.jpg" width="600"/>
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
此时保存 API 接收配置会失败,因为程序还未启动,等项目运行后再回来保存。
|
Saving the API reception configuration will fail at this point because the program has not started yet. Come back to save it after the project is running.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## 三、配置和运行
|
## 3. Configuration and Run
|
||||||
|
|
||||||
填入上一步收集到的 4 个字段(Corp ID / Secret / Token / EncodingAESKey):
|
Fill in the 4 fields collected from the previous step (Corp ID / Secret / Token / EncodingAESKey):
|
||||||
|
|
||||||
<Tabs>
|
<Tabs>
|
||||||
<Tab title="Web 控制台">
|
<Tab title="Web Console">
|
||||||
启动 Cow 项目后打开 Web 控制台,选择 **通道** 菜单,点击 **接入通道**,选择 **微信客服**,依次填入 Corp ID / Secret / Token / AES Key(端口默认 9888,可改),点击接入即可。
|
Start the Cow project and open the Web Console. Go to the **Channels** menu, click **Connect**, choose **WeCom Customer Service**, fill in Corp ID / Secret / Token / AES Key (port defaults to 9888, configurable), and click Connect.
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/cow-weixinkefu-web-control.png" width="800"/>
|
<img src="https://cdn.link-ai.tech/doc/cow-weixinkefu-web-control.png" width="800"/>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab title="配置文件">
|
<Tab title="Config File">
|
||||||
在 `config.json` 中添加以下配置(各参数与企业微信后台的对应关系见上方截图):
|
Add the following configuration to `config.json` (each parameter maps to a field shown in the screenshots above):
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -67,34 +67,34 @@ description: 将 CowAgent 接入微信客服(WeCom Customer Service)
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| 参数 | 说明 |
|
| Parameter | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `wechat_kf_corp_id` | 企业 ID |
|
| `wechat_kf_corp_id` | Corp ID |
|
||||||
| `wechat_kf_secret` | 绑定到微信客服的那个企微自建应用的 Secret |
|
| `wechat_kf_secret` | Secret of the WeCom custom app bound to Customer Service |
|
||||||
| `wechat_kf_token` | API 接收配置中的 Token |
|
| `wechat_kf_token` | Token from the API reception config |
|
||||||
| `wechat_kf_aes_key` | API 接收配置中的 EncodingAESKey |
|
| `wechat_kf_aes_key` | EncodingAESKey from the API reception config |
|
||||||
| `wechat_kf_port` | 监听端口,默认 9888 |
|
| `wechat_kf_port` | Listening port, default 9888 |
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
接入完成后启动程序(Web 控制台方式会自动重启),日志中出现 `Listening on http://0.0.0.0:9888/wxkf/` 表示运行成功,需要将该端口对外开放(如在云服务器安全组中放行)。
|
After connecting, start the program (the Web Console method restarts the channel automatically). When the log shows `Listening on http://0.0.0.0:9888/wxkf/`, the program is running successfully. You need to open this port externally (e.g., allow it in the cloud server security group).
|
||||||
|
|
||||||
接着回到企业微信「接收消息 → 设置API接收」,将回调 URL 填为 `http://<your-host>:9888/wxkf/`,点击保存。保存成功后还需将服务器 IP 添加到 **企业可信IP** 中,否则无法收发消息:
|
Then go back to **Receive Messages → Set API Reception** in the WeCom console and set the callback URL to `http://<your-host>:9888/wxkf/`, then click Save. After saving successfully, you also need to add the server IP to **Enterprise Trusted IPs**, otherwise messages cannot be sent or received:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/wechat-com_config.png" width="600"/>
|
<img src="https://cdn.link-ai.tech/doc/wechat-com_config.png" width="600"/>
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103224.png" width="520"/>
|
<img src="https://cdn.link-ai.tech/doc/20260228103224.png" width="520"/>
|
||||||
|
|
||||||
<Warning>
|
<Warning>
|
||||||
如遇到 URL 配置回调不通过或配置失败:
|
If URL verification fails or the configuration is unsuccessful:
|
||||||
1. 确保服务器防火墙关闭且安全组放行监听端口(默认 9888)
|
1. Ensure the server firewall is disabled and the security group allows the listening port (default 9888)
|
||||||
2. 仔细检查 Token、Secret、EncodingAESKey 等参数配置是否一致,URL 格式是否正确
|
2. Carefully check that Token, Secret, EncodingAESKey and other parameters are consistent, and the URL format is correct
|
||||||
3. 认证企业微信需要配置与主体一致的备案域名
|
3. Verified WeCom accounts must use a filed domain matching the entity
|
||||||
</Warning>
|
</Warning>
|
||||||
|
|
||||||
## 四、绑定微信客服账号
|
## 4. Bind a WeCom Customer Service Account
|
||||||
|
|
||||||
进入企业微信管理后台 **微信客服** 页面,创建客服账号并与上一步的企微自建应用绑定:
|
In the WeCom Admin Console, go to **WeCom Customer Service**, create a customer service account, and bind it to the custom app you created above:
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/wxcustomer-hosting-step1.jpg" width="600"/>
|
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/wxcustomer-hosting-step1.jpg" width="600"/>
|
||||||
|
|
||||||
@@ -102,28 +102,28 @@ description: 将 CowAgent 接入微信客服(WeCom Customer Service)
|
|||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/wxcustomer-hosting-step3.jpg" width="600"/>
|
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/wxcustomer-hosting-step3.jpg" width="600"/>
|
||||||
|
|
||||||
绑定完成后,进入 **微信客服 → 微信客服账号详情**,在「**接入链接**」一栏:
|
After binding, go to **WeCom Customer Service → Account Details**, and under **"Access Link"**:
|
||||||
|
|
||||||
- 点击「**复制链接**」可获得形如 `https://work.weixin.qq.com/kfid/kfcd83e5896b9ba07be` 的访问链接
|
- Click **"Copy Link"** to get an access link like `https://work.weixin.qq.com/kfid/kfcd83e5896b9ba07be`
|
||||||
- 点击「**生成二维码**」可获得对应的二维码
|
- Click **"Generate QR Code"** to get the corresponding QR code
|
||||||
|
|
||||||
把链接或二维码推给微信客户使用即可:
|
Distribute the link or QR code to your WeChat customers:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/wechat-customer-service_use.png" width="600"/>
|
<img src="https://cdn.link-ai.tech/doc/wechat-customer-service_use.png" width="600"/>
|
||||||
|
|
||||||
## 五、使用
|
## 5. Usage
|
||||||
|
|
||||||
微信用户通过链接或二维码进入客服对话后,即可与 AI 进行多轮对话,支持文本、图片、语音等消息:
|
After WeChat users enter the customer service conversation via the link or QR code, they can chat with the AI across multiple turns, with support for text, image, and voice messages:
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/wxcustomer-hosting-chat-demo.jpg" width="900"/>
|
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/wxcustomer-hosting-chat-demo.jpg" width="900"/>
|
||||||
|
|
||||||
除此之外,基于微信生态官方能力,还可将微信客服应用在公众号、小程序、视频号及视频号小店等场景,详情可查看企业微信管理后台 [微信客服 → 接入场景](https://work.weixin.qq.com/wework_admin/frame#/app/servicer) 的相关说明:
|
Beyond that, leveraging the official WeChat ecosystem, WeCom Customer Service can also be embedded into Official Accounts, Mini Programs, Video Channels and more. See the **WeCom Customer Service → Access Scenarios** section in the [WeCom Admin Console](https://work.weixin.qq.com/wework_admin/frame#/app/servicer) for details:
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/wxcustomer-hosting-interface-demo.png" width="800"/>
|
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/wxcustomer-hosting-interface-demo.png" width="800"/>
|
||||||
|
|
||||||
## 常见问题
|
## FAQ
|
||||||
|
|
||||||
需要确保已安装以下依赖:
|
Make sure the following dependencies are installed:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install websocket-client pycryptodome
|
pip install websocket-client pycryptodome
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
---
|
---
|
||||||
title: 微信公众号
|
title: WeChat Official Account
|
||||||
description: 将 CowAgent 接入微信公众号
|
description: Integrate CowAgent with WeChat Official Accounts
|
||||||
---
|
---
|
||||||
|
|
||||||
CowAgent 支持接入个人订阅号和企业服务号两种公众号类型。
|
CowAgent supports both personal subscription accounts and enterprise service accounts.
|
||||||
|
|
||||||
| 类型 | 要求 | 特点 |
|
| Type | Requirements | Features |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| **个人订阅号** | 个人可申请 | 收到消息时会回复一条提示,回复生成后需用户主动发消息获取 |
|
| **Personal Subscription** | Available to individuals | Sends a placeholder reply first; users must send a message to retrieve the full response |
|
||||||
| **企业服务号** | 企业申请,需通过微信认证开通客服接口 | 回复生成后可主动推送给用户 |
|
| **Enterprise Service** | Enterprise with verified customer service API | Can proactively push replies to users |
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
公众号仅支持服务器和 Docker 部署,不支持本地运行。需额外安装扩展依赖:`pip3 install -r requirements-optional.txt`
|
Official Accounts only support server and Docker deployment, not local run mode. Install extended dependencies: `pip3 install -r requirements-optional.txt`
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## 一、个人订阅号
|
## 1. Personal Subscription Account
|
||||||
|
|
||||||
在 `config.json` 中添加以下配置:
|
Add the following configuration to `config.json`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -30,34 +30,34 @@ CowAgent 支持接入个人订阅号和企业服务号两种公众号类型。
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 配置步骤
|
### Setup Steps
|
||||||
|
|
||||||
这些配置需要和 [微信公众号后台](https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev) 中的保持一致,进入页面后,在左侧菜单选择 **设置与开发 → 基本配置 → 服务器配置**,按下图进行配置:
|
These configurations must be consistent with the [WeChat Official Account Platform](https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev). Navigate to **Settings & Development → Basic Configuration → Server Configuration** and configure as shown below:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103506.png" width="480"/>
|
<img src="https://cdn.link-ai.tech/doc/20260228103506.png" width="480"/>
|
||||||
|
|
||||||
1. 在公众平台启用开发者密码(对应配置 `wechatmp_app_secret`),并将服务器 IP 填入白名单
|
1. Enable the developer secret on the platform (corresponds to `wechatmp_app_secret`), and add the server IP to the whitelist
|
||||||
2. 按上图填写 `config.json` 中与公众号相关的配置,要与公众号后台的配置一致
|
2. Fill in the `config.json` with the official account parameters matching the platform configuration
|
||||||
3. 启动程序,启动后会监听 80 端口(若无权限监听,则在启动命令前加上 `sudo`;若 80 端口已被占用,则关闭该占用进程)
|
3. Start the program, which listens on port 80 (use `sudo` if you don't have permission; stop any process occupying port 80)
|
||||||
4. 在公众号后台 **启用服务器配置** 并提交,保存成功则表示已成功配置。注意 **"服务器地址(URL)"** 需要配置为 `http://{HOST}/wx` 的格式,其中 `{HOST}` 可以是服务器的 IP 或域名
|
4. **Enable server configuration** on the official account platform and submit. A successful save means the configuration is complete. Note that the **"Server URL"** must be in the format `http://{HOST}/wx`, where `{HOST}` can be the server IP or domain
|
||||||
|
|
||||||
随后关注公众号并发送消息即可看到以下效果:
|
After following the account and sending a message, you should see the following result:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103522.png" width="720"/>
|
<img src="https://cdn.link-ai.tech/doc/20260228103522.png" width="720"/>
|
||||||
|
|
||||||
由于受订阅号限制,回复内容较短的情况下(15s 内),可以立即完成回复,但耗时较长的回复则会先回复一句 "正在思考中",后续需要用户输入任意文字主动获取答案,而服务号则可以通过客服接口解决这一问题。
|
Due to subscription account limitations, short replies (within 15s) can be returned immediately, but longer replies will first send a "Thinking..." placeholder, requiring users to send any text to retrieve the answer. Enterprise service accounts can solve this with the customer service API.
|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
**语音识别**:可利用微信自带的语音识别功能,需要在公众号管理页面的 "设置与开发 → 接口权限" 页面开启 "接收语音识别结果"。
|
**Voice Recognition**: You can use WeChat's built-in voice recognition. Enable "Receive Voice Recognition Results" under "Settings & Development → API Permissions" on the official account management page.
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
## 二、企业服务号
|
## 2. Enterprise Service Account
|
||||||
|
|
||||||
企业服务号与上述个人订阅号的接入过程基本相同,差异如下:
|
The setup process for enterprise service accounts is essentially the same as personal subscription accounts, with the following differences:
|
||||||
|
|
||||||
1. 在公众平台申请企业服务号并完成微信认证,在接口权限中确认已获得 **客服接口** 的权限
|
1. Register an enterprise service account on the platform and complete WeChat certification. Confirm that the **Customer Service API** permission has been granted
|
||||||
2. 在 `config.json` 中设置 `"channel_type": "wechatmp_service"`,其他配置与上述订阅号相同
|
2. Set `"channel_type": "wechatmp_service"` in `config.json`; other configurations remain the same
|
||||||
3. 交互效果上,即使是较长耗时的回复,也可以主动推送给用户,无需用户手动获取
|
3. Even for longer replies, they can be proactively pushed to users without requiring manual retrieval
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,56 +1,56 @@
|
|||||||
---
|
---
|
||||||
title: 企微智能机器人
|
title: WeCom Bot
|
||||||
description: 将 CowAgent 接入企业微信智能机器人(长连接模式)
|
description: Connect CowAgent to WeCom AI Bot (WebSocket long connection)
|
||||||
---
|
---
|
||||||
|
|
||||||
> 通过企业微信智能机器人接入CowAgent,支持企业内部单聊和内部群聊,无需公网 IP,使用 WebSocket 长连接模式,支持Markdown渲染和流式输出。
|
> Connect CowAgent via WeCom AI Bot, supporting both internal direct messages and group chats. No public IP required — uses a WebSocket long connection, with Markdown rendering and streaming output.
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
智能机器人与企业微信自建应用是两种不同的接入方式。智能机器人使用 WebSocket 长连接,无需服务器公网 IP 和域名,配置更简单。
|
WeCom Bot and WeCom App are two different integration methods. WeCom Bot uses a WebSocket long connection and requires no public IP or domain, making setup much simpler.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## 一、接入方式
|
## 1. Connection methods
|
||||||
|
|
||||||
### 方式一:扫码一键接入(推荐)
|
### Option A: One-click QR scan (recommended)
|
||||||
|
|
||||||
无需提前创建机器人,启动 Cow 项目后打开 Web 控制台(本地链接:http://127.0.0.1:9899/),选择 **通道** 菜单,点击**接入通道**,选择**企微智能机器人**,切换到「扫码接入」模式,使用**企业微信**扫码即可自动完成机器人创建和接入。
|
No need to create the bot ahead of time. Start CowAgent and open the Web console (local URL: http://127.0.0.1:9899/), go to the **Channels** tab, click **Connect Channel**, choose **WeCom Bot**, switch to **QR scan** mode, and scan the QR code with **WeCom** — bot creation and connection complete automatically.
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260401121213.png" width="800"/>
|
<img src="https://cdn.link-ai.tech/doc/20260401121213.png" width="800"/>
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
扫码成功后,可在企业微信工作台 - **智能机器人**页面对机器人进行进一步配置,包括修改名称、头像、可见范围等。
|
After a successful scan, you can further configure the bot (name, avatar, visibility scope, etc.) in **WeCom Workbench → AI Bot**.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
### 方式二:手动创建接入
|
### Option B: Manual creation
|
||||||
|
|
||||||
需要先在企业微信中创建智能机器人并获取 Bot ID 和 Secret,再通过 Web 控制台或配置文件接入。
|
Create the AI Bot in WeCom and obtain the Bot ID and Secret, then connect via the Web console or config file.
|
||||||
|
|
||||||
**步骤一:创建智能机器人**
|
**Step 1: Create the AI Bot**
|
||||||
|
|
||||||
1. 打开企业微信客户端,进入工作台,点击**智能机器人**:
|
1. Open the WeCom client, go to **Workbench**, and click **AI Bot**:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260316180959.png" width="800"/>
|
<img src="https://cdn.link-ai.tech/doc/20260316180959.png" width="800"/>
|
||||||
|
|
||||||
2. 点击创建机器人 - 手动创建:
|
2. Click **Create Bot → Manual Creation**:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260316181118.png" width="800"/>
|
<img src="https://cdn.link-ai.tech/doc/20260316181118.png" width="800"/>
|
||||||
|
|
||||||
3. 右侧窗口拖到最下方,选择**API模式创建**:
|
3. Scroll to the bottom of the right panel and select **API Mode**:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260316181215.png" width="800"/>
|
<img src="https://cdn.link-ai.tech/doc/20260316181215.png" width="800"/>
|
||||||
|
|
||||||
4. 设置机器人名称、头像、可见范围,并选择**长连接模式**,记录下 **Bot ID** 和 **Secret** 信息后点击保存。
|
4. Set the bot name, avatar, and visibility scope. Choose **Long Connection** mode, save the **Bot ID** and **Secret**, then click Save.
|
||||||
|
|
||||||
**步骤二:接入 CowAgent**
|
**Step 2: Connect to CowAgent**
|
||||||
|
|
||||||
<Tabs>
|
<Tabs>
|
||||||
<Tab title="Web 控制台">
|
<Tab title="Web Console">
|
||||||
打开 Web 控制台,选择**通道**菜单,点击**接入通道**,选择**企微智能机器人**,切换到「手动填写」模式,输入 Bot ID 和 Secret,点击接入即可。
|
Open the Web console, go to the **Channels** tab, click **Connect Channel**, choose **WeCom Bot**, switch to **Manual** mode, enter the Bot ID and Secret, and click Connect.
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260316181711.png" width="800"/>
|
<img src="https://cdn.link-ai.tech/doc/20260316181711.png" width="800"/>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab title="配置文件">
|
<Tab title="Config File">
|
||||||
在 `config.json` 中添加以下配置后启动程序:
|
Add the following to `config.json`, then start CowAgent:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -60,31 +60,31 @@ description: 将 CowAgent 接入企业微信智能机器人(长连接模式)
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| 参数 | 说明 |
|
| Parameter | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `wecom_bot_id` | 智能机器人的 BotID |
|
| `wecom_bot_id` | Bot ID of the AI Bot |
|
||||||
| `wecom_bot_secret` | 智能机器人的 Secret |
|
| `wecom_bot_secret` | Secret of the AI Bot |
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
日志显示 `[WecomBot] Subscribe success` 即表示连接成功。
|
The log line `[WecomBot] Subscribe success` confirms the connection is established.
|
||||||
|
|
||||||
## 二、功能说明
|
## 2. Supported features
|
||||||
|
|
||||||
| 功能 | 支持情况 |
|
| Feature | Status |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 单聊 | ✅ |
|
| Direct chat | ✅ |
|
||||||
| 群聊(@机器人) | ✅ |
|
| Group chat (@bot) | ✅ |
|
||||||
| 文本消息 | ✅ 收发 |
|
| Text messages | ✅ Send / Receive |
|
||||||
| 图片消息 | ✅ 收发 |
|
| Image messages | ✅ Send / Receive |
|
||||||
| 文件消息 | ✅ 收发 |
|
| File messages | ✅ Send / Receive |
|
||||||
| 流式回复 | ✅ |
|
| Streaming replies | ✅ |
|
||||||
| 定时任务主动推送 | ✅ |
|
| Scheduled push messages | ✅ |
|
||||||
|
|
||||||
## 三、使用
|
## 3. Usage
|
||||||
|
|
||||||
在企业微信中搜索创建的机器人名称,即可开始单聊对话。
|
Search for the bot's name inside WeCom to start a direct chat.
|
||||||
|
|
||||||
如需在企微内部群聊中使用,将机器人添加到群中,@机器人发送消息即可。
|
To use the bot in an internal group chat, add it to the group and @-mention it.
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260316182902.png" width="800"/>
|
<img src="https://cdn.link-ai.tech/doc/20260316182902.png" width="800"/>
|
||||||
|
|||||||
@@ -1,48 +1,48 @@
|
|||||||
---
|
---
|
||||||
title: 企微自建应用
|
title: WeCom
|
||||||
description: 将 CowAgent 接入企业微信自建应用
|
description: Integrate CowAgent into WeCom enterprise app
|
||||||
---
|
---
|
||||||
|
|
||||||
通过企业微信自建应用接入 CowAgent,支持企业内部人员单聊使用。
|
Integrate CowAgent into WeCom through a custom enterprise app, supporting one-on-one chat for internal employees.
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
企业微信只能使用 Docker 部署或服务器 Python 部署,不支持本地运行模式。
|
WeCom only supports Docker deployment or server Python deployment. Local run mode is not supported.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## 一、准备
|
## 1. Prerequisites
|
||||||
|
|
||||||
需要的资源:
|
Required resources:
|
||||||
|
|
||||||
1. 一台服务器(有公网 IP)
|
1. A server with public IP (overseas server, or domestic server with a proxy for international API access)
|
||||||
2. 注册一个企业微信(个人也可注册,但无法认证)
|
2. A registered WeCom account (individual registration is possible but cannot be certified)
|
||||||
3. 认证企业微信还需要对应主体备案的域名
|
3. Certified WeCom accounts additionally require a domain filed under the corresponding entity
|
||||||
|
|
||||||
## 二、创建企业微信应用
|
## 2. Create WeCom App
|
||||||
|
|
||||||
1. 在 [企业微信管理后台](https://work.weixin.qq.com/wework_admin/frame#profile) 点击 **我的企业**,在最下方获取 **企业ID**(后续填写到 `wechatcom_corp_id` 字段中)。
|
1. In the [WeCom Admin Console](https://work.weixin.qq.com/wework_admin/frame#profile), click **My Enterprise** and find the **Corp ID** at the bottom of the page. Save this ID for the `wechatcom_corp_id` configuration field.
|
||||||
|
|
||||||
2. 切换到 **应用管理**,点击创建应用:
|
2. Switch to **Application Management** and click Create Application:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103156.png" width="480"/>
|
<img src="https://cdn.link-ai.tech/doc/20260228103156.png" width="480"/>
|
||||||
|
|
||||||
3. 进入应用创建页面,记录 `AgentId` 和 `Secret`:
|
3. On the application creation page, record the `AgentId` and `Secret`:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103218.png" width="580"/>
|
<img src="https://cdn.link-ai.tech/doc/20260228103218.png" width="580"/>
|
||||||
|
|
||||||
4. 点击 **设置API接收**,配置应用接口:
|
4. Click **Set API Reception** to configure the application interface:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103211.png" width="520"/>
|
<img src="https://cdn.link-ai.tech/doc/20260228103211.png" width="520"/>
|
||||||
|
|
||||||
- URL 格式为 `http://ip:port/wxcomapp`(认证企业需使用备案域名)
|
- URL format: `http://ip:port/wxcomapp` (certified enterprises must use a filed domain)
|
||||||
- 随机获取 `Token` 和 `EncodingAESKey` 并保存
|
- Generate random `Token` and `EncodingAESKey` and save them for the configuration file
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
此时保存 API 接收配置会失败,因为程序还未启动,等项目运行后再回来保存。
|
The API reception configuration cannot be saved at this point because the program hasn't started yet. Come back to save it after the project is running.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## 三、配置和运行
|
## 3. Configuration and Run
|
||||||
|
|
||||||
在 `config.json` 中添加以下配置(各参数与企业微信后台的对应关系见上方截图):
|
Add the following configuration to `config.json` (the mapping between each parameter and the WeCom console is shown in the screenshots above):
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -57,41 +57,41 @@ description: 将 CowAgent 接入企业微信自建应用
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
| 参数 | 说明 |
|
| Parameter | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `wechatcom_corp_id` | 企业 ID |
|
| `wechatcom_corp_id` | Corp ID |
|
||||||
| `wechatcomapp_token` | API 接收配置中的 Token |
|
| `wechatcomapp_token` | Token from API reception config |
|
||||||
| `wechatcomapp_secret` | 应用的 Secret |
|
| `wechatcomapp_secret` | App Secret |
|
||||||
| `wechatcomapp_agent_id` | 应用的 AgentId |
|
| `wechatcomapp_agent_id` | App AgentId |
|
||||||
| `wechatcomapp_aes_key` | API 接收配置中的 EncodingAESKey |
|
| `wechatcomapp_aes_key` | EncodingAESKey from API reception config |
|
||||||
| `wechatcomapp_port` | 监听端口,默认 9898 |
|
| `wechatcomapp_port` | Listen port, default 9898 |
|
||||||
|
|
||||||
配置完成后启动程序。当后台日志显示 `http://0.0.0.0:9898/` 时说明程序运行成功,需要将该端口对外开放(如在云服务器安全组中放行)。
|
After configuration, start the program. When the log shows `http://0.0.0.0:9898/`, the program is running successfully. You need to open this port externally (e.g., allow it in the cloud server security group).
|
||||||
|
|
||||||
程序启动后,回到企业微信后台保存 **消息服务器配置**,保存成功后还需将服务器 IP 添加到 **企业可信IP** 中,否则无法收发消息:
|
After the program starts, return to the WeCom Admin Console to save the **Message Server Configuration**. After saving successfully, you also need to add the server IP to **Enterprise Trusted IPs**, otherwise messages cannot be sent or received:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103224.png" width="520"/>
|
<img src="https://cdn.link-ai.tech/doc/20260228103224.png" width="520"/>
|
||||||
|
|
||||||
<Warning>
|
<Warning>
|
||||||
如遇到 URL 配置回调不通过或配置失败:
|
If the URL configuration callback fails or the configuration is unsuccessful:
|
||||||
1. 确保服务器防火墙关闭且安全组放行监听端口
|
1. Ensure the server firewall is disabled and the security group allows the listening port
|
||||||
2. 仔细检查 Token、Secret Key 等参数配置是否一致,URL 格式是否正确
|
2. Carefully check that Token, Secret Key and other parameter configurations are consistent, and that the URL format is correct
|
||||||
3. 认证企业微信需要配置与主体一致的备案域名
|
3. Certified WeCom accounts must configure a filed domain matching the entity
|
||||||
</Warning>
|
</Warning>
|
||||||
|
|
||||||
## 四、使用
|
## 4. Usage
|
||||||
|
|
||||||
在企业微信中搜索刚创建的应用名称,即可直接对话:
|
Search for the app name you just created in WeCom to start chatting directly. You can run multiple instances listening on different ports to create multiple WeCom apps:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103228.png" width="720"/>
|
<img src="https://cdn.link-ai.tech/doc/20260228103228.png" width="720"/>
|
||||||
|
|
||||||
如需让外部个人微信用户使用,可在 **我的企业 → 微信插件** 中分享邀请关注二维码,个人微信扫码关注后即可与应用对话:
|
To allow external personal WeChat users to use the app, go to **My Enterprise → WeChat Plugin**, share the invite QR code. After scanning and following, personal WeChat users can join and chat with the app:
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103232.png" width="520"/>
|
<img src="https://cdn.link-ai.tech/doc/20260228103232.png" width="520"/>
|
||||||
|
|
||||||
## 常见问题
|
## FAQ
|
||||||
|
|
||||||
需要确保已安装以下依赖:
|
Make sure the following dependencies are installed:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install websocket-client pycryptodome
|
pip install websocket-client pycryptodome
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
---
|
---
|
||||||
title: 微信
|
title: WeChat
|
||||||
description: 将 CowAgent 接入个人微信(基于官方接口)
|
description: Connect CowAgent to personal WeChat (via the official API)
|
||||||
---
|
---
|
||||||
|
|
||||||
> 接入个人微信,扫码登录即可使用,支持文本、图片、语音、文件、视频等消息的私聊收发。通过微信官方API进行接入,无安全风险,接入后会在会话中新增一个机器人助手,不影响当前账号的使用。
|
> Connect CowAgent to your personal WeChat — scan to log in, no public IP required. Supports text, image, voice, file, and video messages in 1-on-1 chats. Backed by WeChat's official API; safe to use. After connecting, a bot assistant is added to your conversation list without affecting normal account usage.
|
||||||
|
|
||||||
## 一、配置和运行
|
## 1. Setup and run
|
||||||
|
|
||||||
### 方式一:Web 控制台接入
|
### Option A: Web console
|
||||||
|
|
||||||
启动 Cow 项目后打开 Web 控制台 (本地链接为: http://127.0.0.1:9899/ ),选择 **通道** 菜单,点击 **接入通道**,选择 **微信**,点击接入后按照提示扫码登录。
|
Start CowAgent and open the Web console (local URL: http://127.0.0.1:9899/). Go to the **Channels** tab, click **Connect Channel**, select **WeChat**, and follow the prompts to scan in.
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260322195114.png" width="800" />
|
<img src="https://cdn.link-ai.tech/doc/20260322195114.png" width="800" />
|
||||||
|
|
||||||
### 方式二:配置文件接入
|
### Option B: Config file
|
||||||
|
|
||||||
在 `config.json` 中设置 `channel_type` 为 `weixin`:
|
Set `channel_type` to `weixin` in `config.json`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -23,52 +23,49 @@ description: 将 CowAgent 接入个人微信(基于官方接口)
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
启动程序后,终端会显示二维码,使用微信扫码授权即可完成登录。
|
After starting CowAgent, a QR code is displayed in the terminal. Scan it with WeChat to complete login.
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260322195509.png" width="800" />
|
<img src="https://cdn.link-ai.tech/doc/20260322195509.png" width="800" />
|
||||||
|
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
1. 兼容历史配置:`channel_type` 设为 `wx` 同样可以启用微信通道。
|
1. For backward compatibility, setting `channel_type` to `wx` also activates the WeChat channel.
|
||||||
2. 注意微信客户端需要更新至 8.0.69 版本或以上
|
2. The WeChat client must be on version **8.0.69** or higher.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## 二、使用说明
|
## 2. Usage
|
||||||
|
|
||||||
微信扫码并进行授权确认后,即可完成接入并开始对话。接入微信后会在对话中创建出一个机器人助理,不会对已有账号的正常使用有任何影响。
|
Once authorized, the integration completes and you can start chatting. A bot assistant is created in your WeChat conversation list, leaving normal account usage unaffected.
|
||||||
|
|
||||||
> 你可以通过搜索"微信ClawBot"随时找到这个机器人,还可以修改这个机器人的头像、备注等信息,将机器人置顶在消息列表等。
|
> You can find the bot at any time by searching for **"微信ClawBot"**. You may also rename it, change its avatar, pin it to the top of your conversation list, and so on.
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/83ae8251d896219fde4803f4205205be.jpg" width="250" />
|
<img src="https://cdn.link-ai.tech/doc/83ae8251d896219fde4803f4205205be.jpg" width="250" />
|
||||||
|
|
||||||
|
## 3. Login
|
||||||
|
|
||||||
|
### QR code login
|
||||||
|
|
||||||
## 三、登录说明
|
On first startup, a QR code appears in the terminal (valid for around 2 minutes). Scan it with WeChat and confirm on your phone to log in.
|
||||||
|
|
||||||
### 扫码登录
|
- The QR code refreshes automatically when it expires
|
||||||
|
- The `qrcode` dependency is already included in `requirements.txt`, so the QR code renders directly in the terminal after install
|
||||||
|
|
||||||
首次启动时,终端会显示一个二维码(有效期约 2 分钟)。使用微信扫描二维码并在手机上确认后即可完成登录。
|
### Credential persistence
|
||||||
|
|
||||||
- 二维码过期后会自动刷新并重新显示
|
After a successful login, credentials are saved to `~/.weixin_cow_credentials.json`. Subsequent startups reuse the saved credentials with no need to re-scan.
|
||||||
- `requirements.txt` 中已默认包含 `qrcode` 依赖,安装后可在终端直接渲染二维码图案
|
|
||||||
|
|
||||||
### 凭证保存
|
To force a re-login, delete the credentials file and restart.
|
||||||
|
|
||||||
登录成功后,凭证会自动保存至 `~/.weixin_cow_credentials.json`,下次启动时无需重新扫码。
|
### Session expiry
|
||||||
|
|
||||||
如需重新登录,删除该凭证文件后重启程序即可。
|
When the WeChat session expires (errcode `-14`), CowAgent automatically clears old credentials and initiates a new QR login — no manual intervention required.
|
||||||
|
|
||||||
### Session 过期
|
## 4. Supported features
|
||||||
|
|
||||||
当微信 session 过期时(errcode -14),程序会自动清除旧凭证并重新发起扫码登录,无需手动干预。
|
| Feature | Status |
|
||||||
|
|
||||||
## 四、功能说明
|
|
||||||
|
|
||||||
| 功能 | 支持情况 |
|
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 单聊 | ✅ |
|
| Direct messages | ✅ |
|
||||||
| 文本消息 | ✅ 收发 |
|
| Text messages | ✅ Send & Receive |
|
||||||
| 图片消息 | ✅ 收发 |
|
| Image messages | ✅ Send & Receive |
|
||||||
| 文件消息 | ✅ 收发 |
|
| File messages | ✅ Send & Receive |
|
||||||
| 视频消息 | ✅ 收发 |
|
| Video messages | ✅ Send & Receive |
|
||||||
| 语音消息 | ✅ 接收 (自带语音识别) |
|
| Voice messages | ✅ Receive (built-in speech recognition) |
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
---
|
---
|
||||||
title: 常用命令
|
title: General Commands
|
||||||
description: 查看状态、管理配置和上下文等常用命令
|
description: View status, manage config, and control context with commonly used commands
|
||||||
---
|
---
|
||||||
|
|
||||||
以下命令支持在对话中使用 `/` 前缀,也支持在终端中使用 `cow` 前缀(部分命令仅对话可用)。
|
The following commands can be used in chat with the `/` prefix or in the terminal with the `cow` prefix (some are chat-only).
|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
在 Web 控制台中输入 `/` 会自动弹出命令提示,支持键盘上下选择和 Tab 补全。
|
In the Web console, typing `/` brings up an autocomplete menu with keyboard navigation and Tab completion.
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
## help
|
## help
|
||||||
|
|
||||||
显示所有可用命令的帮助信息。
|
Show help information for all available commands.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/help
|
/help
|
||||||
@@ -19,29 +19,15 @@ description: 查看状态、管理配置和上下文等常用命令
|
|||||||
|
|
||||||
## status
|
## status
|
||||||
|
|
||||||
查看当前会话和服务的运行状态,包括进程信息、模型配置、会话消息数量和已加载技能数量。
|
View current session and service status, including process info, model configuration, message count, and loaded skills.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/status
|
/status
|
||||||
```
|
```
|
||||||
|
|
||||||
输出示例:
|
|
||||||
|
|
||||||
```
|
|
||||||
🐮 CowAgent Status
|
|
||||||
|
|
||||||
Process: PID 12345 | Running 2h 15m
|
|
||||||
Version: 2.0.4
|
|
||||||
Channel: web
|
|
||||||
Model: MiniMax-M2.5
|
|
||||||
Mode: agent
|
|
||||||
|
|
||||||
Session: 12 messages | 8 skills loaded
|
|
||||||
```
|
|
||||||
|
|
||||||
## cancel
|
## cancel
|
||||||
|
|
||||||
中止当前会话正在运行的 Agent 任务。在 Agent 执行长时间任务(例如多轮工具调用、长流式输出)时,可随时发送 `/cancel`,Agent 会在下一次工具执行前停止。Web 端、微信、企业微信、飞书等各通道均可使用。
|
Abort the agent task currently running in this session. When the agent is busy with a long task (e.g. multi-turn tool calls or a long streaming response), send `/cancel` and the agent will stop before the next tool execution. Available across all channels — Web, WeChat, WeCom, Feishu, etc.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/cancel
|
/cancel
|
||||||
@@ -49,67 +35,67 @@ Session: 12 messages | 8 skills loaded
|
|||||||
|
|
||||||
## config
|
## config
|
||||||
|
|
||||||
查看或修改运行时配置。修改后立即生效,无需重启服务。
|
View or modify runtime configuration. Changes take effect immediately without restarting.
|
||||||
|
|
||||||
**查看所有可配置项:**
|
**View all configurable items:**
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/config
|
/config
|
||||||
```
|
```
|
||||||
|
|
||||||
**查看单个配置项:**
|
**View a single item:**
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/config model
|
/config model
|
||||||
```
|
```
|
||||||
|
|
||||||
**修改配置项:**
|
**Modify a config item:**
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/config model deepseek-v4-flash
|
/config model deepseek-v4-flash
|
||||||
```
|
```
|
||||||
|
|
||||||
**支持修改的配置项:**
|
**Configurable items:**
|
||||||
|
|
||||||
| 配置项 | 说明 | 示例值 |
|
| Item | Description | Example |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `model` | AI 模型名称 | `deepseek-v4-flash` |
|
| `model` | AI model name | `deepseek-v4-flash` |
|
||||||
| `agent_max_context_tokens` | 最大上下文 tokens | `40000` |
|
| `agent_max_context_tokens` | Max context tokens | `40000` |
|
||||||
| `agent_max_context_turns` | 最大上下文记忆轮次 | `30` |
|
| `agent_max_context_turns` | Max context memory turns | `30` |
|
||||||
| `agent_max_steps` | 单次任务最大决策步数 | `15` |
|
| `agent_max_steps` | Max decision steps per task | `15` |
|
||||||
| `enable_thinking` | 是否启用深度思考模式 | `true` / `false` |
|
| `enable_thinking` | Enable deep thinking mode | `true` / `false` |
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
修改 `model` 时,系统会自动匹配对应的模型调用方式。配置会写入 `config.json` 并持久保存。
|
When changing `model`, the system automatically matches the corresponding model API. Configuration is persisted to `config.json`.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
## context
|
## context
|
||||||
|
|
||||||
查看当前会话的上下文信息,包括消息数量、内容长度等统计。
|
View current session context statistics, including message count and content length.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/context
|
/context
|
||||||
```
|
```
|
||||||
|
|
||||||
**清空当前会话上下文:**
|
**Clear current session context:**
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/context clear
|
/context clear
|
||||||
```
|
```
|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
清空上下文后,Agent 会"忘记"之前的对话内容,适用于切换话题或释放上下文空间。
|
Clearing context makes the Agent "forget" previous conversation, useful for switching topics or freeing context space.
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
## logs
|
## logs
|
||||||
|
|
||||||
查看最近的服务日志,默认显示最近 20 行,最多 50 行。
|
View recent service logs. Shows the last 20 lines by default, up to 50.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/logs
|
/logs
|
||||||
```
|
```
|
||||||
|
|
||||||
**指定行数:**
|
**Specify line count:**
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/logs 50
|
/logs 50
|
||||||
@@ -117,7 +103,7 @@ Session: 12 messages | 8 skills loaded
|
|||||||
|
|
||||||
## version
|
## version
|
||||||
|
|
||||||
显示当前 CowAgent 版本号。
|
Show the current CowAgent version.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/version
|
/version
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
---
|
---
|
||||||
title: 命令总览
|
title: Commands Overview
|
||||||
description: CowAgent 命令系统 — 终端 CLI 和对话命令
|
description: CowAgent command system — Terminal CLI and chat commands
|
||||||
---
|
---
|
||||||
|
|
||||||
CowAgent 提供两种命令交互方式:
|
CowAgent provides two ways to interact via commands:
|
||||||
|
|
||||||
- **终端CLI** — 在系统终端中执行 `cow <命令>`,用于服务管理、技能管理等运维操作
|
- **Terminal CLI** — Run `cow <command>` in your system terminal for service management, skill management, and other operations
|
||||||
- **对话命令** — 在对话中输入 `/<命令>` 或 `cow <命令>`,用于查看状态、管理技能、调整配置等
|
- **Chat Commands** — Type `/<command>` or `cow <command>` in any conversation to check status, manage skills, adjust configuration, etc.
|
||||||
|
|
||||||
## 终端命令
|
## Cow CLI
|
||||||
|
|
||||||
通过一键安装脚本部署后,`cow` 命令会自动可用。手动安装的用户需要在项目根目录下额外执行:
|
After deploying with the one-click install script, the `cow` command is automatically available. For manual installations, run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install -e .
|
pip install -e .
|
||||||
```
|
```
|
||||||
|
|
||||||
安装后即可在任意位置使用 `cow` 命令:
|
Then use the `cow` command from anywhere:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cow help
|
cow help
|
||||||
```
|
```
|
||||||
|
|
||||||
输出示例:
|
Example output:
|
||||||
|
|
||||||
```
|
```
|
||||||
CowAgent CLI
|
🐮 CowAgent CLI
|
||||||
|
|
||||||
Usage: cow <command>
|
Usage: cow <command>
|
||||||
|
|
||||||
@@ -49,35 +49,33 @@ Others:
|
|||||||
version Show version
|
version Show version
|
||||||
```
|
```
|
||||||
|
|
||||||
## 对话命令
|
## Chat Commands
|
||||||
|
|
||||||
在 Web 控制台或任意接入渠道的对话中,支持输入以 `/` 开头的命令:
|
In the Web console or any connected channel, type `/` to see command suggestions. Supported commands:
|
||||||
|
|
||||||
| 命令 | 说明 |
|
| Command | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `/help` | 显示命令帮助 |
|
| `/help` | Show command help |
|
||||||
| `/status` | 查看服务状态和配置 |
|
| `/status` | View service status and configuration |
|
||||||
| `/cancel` | 中止当前正在运行的 Agent 任务 |
|
| `/cancel` | Abort the currently running agent task |
|
||||||
| `/config` | 查看或修改运行时配置 |
|
| `/config` | View or modify runtime configuration |
|
||||||
| `/skill` | 管理技能(安装、卸载、启用、禁用等) |
|
| `/skill` | Manage skills (install, uninstall, enable, disable, etc.) |
|
||||||
| `/memory dream [N]` | 手动触发记忆蒸馏(默认 3 天,最大 30) |
|
| `/memory dream [N]` | Manually trigger memory distillation (default 3 days, max 30) |
|
||||||
| `/knowledge` | 查看知识库统计信息 |
|
| `/knowledge` | View knowledge base statistics |
|
||||||
| `/knowledge list` | 查看知识库目录结构 |
|
| `/knowledge list` | View knowledge base directory structure |
|
||||||
| `/knowledge on\|off` | 开启或关闭知识库 |
|
| `/knowledge on\|off` | Enable or disable knowledge base |
|
||||||
| `/context` | 查看当前会话上下文信息 |
|
| `/context` | View current session context info |
|
||||||
| `/context clear` | 清空当前会话上下文 |
|
| `/context clear` | Clear current session context |
|
||||||
| `/logs` | 查看最近日志 |
|
| `/logs` | View recent logs |
|
||||||
| `/version` | 显示版本号 |
|
| `/version` | Show version number |
|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
对话命令中 `/start`、`/stop`、`/restart` 等服务管理命令会提示到终端中执行,因为它们涉及进程操作。
|
Service management commands like `/start`, `/stop`, `/restart` will prompt you to use them in the terminal instead, as they involve process operations.
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
## 命令对照表
|
## Command Availability
|
||||||
|
|
||||||
以下是各命令在终端和对话中的可用性:
|
| Command | Terminal (`cow`) | Chat (`/`) |
|
||||||
|
|
||||||
| 命令 | 终端 (`cow`) | 对话 (`/`) |
|
|
||||||
| --- | :---: | :---: |
|
| --- | :---: | :---: |
|
||||||
| help | ✓ | ✓ |
|
| help | ✓ | ✓ |
|
||||||
| version | ✓ | ✓ |
|
| version | ✓ | ✓ |
|
||||||
@@ -86,13 +84,13 @@ Others:
|
|||||||
| cancel | ✗ | ✓ |
|
| cancel | ✗ | ✓ |
|
||||||
| config | ✗ | ✓ |
|
| config | ✗ | ✓ |
|
||||||
| context | — | ✓ |
|
| context | — | ✓ |
|
||||||
| memory (子命令) | ✗ | ✓ |
|
| memory (subcommands) | ✗ | ✓ |
|
||||||
| knowledge (子命令) | ✓ | ✓ |
|
| knowledge (subcommands) | ✓ | ✓ |
|
||||||
| skill (子命令) | ✓ | ✓ |
|
| skill (subcommands) | ✓ | ✓ |
|
||||||
| start / stop / restart | ✓ | ✗ |
|
| start / stop / restart | ✓ | ✗ |
|
||||||
| update | ✓ | ✗ |
|
| update | ✓ | ✗ |
|
||||||
| install-browser | ✓ | ✗ |
|
| install-browser | ✓ | ✗ |
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
`context` 在终端中仅提示到对话中使用。`config` 仅支持在对话中修改。
|
`context` only shows a hint in the terminal to use it in chat. `config` is only available in chat.
|
||||||
</Note>
|
</Note>
|
||||||
|
|||||||
@@ -1,63 +1,49 @@
|
|||||||
---
|
---
|
||||||
title: 记忆与知识库
|
title: Memory & Knowledge
|
||||||
description: 记忆蒸馏和知识库管理命令
|
description: Memory distillation and knowledge base management commands
|
||||||
---
|
---
|
||||||
|
|
||||||
## memory
|
## memory
|
||||||
|
|
||||||
管理 Agent 的长期记忆系统。
|
Manage the Agent's long-term memory system.
|
||||||
|
|
||||||
### memory dream
|
### memory dream
|
||||||
|
|
||||||
手动触发记忆蒸馏(Deep Dream),整理近期的天级记忆,蒸馏合并到 MEMORY.md,并生成梦境日记。
|
Manually trigger memory distillation (Deep Dream) — consolidate recent daily memories into MEMORY.md and generate a dream diary.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/memory dream [N]
|
/memory dream [N]
|
||||||
```
|
```
|
||||||
|
|
||||||
- `N`:整理近 N 天的记忆,默认 3 天,最大 30 天
|
- `N`: Consolidate the last N days of memory (default 3, max 30)
|
||||||
- 蒸馏在后台异步执行,完成后会在对话中通知结果
|
- Runs asynchronously in the background; you'll be notified in chat when complete
|
||||||
- 无需等待 Agent 初始化,首次对话前即可使用
|
- Works without Agent initialization — can be used before the first conversation
|
||||||
|
|
||||||
**示例:**
|
**Examples:**
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/memory dream # 整理近 3 天
|
/memory dream # Consolidate last 3 days
|
||||||
/memory dream 7 # 整理近 7 天
|
/memory dream 7 # Consolidate last 7 days
|
||||||
/memory dream 30 # 整理近 30 天(全量)
|
/memory dream 30 # Consolidate last 30 days (full)
|
||||||
```
|
```
|
||||||
|
|
||||||
蒸馏完成后,Web 端会收到带有跳转链接的通知,可直接查看更新后的 MEMORY.md 和梦境日记。
|
On the Web console, the completion notification includes clickable links to view the updated MEMORY.md and dream diary.
|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
系统每天 23:55 会自动执行一次蒸馏(lookback 1 天)。手动触发适用于首次部署后的历史整理,或需要立即更新记忆时使用。
|
The system automatically runs distillation daily at 23:55 (lookback 1 day). Manual trigger is useful for consolidating historical memories after first deployment, or when you need an immediate memory update.
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
## knowledge
|
## knowledge
|
||||||
|
|
||||||
查看和管理个人知识库。默认显示知识库统计信息。
|
View and manage the personal knowledge base. Shows statistics by default.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/knowledge
|
/knowledge
|
||||||
```
|
```
|
||||||
|
|
||||||
输出示例:
|
|
||||||
|
|
||||||
```
|
|
||||||
📚 知识库
|
|
||||||
|
|
||||||
- 状态:已开启
|
|
||||||
- 页面数:12
|
|
||||||
- 总大小:45.2 KB
|
|
||||||
- 分类明细:
|
|
||||||
- concepts/: 5 篇
|
|
||||||
- entities/: 4 篇
|
|
||||||
- sources/: 3 篇
|
|
||||||
```
|
|
||||||
|
|
||||||
### knowledge list
|
### knowledge list
|
||||||
|
|
||||||
查看知识库目录树结构。
|
View the knowledge base directory tree.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/knowledge list
|
/knowledge list
|
||||||
@@ -65,7 +51,7 @@ description: 记忆蒸馏和知识库管理命令
|
|||||||
|
|
||||||
### knowledge on / off
|
### knowledge on / off
|
||||||
|
|
||||||
开启或关闭知识库。关闭后不再注入知识提示词和索引知识文件。
|
Enable or disable the knowledge base. When disabled, knowledge prompts and file indexing are not injected.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/knowledge on
|
/knowledge on
|
||||||
@@ -73,5 +59,5 @@ description: 记忆蒸馏和知识库管理命令
|
|||||||
```
|
```
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
终端 CLI 中 `cow knowledge` 和 `cow knowledge list` 可用,但 `on|off` 仅支持在对话中使用(需实时生效)。
|
In the terminal CLI, `cow knowledge` and `cow knowledge list` are available, but `on|off` is only supported in chat (requires runtime effect).
|
||||||
</Note>
|
</Note>
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
---
|
---
|
||||||
title: 进程管理
|
title: Process Management
|
||||||
description: 使用 cow 命令管理 CowAgent 进程的启动、停止、重启、更新等操作
|
description: Manage CowAgent process lifecycle with cow commands
|
||||||
---
|
---
|
||||||
|
|
||||||
进程管理命令用于控制 CowAgent 后台进程的生命周期。这些命令仅在终端中可用。
|
Process management commands control the CowAgent background process. These commands are only available in the terminal.
|
||||||
|
|
||||||
## start
|
## start
|
||||||
|
|
||||||
启动 CowAgent 服务。默认以后台进程方式运行,并自动跟踪日志输出。
|
Start the CowAgent service. Runs as a background daemon by default and automatically tails logs.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cow start
|
cow start
|
||||||
```
|
```
|
||||||
|
|
||||||
**选项:**
|
**Options:**
|
||||||
|
|
||||||
| 选项 | 说明 |
|
| Option | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `-f`, `--foreground` | 前台运行,不以后台守护进程方式启动 |
|
| `-f`, `--foreground` | Run in foreground, not as a background daemon |
|
||||||
| `--no-logs` | 启动后不自动跟踪日志 |
|
| `--no-logs` | Don't tail logs after starting |
|
||||||
|
|
||||||
## stop
|
## stop
|
||||||
|
|
||||||
停止正在运行的 CowAgent 服务。
|
Stop the running CowAgent service.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cow stop
|
cow stop
|
||||||
@@ -30,97 +30,86 @@ cow stop
|
|||||||
|
|
||||||
## restart
|
## restart
|
||||||
|
|
||||||
重启 CowAgent 服务(先停止再启动)。
|
Restart the CowAgent service (stop then start).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cow restart
|
cow restart
|
||||||
```
|
```
|
||||||
|
|
||||||
**选项:**
|
**Options:**
|
||||||
|
|
||||||
| 选项 | 说明 |
|
| Option | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `--no-logs` | 重启后不自动跟踪日志 |
|
| `--no-logs` | Don't tail logs after restart |
|
||||||
|
|
||||||
## update
|
## update
|
||||||
|
|
||||||
更新代码并重启服务。自动执行以下流程:
|
Update code and restart the service. Automatically performs:
|
||||||
|
|
||||||
1. 拉取最新代码(`git pull`)
|
1. Pull latest code (`git pull`)
|
||||||
2. 停止当前服务
|
2. Stop current service
|
||||||
3. 更新 Python 依赖
|
3. Update Python dependencies
|
||||||
4. 重新安装 CLI
|
4. Reinstall CLI
|
||||||
5. 启动服务
|
5. Start service
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cow update
|
cow update
|
||||||
```
|
```
|
||||||
|
|
||||||
<Warning>
|
<Warning>
|
||||||
如果 `git pull` 失败(如存在本地未提交的修改),更新会中止,服务不受影响。
|
If `git pull` fails (e.g., uncommitted local changes), the update aborts and the service remains unaffected.
|
||||||
</Warning>
|
</Warning>
|
||||||
|
|
||||||
## status
|
## status
|
||||||
|
|
||||||
查看 CowAgent 服务运行状态,包括进程信息、版本号、当前配置的模型和通道。
|
Check CowAgent service status, including process info, version, and current model/channel configuration.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cow status
|
cow status
|
||||||
```
|
```
|
||||||
|
|
||||||
输出示例:
|
|
||||||
|
|
||||||
```
|
|
||||||
🐮 CowAgent Status
|
|
||||||
Status: ● Running (PID: 12345)
|
|
||||||
Version: 2.0.4
|
|
||||||
Channel: web
|
|
||||||
Model: MiniMax-M2.5
|
|
||||||
Mode: agent
|
|
||||||
```
|
|
||||||
|
|
||||||
## logs
|
## logs
|
||||||
|
|
||||||
查看服务日志。
|
View service logs.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cow logs
|
cow logs
|
||||||
```
|
```
|
||||||
|
|
||||||
**选项:**
|
**Options:**
|
||||||
|
|
||||||
| 选项 | 说明 | 默认值 |
|
| Option | Description | Default |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `-f`, `--follow` | 持续跟踪日志输出 | 否 |
|
| `-f`, `--follow` | Continuously tail log output | No |
|
||||||
| `-n`, `--lines` | 显示最近 N 行 | 50 |
|
| `-n`, `--lines` | Show last N lines | 50 |
|
||||||
|
|
||||||
示例:
|
Examples:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 查看最近 100 行日志
|
# View last 100 lines
|
||||||
cow logs -n 100
|
cow logs -n 100
|
||||||
|
|
||||||
# 持续跟踪日志
|
# Continuously tail logs
|
||||||
cow logs -f
|
cow logs -f
|
||||||
```
|
```
|
||||||
|
|
||||||
## install-browser
|
## install-browser
|
||||||
|
|
||||||
安装 Playwright 和 Chromium 浏览器,用于启用 [浏览器工具](/tools/browser)。
|
Install Playwright and Chromium browser for the [browser tool](/tools/browser).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cow install-browser
|
cow install-browser
|
||||||
```
|
```
|
||||||
|
|
||||||
<Tip>
|
<Tip>
|
||||||
仅在需要使用浏览器工具(如网页浏览、截图等)时才需要安装。
|
Only needed when using browser tools (web browsing, screenshots, etc.).
|
||||||
</Tip>
|
</Tip>
|
||||||
|
|
||||||
## run.sh 兼容
|
## run.sh Compatibility
|
||||||
|
|
||||||
如果未安装 Cow CLI,也可以使用 `run.sh` 脚本管理服务:
|
If Cow CLI is not installed, you can use `run.sh` to manage the service:
|
||||||
|
|
||||||
| cow 命令 | run.sh 等效命令 |
|
| cow command | run.sh equivalent |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `cow start` | `./run.sh start` |
|
| `cow start` | `./run.sh start` |
|
||||||
| `cow stop` | `./run.sh stop` |
|
| `cow stop` | `./run.sh stop` |
|
||||||
@@ -130,5 +119,5 @@ cow install-browser
|
|||||||
| `cow logs` | `./run.sh logs` |
|
| `cow logs` | `./run.sh logs` |
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
推荐使用 `cow` 命令,它提供更简洁的语法和更丰富的功能。通过一键安装脚本部署时 `cow` 命令会自动安装。
|
The `cow` command is recommended — it provides cleaner syntax and richer features. It is automatically installed via the one-click install script.
|
||||||
</Note>
|
</Note>
|
||||||
|
|||||||
@@ -1,190 +1,182 @@
|
|||||||
---
|
---
|
||||||
title: 技能管理
|
title: Skill Management
|
||||||
description: 通过命令安装、卸载、启用、禁用和管理技能
|
description: Install, uninstall, enable, disable, and manage skills via commands
|
||||||
---
|
---
|
||||||
|
|
||||||
技能管理命令用于安装、查询和管理 CowAgent 的技能。在对话中使用 `/skill <子命令>`,在终端中使用 `cow skill <子命令>`。
|
Skill management commands are used to install, query, and manage CowAgent skills. Use `/skill <subcommand>` in chat or `cow skill <subcommand>` in the terminal.
|
||||||
|
|
||||||
## list
|
## list
|
||||||
|
|
||||||
列出已安装的技能及其状态。
|
List installed skills and their status.
|
||||||
|
|
||||||
<CodeGroup>
|
<CodeGroup>
|
||||||
```text 对话
|
```text Chat
|
||||||
/skill list
|
/skill list
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash 终端
|
```bash Terminal
|
||||||
cow skill list
|
cow skill list
|
||||||
```
|
```
|
||||||
</CodeGroup>
|
</CodeGroup>
|
||||||
|
|
||||||
输出示例:
|
Example output:
|
||||||
|
|
||||||
```
|
```
|
||||||
📦 已安装的技能 (3/4)
|
📦 Installed skills (3/4)
|
||||||
|
|
||||||
✅ pptx
|
✅ pptx
|
||||||
Use this skill any time a .pptx file is involved…
|
Use this skill any time a .pptx file is involved…
|
||||||
来源: cowhub
|
Source: cowhub
|
||||||
|
|
||||||
✅ skill-creator
|
✅ skill-creator
|
||||||
Create, install, or update skills…
|
Create, install, or update skills…
|
||||||
来源: builtin
|
Source: builtin
|
||||||
|
|
||||||
⏸️ image-vision (已禁用)
|
⏸️ image-vision (disabled)
|
||||||
图片理解和视觉分析
|
Image understanding and visual analysis
|
||||||
来源: builtin
|
Source: builtin
|
||||||
```
|
```
|
||||||
|
|
||||||
**浏览技能广场**(查看 Hub 上所有可安装的技能):
|
**Browse the Skill Hub** (view all available skills):
|
||||||
|
|
||||||
<CodeGroup>
|
<CodeGroup>
|
||||||
```text 对话
|
```text Chat
|
||||||
/skill list --remote
|
/skill list --remote
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash 终端
|
```bash Terminal
|
||||||
cow skill list --remote
|
cow skill list --remote
|
||||||
```
|
```
|
||||||
</CodeGroup>
|
</CodeGroup>
|
||||||
|
|
||||||
**选项:**
|
**Options:**
|
||||||
|
|
||||||
| 选项 | 说明 | 默认值 |
|
| Option | Description | Default |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `--remote`, `-r` | 浏览 Skill Hub 远程技能列表 | 否 |
|
| `--remote`, `-r` | Browse Skill Hub remote skill list | No |
|
||||||
| `--page` | 远程列表分页页码 | 1 |
|
| `--page` | Page number for remote listing | 1 |
|
||||||
|
|
||||||
## search
|
## search
|
||||||
|
|
||||||
在技能广场中搜索技能。
|
Search for skills on the Skill Hub.
|
||||||
|
|
||||||
<CodeGroup>
|
<CodeGroup>
|
||||||
```text 对话
|
```text Chat
|
||||||
/skill search pptx
|
/skill search pptx
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash 终端
|
```bash Terminal
|
||||||
cow skill search pptx
|
cow skill search pptx
|
||||||
```
|
```
|
||||||
</CodeGroup>
|
</CodeGroup>
|
||||||
|
|
||||||
## install
|
## install
|
||||||
|
|
||||||
安装技能。通过统一的 `install` 命令,可一键安装来自 **Cow 技能广场、GitHub、ClawHub** 以及任意 URL(zip 压缩包、SKILL.md 链接)上的技能,无需手动下载和配置。
|
Install skills with a single `install` command from Cow Skill Hub, GitHub, ClawHub, or any URL (zip archives, SKILL.md links) — no manual download or configuration required.
|
||||||
|
|
||||||
**从 Cow 技能广场安装(推荐):**
|
**From Skill Hub (recommended):**
|
||||||
|
|
||||||
<CodeGroup>
|
<CodeGroup>
|
||||||
```text 对话
|
```text Chat
|
||||||
/skill install pptx
|
/skill install pptx
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash 终端
|
```bash Terminal
|
||||||
cow skill install pptx
|
cow skill install pptx
|
||||||
```
|
```
|
||||||
</CodeGroup>
|
</CodeGroup>
|
||||||
|
|
||||||
**从 GitHub 安装:**
|
**From GitHub:**
|
||||||
|
|
||||||
<CodeGroup>
|
<CodeGroup>
|
||||||
```text 对话
|
```text Chat
|
||||||
# 安装仓库中的所有技能(自动扫描包含 SKILL.md 的子目录)
|
# Install all skills in a repo (auto-discovers subdirectories with SKILL.md)
|
||||||
/skill install larksuite/cli
|
/skill install larksuite/cli
|
||||||
|
|
||||||
# 指定子目录,只安装单个技能
|
# Specify a subdirectory to install a single skill
|
||||||
/skill install https://github.com/larksuite/cli/tree/main/skills/lark-im
|
/skill install https://github.com/larksuite/cli/tree/main/skills/lark-im
|
||||||
|
|
||||||
# 使用 # 指定子目录
|
# Use # to specify a subdirectory
|
||||||
/skill install larksuite/cli#skills/lark-minutes
|
/skill install larksuite/cli#skills/lark-minutes
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash 终端
|
```bash Terminal
|
||||||
# 安装仓库中的所有技能(自动扫描包含 SKILL.md 的子目录)
|
# Install all skills in a repo (auto-discovers subdirectories with SKILL.md)
|
||||||
cow skill install larksuite/cli
|
cow skill install larksuite/cli
|
||||||
|
|
||||||
# 指定子目录,只安装单个技能
|
# Specify a subdirectory to install a single skill
|
||||||
cow skill install https://github.com/larksuite/cli/tree/main/skills/lark-im
|
cow skill install https://github.com/larksuite/cli/tree/main/skills/lark-im
|
||||||
|
|
||||||
# 使用 # 指定子目录
|
# Use # to specify a subdirectory
|
||||||
cow skill install larksuite/cli#skills/lark-minutes
|
cow skill install larksuite/cli#skills/lark-minutes
|
||||||
```
|
```
|
||||||
</CodeGroup>
|
</CodeGroup>
|
||||||
|
|
||||||
支持完整的 GitHub URL 和 `owner/repo` 简写。对于 mono-repo(一个仓库中包含多个技能),不指定子目录时会自动发现并批量安装所有技能;指定子目录时只安装该目录下的技能。
|
Supports full GitHub URLs and `owner/repo` shorthand. For mono-repos (multiple skills in one repository), omitting the subdirectory auto-discovers and batch-installs all skills; specifying a subdirectory installs only that skill.
|
||||||
|
|
||||||
**从 ClawHub 安装:**
|
**From ClawHub:**
|
||||||
|
|
||||||
<CodeGroup>
|
<CodeGroup>
|
||||||
```text 对话
|
```text Chat
|
||||||
/skill install clawhub:baidu-search
|
/skill install clawhub:baidu-search
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash 终端
|
```bash Terminal
|
||||||
cow skill install clawhub:baidu-search
|
cow skill install clawhub:baidu-search
|
||||||
```
|
```
|
||||||
</CodeGroup>
|
</CodeGroup>
|
||||||
|
|
||||||
**从 URL 安装:**
|
**From URL:**
|
||||||
|
|
||||||
<CodeGroup>
|
<CodeGroup>
|
||||||
```text 对话
|
```text Chat
|
||||||
# 从 zip 压缩包安装(支持单个或批量)
|
# Install from a zip archive (single or batch)
|
||||||
/skill install https://cdn.link-ai.tech/skills/pptx.zip
|
/skill install https://cdn.link-ai.tech/skills/pptx.zip
|
||||||
|
|
||||||
# 从 SKILL.md 链接安装
|
# Install from a SKILL.md link
|
||||||
/skill install https://example.com/path/to/SKILL.md
|
/skill install https://example.com/path/to/SKILL.md
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash 终端
|
```bash Terminal
|
||||||
# 从 zip 压缩包安装(支持单个或批量)
|
# Install from a zip archive (single or batch)
|
||||||
cow skill install https://cdn.link-ai.tech/skills/pptx.zip
|
cow skill install https://cdn.link-ai.tech/skills/pptx.zip
|
||||||
|
|
||||||
# 从 SKILL.md 链接安装
|
# Install from a SKILL.md link
|
||||||
cow skill install https://example.com/path/to/SKILL.md
|
cow skill install https://example.com/path/to/SKILL.md
|
||||||
```
|
```
|
||||||
</CodeGroup>
|
</CodeGroup>
|
||||||
|
|
||||||
支持从 zip / tar.gz 压缩包 URL 安装,解压后自动扫描包含 `SKILL.md` 的目录,支持单个或批量安装。也支持直接从 `SKILL.md` 文件链接安装,会自动解析技能名称和描述。
|
Supports installing from zip / tar.gz archive URLs — automatically extracts and discovers directories containing `SKILL.md`, with support for single or batch install. Also supports installing directly from a `SKILL.md` file URL, automatically parsing the skill name and description.
|
||||||
|
|
||||||
安装成功后会显示技能名称、描述和来源,例如:
|
|
||||||
|
|
||||||
```
|
|
||||||
✅ baidu-search
|
|
||||||
百度搜索:使用百度搜索引擎检索信息…
|
|
||||||
来源: clawhub
|
|
||||||
```
|
|
||||||
|
|
||||||
## uninstall
|
## uninstall
|
||||||
|
|
||||||
卸载已安装的技能。
|
Uninstall an installed skill.
|
||||||
|
|
||||||
<CodeGroup>
|
<CodeGroup>
|
||||||
```text 对话
|
```text Chat
|
||||||
/skill uninstall pptx
|
/skill uninstall pptx
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash 终端
|
```bash Terminal
|
||||||
cow skill uninstall pptx
|
cow skill uninstall pptx
|
||||||
```
|
```
|
||||||
</CodeGroup>
|
</CodeGroup>
|
||||||
|
|
||||||
<Warning>
|
<Warning>
|
||||||
卸载操作会删除技能目录下的所有文件,此操作不可恢复。
|
Uninstalling deletes all files in the skill directory. This action cannot be undone.
|
||||||
</Warning>
|
</Warning>
|
||||||
|
|
||||||
## enable / disable
|
## enable / disable
|
||||||
|
|
||||||
启用或禁用技能,禁用后技能不会被 Agent 调用。
|
Enable or disable a skill. Disabled skills will not be invoked by the Agent.
|
||||||
|
|
||||||
<CodeGroup>
|
<CodeGroup>
|
||||||
```text 对话
|
```text Chat
|
||||||
/skill enable pptx
|
/skill enable pptx
|
||||||
/skill disable pptx
|
/skill disable pptx
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash 终端
|
```bash Terminal
|
||||||
cow skill enable pptx
|
cow skill enable pptx
|
||||||
cow skill disable pptx
|
cow skill disable pptx
|
||||||
```
|
```
|
||||||
@@ -192,27 +184,27 @@ cow skill disable pptx
|
|||||||
|
|
||||||
## info
|
## info
|
||||||
|
|
||||||
查看已安装技能的详细信息,包括 `SKILL.md` 内容预览。
|
View details of an installed skill, including a preview of its `SKILL.md`.
|
||||||
|
|
||||||
<CodeGroup>
|
<CodeGroup>
|
||||||
```text 对话
|
```text Chat
|
||||||
/skill info pptx
|
/skill info pptx
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash 终端
|
```bash Terminal
|
||||||
cow skill info pptx
|
cow skill info pptx
|
||||||
```
|
```
|
||||||
</CodeGroup>
|
</CodeGroup>
|
||||||
|
|
||||||
## 技能来源
|
## Skill Sources
|
||||||
|
|
||||||
安装的技能会记录来源信息,可通过 `/skill list` 查看:
|
Installed skills track their origin, viewable via `/skill list`:
|
||||||
|
|
||||||
| 来源标识 | 说明 |
|
| Source | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `builtin` | 项目内置技能 |
|
| `builtin` | Built-in project skills |
|
||||||
| `cowhub` | 从 CowAgent Skill Hub 安装 |
|
| `cowhub` | Installed from CowAgent Skill Hub |
|
||||||
| `github` | 从 GitHub URL 直接安装 |
|
| `github` | Installed directly from a GitHub URL |
|
||||||
| `clawhub` | 从 ClawHub 安装 |
|
| `clawhub` | Installed from ClawHub |
|
||||||
| `url` | 从 SKILL.md URL 安装 |
|
| `url` | Installed from a SKILL.md URL |
|
||||||
| `local` | 本地创建的技能 |
|
| `local` | Locally created skills |
|
||||||
|
|||||||
301
docs/docs.json
301
docs/docs.json
@@ -33,23 +33,36 @@
|
|||||||
"github": "https://github.com/zhayujie/CowAgent"
|
"github": "https://github.com/zhayujie/CowAgent"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"redirects": [
|
||||||
|
{
|
||||||
|
"source": "/en/:slug*",
|
||||||
|
"destination": "/:slug*",
|
||||||
|
"permanent": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"languages": [
|
"languages": [
|
||||||
{
|
{
|
||||||
"language": "zh",
|
"language": "en",
|
||||||
"default": true,
|
"default": true,
|
||||||
"navbar": {
|
"navbar": {
|
||||||
"links": [
|
"links": [
|
||||||
{ "label": "官网", "href": "https://cowagent.ai/?lang=zh" },
|
{
|
||||||
{ "label": "GitHub", "href": "https://github.com/zhayujie/CowAgent" }
|
"label": "Website",
|
||||||
|
"href": "https://cowagent.ai/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "GitHub",
|
||||||
|
"href": "https://github.com/zhayujie/CowAgent"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"tabs": [
|
"tabs": [
|
||||||
{
|
{
|
||||||
"tab": "项目介绍",
|
"tab": "Introduction",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "概览",
|
"group": "Overview",
|
||||||
"pages": [
|
"pages": [
|
||||||
"intro/index",
|
"intro/index",
|
||||||
"intro/architecture",
|
"intro/architecture",
|
||||||
@@ -59,10 +72,10 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "快速开始",
|
"tab": "Get Started",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "安装部署",
|
"group": "Installation",
|
||||||
"pages": [
|
"pages": [
|
||||||
"guide/quick-start",
|
"guide/quick-start",
|
||||||
"guide/manual-install",
|
"guide/manual-install",
|
||||||
@@ -72,17 +85,17 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "模型",
|
"tab": "Models",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "模型配置",
|
"group": "Model Configuration",
|
||||||
"pages": [
|
"pages": [
|
||||||
"models/index",
|
"models/index",
|
||||||
"models/deepseek",
|
"models/deepseek",
|
||||||
"models/minimax",
|
|
||||||
"models/claude",
|
"models/claude",
|
||||||
"models/gemini",
|
"models/gemini",
|
||||||
"models/openai",
|
"models/openai",
|
||||||
|
"models/minimax",
|
||||||
"models/glm",
|
"models/glm",
|
||||||
"models/qwen",
|
"models/qwen",
|
||||||
"models/doubao",
|
"models/doubao",
|
||||||
@@ -97,16 +110,16 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "工具",
|
"tab": "Tools",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "工具系统",
|
"group": "Tools System",
|
||||||
"pages": [
|
"pages": [
|
||||||
"tools/index"
|
"tools/index"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group": "内置工具",
|
"group": "Built-in Tools",
|
||||||
"pages": [
|
"pages": [
|
||||||
"tools/read",
|
"tools/read",
|
||||||
"tools/write",
|
"tools/write",
|
||||||
@@ -121,7 +134,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group": "可选工具",
|
"group": "Optional Tools",
|
||||||
"pages": [
|
"pages": [
|
||||||
"tools/web-search",
|
"tools/web-search",
|
||||||
"tools/vision",
|
"tools/vision",
|
||||||
@@ -129,7 +142,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group": "MCP 工具",
|
"group": "MCP Tools",
|
||||||
"pages": [
|
"pages": [
|
||||||
"tools/mcp"
|
"tools/mcp"
|
||||||
]
|
]
|
||||||
@@ -137,10 +150,10 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "技能",
|
"tab": "Skills",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "技能系统",
|
"group": "Skills System",
|
||||||
"pages": [
|
"pages": [
|
||||||
"skills/index",
|
"skills/index",
|
||||||
"skills/install",
|
"skills/install",
|
||||||
@@ -149,7 +162,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group": "内置技能",
|
"group": "Built-in Skills",
|
||||||
"pages": [
|
"pages": [
|
||||||
"skills/skill-creator",
|
"skills/skill-creator",
|
||||||
"skills/knowledge-wiki",
|
"skills/knowledge-wiki",
|
||||||
@@ -159,10 +172,10 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "记忆",
|
"tab": "Memory",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "记忆系统",
|
"group": "Memory System",
|
||||||
"pages": [
|
"pages": [
|
||||||
"memory/index",
|
"memory/index",
|
||||||
"memory/context",
|
"memory/context",
|
||||||
@@ -172,10 +185,10 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "知识",
|
"tab": "Knowledge",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "知识库",
|
"group": "Knowledge Base",
|
||||||
"pages": [
|
"pages": [
|
||||||
"knowledge/index"
|
"knowledge/index"
|
||||||
]
|
]
|
||||||
@@ -183,33 +196,33 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "通道",
|
"tab": "Channels",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "接入渠道",
|
"group": "Platforms",
|
||||||
"pages": [
|
"pages": [
|
||||||
"channels/index",
|
"channels/index",
|
||||||
"channels/weixin",
|
|
||||||
"channels/web",
|
"channels/web",
|
||||||
|
"channels/telegram",
|
||||||
|
"channels/slack",
|
||||||
|
"channels/discord",
|
||||||
|
"channels/weixin",
|
||||||
"channels/feishu",
|
"channels/feishu",
|
||||||
"channels/dingtalk",
|
"channels/dingtalk",
|
||||||
"channels/wecom-bot",
|
"channels/wecom-bot",
|
||||||
"channels/qq",
|
"channels/qq",
|
||||||
"channels/wecom",
|
"channels/wecom",
|
||||||
"channels/wechat-kf",
|
"channels/wechat-kf",
|
||||||
"channels/wechatmp",
|
"channels/wechatmp"
|
||||||
"channels/telegram",
|
|
||||||
"channels/slack",
|
|
||||||
"channels/discord"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "命令",
|
"tab": "CLI",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "命令系统",
|
"group": "Command System",
|
||||||
"pages": [
|
"pages": [
|
||||||
"cli/index",
|
"cli/index",
|
||||||
"cli/process",
|
"cli/process",
|
||||||
@@ -221,10 +234,10 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "版本",
|
"tab": "Releases",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "发布记录",
|
"group": "Release Notes",
|
||||||
"pages": [
|
"pages": [
|
||||||
"releases/overview",
|
"releases/overview",
|
||||||
"releases/v2.0.9",
|
"releases/v2.0.9",
|
||||||
@@ -244,206 +257,212 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"language": "en",
|
"language": "zh",
|
||||||
"navbar": {
|
"navbar": {
|
||||||
"links": [
|
"links": [
|
||||||
{ "label": "Website", "href": "https://cowagent.ai/" },
|
{
|
||||||
{ "label": "GitHub", "href": "https://github.com/zhayujie/CowAgent" }
|
"label": "官网",
|
||||||
|
"href": "https://cowagent.ai/?lang=zh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "GitHub",
|
||||||
|
"href": "https://github.com/zhayujie/CowAgent"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"tabs": [
|
"tabs": [
|
||||||
{
|
{
|
||||||
"tab": "Introduction",
|
"tab": "项目介绍",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "Overview",
|
"group": "概览",
|
||||||
"pages": [
|
"pages": [
|
||||||
"en/intro/index",
|
"zh/intro/index",
|
||||||
"en/intro/architecture",
|
"zh/intro/architecture",
|
||||||
"en/intro/features"
|
"zh/intro/features"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "Get Started",
|
"tab": "快速开始",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "Installation",
|
"group": "安装部署",
|
||||||
"pages": [
|
"pages": [
|
||||||
"en/guide/quick-start",
|
"zh/guide/quick-start",
|
||||||
"en/guide/manual-install",
|
"zh/guide/manual-install",
|
||||||
"en/guide/upgrade"
|
"zh/guide/upgrade"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "Models",
|
"tab": "模型",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "Model Configuration",
|
"group": "模型配置",
|
||||||
"pages": [
|
"pages": [
|
||||||
"en/models/index",
|
"zh/models/index",
|
||||||
"en/models/deepseek",
|
"zh/models/deepseek",
|
||||||
"en/models/claude",
|
"zh/models/minimax",
|
||||||
"en/models/gemini",
|
"zh/models/claude",
|
||||||
"en/models/openai",
|
"zh/models/gemini",
|
||||||
"en/models/minimax",
|
"zh/models/openai",
|
||||||
"en/models/glm",
|
"zh/models/glm",
|
||||||
"en/models/qwen",
|
"zh/models/qwen",
|
||||||
"en/models/doubao",
|
"zh/models/doubao",
|
||||||
"en/models/kimi",
|
"zh/models/kimi",
|
||||||
"en/models/qianfan",
|
"zh/models/qianfan",
|
||||||
"en/models/mimo",
|
"zh/models/mimo",
|
||||||
"en/models/linkai",
|
"zh/models/linkai",
|
||||||
"en/models/coding-plan",
|
"zh/models/coding-plan",
|
||||||
"en/models/custom"
|
"zh/models/custom"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "Tools",
|
"tab": "工具",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "Tools System",
|
"group": "工具系统",
|
||||||
"pages": [
|
"pages": [
|
||||||
"en/tools/index"
|
"zh/tools/index"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group": "Built-in Tools",
|
"group": "内置工具",
|
||||||
"pages": [
|
"pages": [
|
||||||
"en/tools/read",
|
"zh/tools/read",
|
||||||
"en/tools/write",
|
"zh/tools/write",
|
||||||
"en/tools/edit",
|
"zh/tools/edit",
|
||||||
"en/tools/ls",
|
"zh/tools/ls",
|
||||||
"en/tools/bash",
|
"zh/tools/bash",
|
||||||
"en/tools/send",
|
"zh/tools/send",
|
||||||
"en/tools/memory",
|
"zh/tools/memory",
|
||||||
"en/tools/env-config",
|
"zh/tools/env-config",
|
||||||
"en/tools/web-fetch",
|
"zh/tools/web-fetch",
|
||||||
"en/tools/scheduler"
|
"zh/tools/scheduler"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group": "Optional Tools",
|
"group": "可选工具",
|
||||||
"pages": [
|
"pages": [
|
||||||
"en/tools/web-search",
|
"zh/tools/web-search",
|
||||||
"en/tools/vision",
|
"zh/tools/vision",
|
||||||
"en/tools/browser"
|
"zh/tools/browser"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group": "MCP Tools",
|
"group": "MCP 工具",
|
||||||
"pages": [
|
"pages": [
|
||||||
"en/tools/mcp"
|
"zh/tools/mcp"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "Skills",
|
"tab": "技能",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "Skills System",
|
"group": "技能系统",
|
||||||
"pages": [
|
"pages": [
|
||||||
"en/skills/index",
|
"zh/skills/index",
|
||||||
"en/skills/install",
|
"zh/skills/install",
|
||||||
"en/skills/create",
|
"zh/skills/create",
|
||||||
"en/skills/hub"
|
"zh/skills/hub"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group": "Built-in Skills",
|
"group": "内置技能",
|
||||||
"pages": [
|
"pages": [
|
||||||
"en/skills/skill-creator",
|
"zh/skills/skill-creator",
|
||||||
"en/skills/knowledge-wiki",
|
"zh/skills/knowledge-wiki",
|
||||||
"en/skills/image-generation"
|
"zh/skills/image-generation"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "Memory",
|
"tab": "记忆",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "Memory System",
|
"group": "记忆系统",
|
||||||
"pages": [
|
"pages": [
|
||||||
"en/memory/index",
|
"zh/memory/index",
|
||||||
"en/memory/context",
|
"zh/memory/context",
|
||||||
"en/memory/deep-dream"
|
"zh/memory/deep-dream"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "Knowledge",
|
"tab": "知识",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "Knowledge Base",
|
"group": "知识库",
|
||||||
"pages": [
|
"pages": [
|
||||||
"en/knowledge/index"
|
"zh/knowledge/index"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "Channels",
|
"tab": "通道",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "Platforms",
|
"group": "接入渠道",
|
||||||
"pages": [
|
"pages": [
|
||||||
"en/channels/index",
|
"zh/channels/index",
|
||||||
"en/channels/web",
|
"zh/channels/weixin",
|
||||||
"en/channels/telegram",
|
"zh/channels/web",
|
||||||
"en/channels/slack",
|
"zh/channels/feishu",
|
||||||
"en/channels/discord",
|
"zh/channels/dingtalk",
|
||||||
"en/channels/weixin",
|
"zh/channels/wecom-bot",
|
||||||
"en/channels/feishu",
|
"zh/channels/qq",
|
||||||
"en/channels/dingtalk",
|
"zh/channels/wecom",
|
||||||
"en/channels/wecom-bot",
|
"zh/channels/wechat-kf",
|
||||||
"en/channels/qq",
|
"zh/channels/wechatmp",
|
||||||
"en/channels/wecom",
|
"zh/channels/telegram",
|
||||||
"en/channels/wechat-kf",
|
"zh/channels/slack",
|
||||||
"en/channels/wechatmp"
|
"zh/channels/discord"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "CLI",
|
"tab": "命令",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "Command System",
|
"group": "命令系统",
|
||||||
"pages": [
|
"pages": [
|
||||||
"en/cli/index",
|
"zh/cli/index",
|
||||||
"en/cli/process",
|
"zh/cli/process",
|
||||||
"en/cli/skill",
|
"zh/cli/skill",
|
||||||
"en/cli/memory-knowledge",
|
"zh/cli/memory-knowledge",
|
||||||
"en/cli/general"
|
"zh/cli/general"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tab": "Releases",
|
"tab": "版本",
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"group": "Release Notes",
|
"group": "发布记录",
|
||||||
"pages": [
|
"pages": [
|
||||||
"en/releases/overview",
|
"zh/releases/overview",
|
||||||
"en/releases/v2.0.9",
|
"zh/releases/v2.0.9",
|
||||||
"en/releases/v2.0.8",
|
"zh/releases/v2.0.8",
|
||||||
"en/releases/v2.0.7",
|
"zh/releases/v2.0.7",
|
||||||
"en/releases/v2.0.6",
|
"zh/releases/v2.0.6",
|
||||||
"en/releases/v2.0.5",
|
"zh/releases/v2.0.5",
|
||||||
"en/releases/v2.0.4",
|
"zh/releases/v2.0.4",
|
||||||
"en/releases/v2.0.3",
|
"zh/releases/v2.0.3",
|
||||||
"en/releases/v2.0.2",
|
"zh/releases/v2.0.2",
|
||||||
"en/releases/v2.0.1",
|
"zh/releases/v2.0.1",
|
||||||
"en/releases/v2.0.0"
|
"zh/releases/v2.0.0"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -454,8 +473,14 @@
|
|||||||
"language": "ja",
|
"language": "ja",
|
||||||
"navbar": {
|
"navbar": {
|
||||||
"links": [
|
"links": [
|
||||||
{ "label": "ウェブサイト", "href": "https://cowagent.ai/" },
|
{
|
||||||
{ "label": "GitHub", "href": "https://github.com/zhayujie/CowAgent" }
|
"label": "ウェブサイト",
|
||||||
|
"href": "https://cowagent.ai/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "GitHub",
|
||||||
|
"href": "https://github.com/zhayujie/CowAgent"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"tabs": [
|
"tabs": [
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
---
|
|
||||||
title: DingTalk
|
|
||||||
description: Integrate CowAgent into DingTalk application
|
|
||||||
---
|
|
||||||
|
|
||||||
Integrate CowAgent into DingTalk by creating an intelligent robot app on the DingTalk Open Platform.
|
|
||||||
|
|
||||||
## 1. Create App
|
|
||||||
|
|
||||||
1. Go to [DingTalk Developer Console](https://open-dev.dingtalk.com/fe/app#/corp/app), log in and click **Create App**, fill in the app information:
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-create-app.png" width="800"/>
|
|
||||||
|
|
||||||
2. Click **Add App Capability**, select **Robot** capability and click **Add**:
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-add-bot.png" width="800"/>
|
|
||||||
|
|
||||||
3. Configure the robot information and click **Publish**. After publishing, click "**Debug**" to automatically create a test group chat, which can be viewed in the client:
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-config-bot.png" width="600"/>
|
|
||||||
|
|
||||||
4. Click **Version Management & Release**, create a new version and publish:
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-publish-bot.png" width="700"/>
|
|
||||||
|
|
||||||
## 2. Project Configuration
|
|
||||||
|
|
||||||
1. Click **Credentials & Basic Info**, get the `Client ID` and `Client Secret`:
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-get-secret.png" width="700"/>
|
|
||||||
|
|
||||||
2. Add the following configuration to `config.json` in the project root:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channel_type": "dingtalk",
|
|
||||||
"dingtalk_client_id": "YOUR_CLIENT_ID",
|
|
||||||
"dingtalk_client_secret": "YOUR_CLIENT_SECRET"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Install the dependency:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pip3 install dingtalk_stream
|
|
||||||
```
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-app-config.png" width="700"/>
|
|
||||||
|
|
||||||
4. After starting the project, go to the DingTalk Developer Console, click **Event Subscription**, then click **Connection verified, verify channel**. When "**Connection successful**" is displayed, the configuration is complete:
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-event-sub.png" width="700"/>
|
|
||||||
|
|
||||||
## 3. Usage
|
|
||||||
|
|
||||||
Chat privately with the robot or add it to an enterprise group to start a conversation:
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/dingtalk-hosting-demo.png" width="650"/>
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
---
|
|
||||||
title: Discord
|
|
||||||
description: Integrate CowAgent with a Discord Bot
|
|
||||||
---
|
|
||||||
|
|
||||||
> Integrate CowAgent into Discord via a Discord Bot using the **Gateway** (persistent WebSocket). Supports direct messages (DM) and server channels (triggered by @mention or replying to the bot). The Gateway uses a persistent WebSocket connection — no public IP or callback URL required, works out of the box.
|
|
||||||
|
|
||||||
## 1. Setup
|
|
||||||
|
|
||||||
### Step 1: Create a Discord Application and Bot
|
|
||||||
|
|
||||||
1. Open the [Discord Developer Portal](https://discord.com/developers/applications), click **New Application**, enter a name (e.g. `CowAgent`), and create it.
|
|
||||||
2. Go to the **Bot** page in the left sidebar, click **Reset Token** to generate a Bot Token, then copy and store it safely (shown only once).
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
This token is your bot's password — keep it secret. If it leaks, click **Reset Token** again on the Bot page to regenerate it.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
### Step 2: Enable the Message Content Intent
|
|
||||||
|
|
||||||
Reading message text in both DMs and channels depends on this privileged intent.
|
|
||||||
|
|
||||||
1. On the **Bot** page, find **Privileged Gateway Intents**.
|
|
||||||
2. Turn on **Message Content Intent** and save.
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
Without this intent enabled, incoming message content will be empty and the bot will not respond.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
### Step 3: Invite the Bot to a Server
|
|
||||||
|
|
||||||
1. Go to **OAuth2 → URL Generator** in the left sidebar.
|
|
||||||
2. Under **Scopes**, check `bot`.
|
|
||||||
3. Under **Bot Permissions**, check at least: `Send Messages`, `Read Message History`, `Attach Files`, `View Channels`.
|
|
||||||
4. Copy the generated authorization URL at the bottom, open it in a browser, and authorize it for your target server.
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
You can skip this step if you only need DMs, but you still need a DM channel with the bot (e.g. the user messages the bot directly).
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
### Step 4: Connect to CowAgent
|
|
||||||
|
|
||||||
<Tabs>
|
|
||||||
<Tab title="Web Console (Recommended)">
|
|
||||||
Open the Web Console (default `http://127.0.0.1:9899`), go to **Channels**, click **Add Channel**, choose **Discord**, paste the Bot Token, and click connect.
|
|
||||||
</Tab>
|
|
||||||
<Tab title="Config File">
|
|
||||||
Add the following to `config.json` and start Cow:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channel_type": "discord",
|
|
||||||
"discord_token": "your-discord-bot-token",
|
|
||||||
"discord_group_trigger": "mention_or_reply"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Key | Description | Default |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `discord_token` | Bot Token generated on the Bot page of the Developer Portal | - |
|
|
||||||
| `discord_group_trigger` | Channel trigger: `mention_or_reply` (@ or reply to bot) / `mention_only` (@ only) / `all` (all messages) | `mention_or_reply` |
|
|
||||||
</Tab>
|
|
||||||
</Tabs>
|
|
||||||
|
|
||||||
The integration is ready when you see logs like:
|
|
||||||
|
|
||||||
```
|
|
||||||
[Discord] Bot logged in as CowAgent#1234 (id=123456789)
|
|
||||||
[Discord] ✅ Discord bot ready, listening for messages
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Capabilities
|
|
||||||
|
|
||||||
| Feature | Support |
|
|
||||||
| --- | --- |
|
|
||||||
| Direct message (DM) | ✅ |
|
|
||||||
| Server channel (@bot / reply to bot) | ✅ |
|
|
||||||
| Text messages | ✅ send / receive |
|
|
||||||
| Image messages | ✅ send / receive |
|
|
||||||
| File messages | ✅ send / receive (PDF / Word / Excel, etc.) |
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
A single Discord message is capped at 2000 characters; long replies are automatically split across multiple messages by line breaks.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## 3. Usage
|
|
||||||
|
|
||||||
Once connected:
|
|
||||||
|
|
||||||
- **Direct message (DM)**: find your bot in the server member list, click its avatar, and message it directly.
|
|
||||||
- **Channel**: in a channel where the bot is invited, trigger it with `@your-bot hello` or by **replying to one of the bot's messages**.
|
|
||||||
|
|
||||||
When sending an image or file, you can **add a text caption** (description / question) in the attachment input — the bot will answer based on both. Sending an attachment first and then a follow-up question also works; the two messages are merged automatically.
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
---
|
|
||||||
title: Feishu (Lark)
|
|
||||||
description: Integrate CowAgent into Feishu via a custom enterprise app
|
|
||||||
---
|
|
||||||
|
|
||||||
> Integrate CowAgent into Feishu via a custom enterprise app. Supports p2p chat and group chat (@bot), uses WebSocket long connection (no public IP needed), supports streaming typewriter replies and voice messages.
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
You need to be a Feishu enterprise user with admin privileges.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## 1. Setup
|
|
||||||
|
|
||||||
### Option 1: One-click Scan to Create (Recommended)
|
|
||||||
|
|
||||||
No need to manually create an app on the Feishu Developer Platform. Start the Cow project, open the web console (default `http://127.0.0.1:9899/`), go to **Channels**, click **Add Channel**, choose **Feishu**, then under the **Scan QR** tab click **One-click Create Feishu App** and scan with the **Feishu App** to complete app creation and connection automatically.
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260505181126.png" width="800"/>
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
1. Requires `lark-oapi` ≥ 1.5.5.
|
|
||||||
2. The created app comes with all required permissions (messaging, card read/write, group events, etc.) and event subscriptions pre-configured — no manual setup on the developer console needed. Currently only the Feishu mainland version is supported (Lark international not yet supported).
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
When starting from CLI without `feishu_app_id` configured, the QR code is also printed to the terminal.
|
|
||||||
|
|
||||||
### Option 2: Manual Setup
|
|
||||||
|
|
||||||
Manually create a custom app on the Feishu Developer Platform, then connect via Web Console or config file.
|
|
||||||
|
|
||||||
**Step 1: Create the App**
|
|
||||||
|
|
||||||
1. Go to [Feishu Developer Platform](https://open.feishu.cn/app/), click **Create Enterprise Custom App**:
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/feishu-hosting-create-app.jpg" width="500"/>
|
|
||||||
|
|
||||||
2. In **Add App Capabilities**, add the **Bot** capability:
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/feishu-hosting-add-bot.jpg" width="800"/>
|
|
||||||
|
|
||||||
3. In **Permission Management**, paste the following permissions and **Batch Enable** all:
|
|
||||||
|
|
||||||
```
|
|
||||||
im:message,im:message.group_at_msg,im:message.group_at_msg:readonly,im:message.p2p_msg,im:message.p2p_msg:readonly,im:message:send_as_bot,im:resource,cardkit:card:write
|
|
||||||
```
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/feishu-hosting-add-auth2.png" width="800"/>
|
|
||||||
|
|
||||||
4. Get `App ID` and `App Secret` from **Credentials & Basic Info**:
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/feishu-hosting-appid-secret.jpg" width="800"/>
|
|
||||||
|
|
||||||
**Step 2: Connect to CowAgent**
|
|
||||||
|
|
||||||
<Tabs>
|
|
||||||
<Tab title="Web Console">
|
|
||||||
Open the web console, go to **Channels**, click **Add Channel**, choose **Feishu**, switch to the **Manual** tab, enter App ID and App Secret, then click connect.
|
|
||||||
</Tab>
|
|
||||||
<Tab title="Config File">
|
|
||||||
Add the following to `config.json` and start the program:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channel_type": "feishu",
|
|
||||||
"feishu_app_id": "YOUR_APP_ID",
|
|
||||||
"feishu_app_secret": "YOUR_APP_SECRET",
|
|
||||||
"feishu_stream_reply": true
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description | Default |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `feishu_app_id` | Feishu app App ID | - |
|
|
||||||
| `feishu_app_secret` | Feishu app App Secret | - |
|
|
||||||
| `feishu_stream_reply` | Enable streaming typewriter reply | `true` |
|
|
||||||
</Tab>
|
|
||||||
</Tabs>
|
|
||||||
|
|
||||||
**Step 3: Publish the App**
|
|
||||||
|
|
||||||
1. After Cow is running, go to **Events & Callbacks** in the Feishu Developer Platform, choose **Long Connection** mode and save:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/202601311731183.png" width="600"/>
|
|
||||||
|
|
||||||
2. Click **Add Event**, search for "Receive Message" and choose **Receive Message v2.0**.
|
|
||||||
|
|
||||||
3. Click **Version Management & Release**, create a version and apply for **Production Release**. Approve the request in the Feishu client:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/202601311807356.png" width="600"/>
|
|
||||||
|
|
||||||
## 2. Features
|
|
||||||
|
|
||||||
| Feature | Status |
|
|
||||||
| --- | --- |
|
|
||||||
| P2P chat | ✅ |
|
|
||||||
| Group chat (@bot) | ✅ |
|
|
||||||
| Text messages | ✅ send/receive |
|
|
||||||
| Image messages | ✅ send/receive |
|
|
||||||
| Voice messages | ✅ send/receive |
|
|
||||||
| Streaming reply | ✅ (powered by Feishu cardkit streaming card) |
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
Streaming reply requires the `cardkit:card:write` permission (already enabled by one-click creation) and Feishu client version ≥ 7.20. Older clients see an upgrade prompt; if the permission or version is not satisfied, replies fall back to plain text automatically.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## 3. Usage
|
|
||||||
|
|
||||||
After connection, search for the bot name in Feishu to start a chat.
|
|
||||||
|
|
||||||
To use in groups, add the bot to a group and @-mention it.
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
---
|
|
||||||
title: Channels Overview
|
|
||||||
description: Channels supported by CowAgent and their capability matrix
|
|
||||||
---
|
|
||||||
|
|
||||||
CowAgent supports multiple chat channels. Switch between them at startup via `channel_type`. The Web Console is enabled by default and can run in parallel with other channels.
|
|
||||||
|
|
||||||
## Capability Matrix
|
|
||||||
|
|
||||||
The table below summarizes the inbound message types, bot reply types, and group chat capabilities supported by each channel, making it easy to choose by scenario.
|
|
||||||
|
|
||||||
| Channel | Text | Image | File | Voice | Group Chat |
|
|
||||||
| --- | :-: | :-: | :-: | :-: | :-: |
|
|
||||||
| [WeChat](/en/channels/weixin) | ✅ | ✅ | ✅ | ✅ | |
|
|
||||||
| [Web Console](/en/channels/web) | ✅ | ✅ | ✅ | ✅ | |
|
|
||||||
| [Feishu](/en/channels/feishu) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
||||||
| [DingTalk](/en/channels/dingtalk) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
||||||
| [WeCom Bot](/en/channels/wecom-bot) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
||||||
| [QQ](/en/channels/qq) | ✅ | ✅ | ✅ | | ✅ |
|
|
||||||
| [WeCom App](/en/channels/wecom) | ✅ | ✅ | ✅ | ✅ | |
|
|
||||||
| [Official Account](/en/channels/wechatmp) | ✅ | ✅ | | ✅ | |
|
|
||||||
| [Telegram](/en/channels/telegram) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
||||||
| [Slack](/en/channels/slack) | ✅ | ✅ | ✅ | | ✅ |
|
|
||||||
| [Discord](/en/channels/discord) | ✅ | ✅ | ✅ | | ✅ |
|
|
||||||
|
|
||||||
- The **Image / File / Voice** columns indicate that the channel can send and receive the corresponding message types; see each channel's docs for details
|
|
||||||
- The **Group Chat** column indicates the ability to recognize and respond to group messages
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
The voice / image capabilities of each channel depend on the configuration of the corresponding model provider. See [Models Overview](/en/models/index) for details.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## Channel List
|
|
||||||
|
|
||||||
- [Web Console](/en/channels/web) — built-in browser-based chat and management panel, enabled by default
|
|
||||||
- [WeChat](/en/channels/weixin) — log in via personal WeChat QR scan
|
|
||||||
- [Feishu](/en/channels/feishu) — Feishu custom bot
|
|
||||||
- [DingTalk](/en/channels/dingtalk) — DingTalk custom bot
|
|
||||||
- [WeCom Bot](/en/channels/wecom-bot) — WeCom AI Bot via WebSocket long connection
|
|
||||||
- [QQ](/en/channels/qq) — QQ Official Bot open platform
|
|
||||||
- [WeCom App](/en/channels/wecom) — WeCom custom app integration
|
|
||||||
- [Official Account](/en/channels/wechatmp) — WeChat Official Account (subscription / service)
|
|
||||||
- [Telegram](/en/channels/telegram) — global IM, 5-minute setup, no public IP needed
|
|
||||||
- [Slack](/en/channels/slack) — team collaboration IM, Socket Mode integration, no public IP needed
|
|
||||||
- [Discord](/en/channels/discord) — community IM, Gateway connection, no public IP needed
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
---
|
|
||||||
title: QQ Bot
|
|
||||||
description: Connect CowAgent to QQ Bot (WebSocket long connection)
|
|
||||||
---
|
|
||||||
|
|
||||||
> Connect CowAgent via QQ Open Platform's bot API, supporting QQ direct messages, group chats (@bot), guild channel messages, and guild DMs. No public IP required — uses WebSocket long connection.
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
QQ Bot is created through the QQ Open Platform. It uses WebSocket long connection to receive messages and OpenAPI to send messages. No public IP or domain is required.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## 1. Create a QQ Bot
|
|
||||||
|
|
||||||
> Visit the [QQ Open Platform](https://q.qq.com), sign in with QQ. If you haven't registered, please complete [account registration](https://q.qq.com/#/register) first.
|
|
||||||
|
|
||||||
1.Go to the [QQ Open Platform - Bot List](https://q.qq.com/#/apps), and click **Create Bot**:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260317162900.png" width="800"/>
|
|
||||||
|
|
||||||
2.Fill in the bot name, avatar, and other basic information to complete the creation:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260317163005.png" width="800"/>
|
|
||||||
|
|
||||||
3.Enter the bot configuration page, go to **Development Management**, and complete the following steps:
|
|
||||||
|
|
||||||
- Copy and save the **AppID** (Bot ID)
|
|
||||||
- Generate and save the **AppSecret** (Bot Secret)
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260317164955.png" width="800"/>
|
|
||||||
|
|
||||||
## 2. Configuration and Running
|
|
||||||
|
|
||||||
### Option A: Web Console
|
|
||||||
|
|
||||||
Start the program and open the Web console (local access: http://127.0.0.1:9899/). Go to the **Channels** tab, click **Connect Channel**, select **QQ Bot**, fill in the AppID and AppSecret from the previous step, and click Connect.
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260317165425.png" width="800"/>
|
|
||||||
|
|
||||||
### Option B: Config File
|
|
||||||
|
|
||||||
Add the following to your `config.json`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channel_type": "qq",
|
|
||||||
"qq_app_id": "YOUR_APP_ID",
|
|
||||||
"qq_app_secret": "YOUR_APP_SECRET"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `qq_app_id` | AppID of the QQ Bot, found in Development Management on the open platform |
|
|
||||||
| `qq_app_secret` | AppSecret of the QQ Bot, found in Development Management on the open platform |
|
|
||||||
|
|
||||||
After configuration, start the program. The log message `[QQ] ✅ Connected successfully` indicates a successful connection.
|
|
||||||
|
|
||||||
|
|
||||||
## 3. Usage
|
|
||||||
|
|
||||||
In the QQ Open Platform, go to **Management → Usage Scope & Members**, scan the "Add to group and message list" QR code with your QQ client to start chatting with the bot:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260317165947.png" width="800"/>
|
|
||||||
|
|
||||||
Chat example:
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260317171508.png" width="800"/>
|
|
||||||
|
|
||||||
## 4. Supported Features
|
|
||||||
|
|
||||||
> Note: To use the QQ bot in group chats and guild channels, you need to complete the publishing review and configure usage scope permissions.
|
|
||||||
|
|
||||||
| Feature | Status |
|
|
||||||
| --- | --- |
|
|
||||||
| QQ Direct Messages | ✅ |
|
|
||||||
| QQ Group Chat (@bot) | ✅ |
|
|
||||||
| Guild Channel (@bot) | ✅ |
|
|
||||||
| Guild DM | ✅ |
|
|
||||||
| Text Messages | ✅ Send & Receive |
|
|
||||||
| Image Messages | ✅ Send & Receive (group & direct) |
|
|
||||||
| File Messages | ✅ Send (group & direct) |
|
|
||||||
| Scheduled Tasks | ✅ Active push (4 per user per month) |
|
|
||||||
|
|
||||||
|
|
||||||
## 5. Notes
|
|
||||||
|
|
||||||
- **Passive message limits**: QQ direct message replies are valid for 60 minutes (max 5 replies per message); group chat replies are valid for 5 minutes.
|
|
||||||
- **Active message limits**: Both direct and group chats have a monthly limit of 4 active messages. Keep this in mind when using the scheduled tasks feature.
|
|
||||||
- **Event permissions**: By default, `GROUP_AND_C2C_EVENT` (QQ group/direct) and `PUBLIC_GUILD_MESSAGES` (guild public messages) are subscribed. Apply for additional permissions on the open platform if needed.
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
---
|
|
||||||
title: Slack
|
|
||||||
description: Integrate CowAgent with a Slack App
|
|
||||||
---
|
|
||||||
|
|
||||||
> Integrate CowAgent into Slack via a Slack App in **Socket Mode**. Supports direct messages (DM) and channels (triggered by @mention or replying within a thread). Socket Mode uses a persistent WebSocket connection — no public IP or callback URL required, works out of the box.
|
|
||||||
|
|
||||||
## 1. Setup
|
|
||||||
|
|
||||||
### Step 1: Create a Slack App
|
|
||||||
|
|
||||||
1. Open the [Slack API apps page](https://api.slack.com/apps), click **Create New App** → **From scratch**.
|
|
||||||
2. Enter an **App Name** (e.g. `CowAgent`), pick the **Workspace** to install into, and create it.
|
|
||||||
|
|
||||||
### Step 2: Enable Socket Mode and get the App Token
|
|
||||||
|
|
||||||
1. In the left sidebar go to **Settings → Socket Mode** and turn on **Enable Socket Mode**.
|
|
||||||
2. You will be prompted to generate an **App-Level Token** with the `connections:write` scope. Save this token starting with `xapp-`.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
Socket Mode receives events over a WebSocket connection, so you don't need to expose a public callback URL — ideal for local or intranet deployments.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
### Step 3: Configure bot scopes and install
|
|
||||||
|
|
||||||
1. Go to **Features → OAuth & Permissions**, click **Add an OAuth Scope** under **Bot Token Scopes**, and add the following scopes one by one:
|
|
||||||
|
|
||||||
```
|
|
||||||
app_mentions:read
|
|
||||||
channels:history
|
|
||||||
chat:write
|
|
||||||
commands
|
|
||||||
files:read
|
|
||||||
files:write
|
|
||||||
groups:history
|
|
||||||
im:history
|
|
||||||
mpim:history
|
|
||||||
users:read
|
|
||||||
```
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
`files:read` / `files:write` are used for sending/receiving images and files; omit them if you only need text conversations.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
2. Go to **Features → Event Subscriptions**, turn on **Enable Events**, and under **Subscribe to bot events** click **Add Bot User Event** to add:
|
|
||||||
|
|
||||||
```
|
|
||||||
app_mention
|
|
||||||
message.im
|
|
||||||
message.channels
|
|
||||||
```
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
Add `message.groups` if you need to use the bot in private channels.
|
|
||||||
</Note>
|
|
||||||
3. Go to **Features → App Home**, enable **Messages Tab** under **Show Tabs**, and check **Allow users to send Slash commands and messages from the messages tab**. Otherwise the DM input box is disabled and users cannot message the bot.
|
|
||||||
4. Back in **OAuth & Permissions**, click **Install to Workspace**. After installing, copy the **Bot User OAuth Token** starting with `xoxb-`.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
If the Slack client still shows "Sending messages to this app has been turned off", make sure you completed the App Home step above, then refresh or restart the Slack client (remove the app from your conversations and reopen it if needed).
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
### Step 4: Connect to CowAgent
|
|
||||||
|
|
||||||
<Tabs>
|
|
||||||
<Tab title="Web Console (Recommended)">
|
|
||||||
Open the Web Console (default `http://127.0.0.1:9899`), go to **Channels**, click **Add Channel**, choose **Slack**, paste the Bot Token (`xoxb-`) and App Token (`xapp-`), and click connect.
|
|
||||||
</Tab>
|
|
||||||
<Tab title="Config File">
|
|
||||||
Add the following to `config.json` and start Cow:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channel_type": "slack",
|
|
||||||
"slack_bot_token": "xoxb-xxxxxxxxxxxx",
|
|
||||||
"slack_app_token": "xapp-xxxxxxxxxxxx",
|
|
||||||
"slack_group_trigger": "mention_or_reply"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Key | Description | Default |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `slack_bot_token` | Bot User OAuth Token, like `xoxb-...` | - |
|
|
||||||
| `slack_app_token` | App-Level Token (generated after enabling Socket Mode), like `xapp-...` | - |
|
|
||||||
| `slack_group_trigger` | Channel trigger: `mention_or_reply` (@ or reply in thread) / `mention_only` (@ only) / `all` (all messages) | `mention_or_reply` |
|
|
||||||
</Tab>
|
|
||||||
</Tabs>
|
|
||||||
|
|
||||||
The integration is ready when you see logs like:
|
|
||||||
|
|
||||||
```
|
|
||||||
[Slack] Bot logged in as user_id=U0XXXXXXX, team=Txxxxxxxx
|
|
||||||
[Slack] ✅ Slack bot ready, listening for events
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Capabilities
|
|
||||||
|
|
||||||
| Feature | Support |
|
|
||||||
| --- | --- |
|
|
||||||
| Direct message (DM) | ✅ |
|
|
||||||
| Channel (@bot / reply in thread) | ✅ |
|
|
||||||
| Text messages | ✅ send / receive |
|
|
||||||
| Image messages | ✅ send / receive |
|
|
||||||
| File messages | ✅ send / receive (PDF / Word / Excel, etc.) |
|
|
||||||
| Thread replies | ✅ replies are posted to the thread of the triggering message |
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
Slack organizes conversations into threads. The bot posts replies into the thread of the triggering message, keeping channels tidy.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## 3. Usage
|
|
||||||
|
|
||||||
Once connected:
|
|
||||||
|
|
||||||
- **Direct message (DM)**: find your App under **Apps** in the Slack sidebar and message it directly.
|
|
||||||
- **Channel**: invite the App into a channel (`/invite @your-app`), then trigger it with `@your-app hello`; continue the conversation by replying within the same thread.
|
|
||||||
|
|
||||||
When sending an image or file, you can **add a text caption** (description / question) in the attachment input — the bot will answer based on both. Sending an attachment first and then a follow-up question also works; the two messages are merged automatically.
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
---
|
|
||||||
title: Telegram
|
|
||||||
description: Integrate CowAgent with Telegram via the Bot API
|
|
||||||
---
|
|
||||||
|
|
||||||
> Integrate CowAgent into Telegram via the official Bot API. Supports private chat and group chat (triggered by @mention or replying to the bot). Uses Long Polling — no public IP required, works out of the box.
|
|
||||||
|
|
||||||
|
|
||||||
## 1. Setup
|
|
||||||
|
|
||||||
### Step 1: Create a Bot via BotFather
|
|
||||||
|
|
||||||
1. Open the official account [@BotFather](https://t.me/BotFather) in Telegram.
|
|
||||||
2. Send `/newbot` and follow the prompts:
|
|
||||||
- **Bot name** (display name, e.g. `My CowAgent Bot`)
|
|
||||||
- **Bot username** (must end with `bot`, e.g. `my_cowagent_bot`)
|
|
||||||
3. Once created, BotFather returns an **HTTP API Token** (e.g. `123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ`). Keep it safe.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
The token is the password of your bot — never share it. If it leaks, send `/revoke` to `@BotFather` to reset it.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
### Step 2: (Group chat only) Disable Privacy Mode
|
|
||||||
|
|
||||||
Skip this step if you only use private chat. Telegram bots run in **Privacy Mode** by default — in groups they can only see commands suffixed with `@bot` (e.g. `/start@your_bot`) and replies to bot messages; **plain `@bot hello` text messages are not delivered**, so the bot will appear unresponsive in groups.
|
|
||||||
|
|
||||||
Send the following to `@BotFather`:
|
|
||||||
|
|
||||||
1. `/setprivacy`
|
|
||||||
2. Pick the bot you just created
|
|
||||||
3. Choose `Disable`
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
If the bot is still silent in groups after this, try removing it from the group and adding it back.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
### Step 3: Connect to CowAgent
|
|
||||||
|
|
||||||
<Tabs>
|
|
||||||
<Tab title="Web Console (Recommended)">
|
|
||||||
Open the Web Console (default `http://127.0.0.1:9899`), go to **Channels**, click **Add Channel**, choose **Telegram**, paste the Bot Token, and click connect.
|
|
||||||
</Tab>
|
|
||||||
<Tab title="Config File">
|
|
||||||
Add the following to `config.json` and start Cow:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channel_type": "telegram",
|
|
||||||
"telegram_token": "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ",
|
|
||||||
"telegram_group_trigger": "mention_or_reply"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Key | Description | Default |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `telegram_token` | HTTP API Token returned by BotFather | - |
|
|
||||||
| `telegram_group_trigger` | Group trigger: `mention_or_reply` (@ or reply) / `mention_only` (@ only) / `all` (all messages) | `mention_or_reply` |
|
|
||||||
| `telegram_register_commands` | Whether to register the command menu with BotFather on startup | `true` |
|
|
||||||
</Tab>
|
|
||||||
</Tabs>
|
|
||||||
|
|
||||||
The integration is ready when you see logs like:
|
|
||||||
|
|
||||||
```
|
|
||||||
[Telegram] Bot logged in as @my_cowagent_bot (id=123456789)
|
|
||||||
[Telegram] Registered 10 bot commands
|
|
||||||
[Telegram] ✅ Telegram bot ready, polling for updates
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Capabilities
|
|
||||||
|
|
||||||
| Feature | Support |
|
|
||||||
| --- | --- |
|
|
||||||
| Private chat | ✅ |
|
|
||||||
| Group chat (@bot / reply to bot) | ✅ |
|
|
||||||
| Text messages | ✅ send / receive |
|
|
||||||
| Image messages | ✅ send / receive |
|
|
||||||
| Voice messages | ✅ send / receive (OGG/Opus) |
|
|
||||||
| Video messages | ✅ send / receive |
|
|
||||||
| File messages | ✅ send / receive (PDF / Word / Excel, etc.) |
|
|
||||||
| Command menu | ✅ aligned with Web Console slash commands |
|
|
||||||
|
|
||||||
### Command Menu
|
|
||||||
|
|
||||||
On startup, the channel registers a command menu with BotFather. Typing `/` in Telegram shows a dropdown:
|
|
||||||
|
|
||||||
| Command | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `/help` | Show command help |
|
|
||||||
| `/status` | View runtime status |
|
|
||||||
| `/context` | View conversation context (`/context clear` to clear) |
|
|
||||||
| `/skill` | Skill management (`/skill list`, `/skill install`, ...) |
|
|
||||||
| `/memory` | Memory management (`/memory dream`) |
|
|
||||||
| `/knowledge` | Knowledge base (`/knowledge list` / `on` / `off`) |
|
|
||||||
| `/config` | View current config |
|
|
||||||
| `/cancel` | Cancel the running Agent task |
|
|
||||||
| `/logs` | View recent logs |
|
|
||||||
| `/version` | Show version |
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
Telegram's command menu only displays top-level commands; subcommands are entered with a space, e.g. `/skill list`, `/context clear`.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## 3. Usage
|
|
||||||
|
|
||||||
Once connected:
|
|
||||||
|
|
||||||
- **Private chat**: search for your bot username (e.g. `@my_cowagent_bot`) in Telegram, click `Start` and chat away.
|
|
||||||
- **Group chat**: add the bot to a group, then trigger it with `@bot hello` or by **replying to one of the bot's messages**. If the bot doesn't respond in groups, double-check Privacy Mode in [Step 2](#step-2-group-chat-only-disable-privacy-mode).
|
|
||||||
|
|
||||||
When sending an image or file, you can **add a caption** (description / question) directly in the attachment input — the bot will answer based on both. Sending an attachment first and then a follow-up question also works; the two messages are merged automatically.
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
---
|
|
||||||
title: Web Console
|
|
||||||
description: Use CowAgent through the Web Console
|
|
||||||
---
|
|
||||||
|
|
||||||
The Web Console is CowAgent's default channel. It runs automatically once started, letting you chat with the Agent in a browser and manage models, skills, memory, channels, and other configuration online.
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channel_type": "web",
|
|
||||||
"web_host": "0.0.0.0",
|
|
||||||
"web_port": 9899,
|
|
||||||
"web_password": "",
|
|
||||||
"enable_thinking": false
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description | Default |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `channel_type` | Set to `web` | `web` |
|
|
||||||
| `web_host` | Web service listen address. Defaults to `127.0.0.1` (local only); set to `0.0.0.0` for public access and configure a password | `""` |
|
|
||||||
| `web_port` | Web service listen port | `9899` |
|
|
||||||
| `web_password` | Access password. Leave empty to disable password protection; recommended when listening on `0.0.0.0` | `""` |
|
|
||||||
| `web_session_expire_days` | Login session validity in days | `30` |
|
|
||||||
| `web_file_serve_root` | Root directory the web console can directly read/send files from. Defaults to the user home dir and agent workspace only; set to `/` to allow the whole filesystem | `"~"` |
|
|
||||||
| `enable_thinking` | Whether to enable deep thinking mode | `false` |
|
|
||||||
|
|
||||||
Once a password is configured, you must enter it to log in when accessing the console. The login session is kept for 30 days by default, so restarting the service during that period does not require re-login. The password can also be changed online from the "Configuration" page in the console.
|
|
||||||
|
|
||||||
## Access URL
|
|
||||||
|
|
||||||
After starting the project, visit:
|
|
||||||
|
|
||||||
- Local: `http://localhost:9899`
|
|
||||||
- Server: `http://<server-ip>:9899`
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
Ensure the server firewall and security group allow the corresponding port.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
### Chat Interface
|
|
||||||
|
|
||||||
Supports streaming output with real-time display of the Agent's reasoning process and tool calls, providing intuitive observation of the Agent's decision-making. Deep thinking can be toggled via configuration or the "Agent Configuration" switch in the console.
|
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227180120.png" />
|
|
||||||
|
|
||||||
#### Multi-Session Management
|
|
||||||
|
|
||||||
The chat interface supports multi-session management. All session records are persistently stored in the database:
|
|
||||||
|
|
||||||
- **Session List**: Click the history icon on the left to expand/collapse the session list panel, with scroll-to-load support for all historical sessions
|
|
||||||
- **AI-Generated Titles**: After the first exchange in a new session, the model is automatically called to generate a short summary title
|
|
||||||
- **New Session**: Click the "New Chat" button at the top of the session list or the `+` button in the input area to create a new session
|
|
||||||
- **Delete Session**: Click the delete button on a session item and confirm to permanently delete the session and all its messages
|
|
||||||
- **Clear Context**: Click the clear button in the input area to insert a divider in the current session. Messages above the divider are still displayed but no longer included as context for the model
|
|
||||||
|
|
||||||
### Model Management
|
|
||||||
|
|
||||||
Manage text, image, voice, and embedding model configurations for different providers online — no need to edit config files manually:
|
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260521212949.png" />
|
|
||||||
|
|
||||||
### Skill Management
|
|
||||||
|
|
||||||
View and manage Agent skills (Skills) online:
|
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173403.png" />
|
|
||||||
|
|
||||||
### Memory Management
|
|
||||||
|
|
||||||
View and manage Agent memory online:
|
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173349.png" />
|
|
||||||
|
|
||||||
### Channel Management
|
|
||||||
|
|
||||||
Manage connected channels online with real-time connect/disconnect operations:
|
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173331.png" />
|
|
||||||
|
|
||||||
### Scheduled Tasks
|
|
||||||
|
|
||||||
View and manage scheduled tasks online, including one-time tasks, fixed intervals, and Cron expressions:
|
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173704.png" />
|
|
||||||
|
|
||||||
### Logs
|
|
||||||
|
|
||||||
View Agent runtime logs in real time for monitoring and troubleshooting:
|
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173514.png" />
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
---
|
|
||||||
title: WeCom Customer Service
|
|
||||||
description: Integrate CowAgent into WeCom Customer Service (微信客服)
|
|
||||||
---
|
|
||||||
|
|
||||||
By binding a WeCom custom enterprise app to a WeCom Customer Service (微信客服) account, CowAgent can take over inbound inquiries from external WeChat users and serve them through links or QR codes embedded in WeChat Mini Programs, Official Accounts, Video Channels, and Video Channel stores.
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
WeCom Customer Service only supports Docker deployment or server Python deployment. A publicly reachable callback URL is required; local run mode is not supported.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## 1. Prerequisites
|
|
||||||
|
|
||||||
Required resources:
|
|
||||||
|
|
||||||
1. A server with a public IP
|
|
||||||
2. A registered and verified WeCom account
|
|
||||||
3. WeCom Customer Service capability enabled
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
It is recommended to create a **dedicated** WeCom custom app for Customer Service rather than reusing the existing `wechatcom_app` one — otherwise the two channels will compete for the same callback URL.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## 2. Create a WeCom Custom App
|
|
||||||
|
|
||||||
1. In the [WeCom Admin Console](https://work.weixin.qq.com/wework_admin/frame#apps), go to **Application Management → Create Application**:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103156.png" width="480"/>
|
|
||||||
|
|
||||||
2. Click **My Enterprise** and find the **Corp ID** at the bottom of the page (it goes into `wechat_kf_corp_id`):
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/wechatcom-hosting-companyid.png" width="600"/>
|
|
||||||
|
|
||||||
3. Open the app you just created and click **"View"** next to Secret. The Secret will be pushed to the admin's phone via the WeCom app, where it can be viewed:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/wechatcom-hosting-agent-secret.png" width="600"/>
|
|
||||||
|
|
||||||
4. Open the app's **Receive Messages → Set API Reception** page, click **"Random Generate"** to generate the **Token** and **EncodingAESKey**, and save them:
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/wechatcom-hosting-token-aeskey.jpg" width="600"/>
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
Saving the API reception configuration will fail at this point because the program has not started yet. Come back to save it after the project is running.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## 3. Configuration and Run
|
|
||||||
|
|
||||||
Fill in the 4 fields collected from the previous step (Corp ID / Secret / Token / EncodingAESKey):
|
|
||||||
|
|
||||||
<Tabs>
|
|
||||||
<Tab title="Web Console">
|
|
||||||
Start the Cow project and open the Web Console. Go to the **Channels** menu, click **Connect**, choose **WeCom Customer Service**, fill in Corp ID / Secret / Token / AES Key (port defaults to 9888, configurable), and click Connect.
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/cow-weixinkefu-web-control.png" width="800"/>
|
|
||||||
</Tab>
|
|
||||||
<Tab title="Config File">
|
|
||||||
Add the following configuration to `config.json` (each parameter maps to a field shown in the screenshots above):
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channel_type": "wechat_kf",
|
|
||||||
"wechat_kf_corp_id": "YOUR_CORP_ID",
|
|
||||||
"wechat_kf_secret": "YOUR_SECRET",
|
|
||||||
"wechat_kf_token": "YOUR_TOKEN",
|
|
||||||
"wechat_kf_aes_key": "YOUR_AES_KEY",
|
|
||||||
"wechat_kf_port": 9888
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `wechat_kf_corp_id` | Corp ID |
|
|
||||||
| `wechat_kf_secret` | Secret of the WeCom custom app bound to Customer Service |
|
|
||||||
| `wechat_kf_token` | Token from the API reception config |
|
|
||||||
| `wechat_kf_aes_key` | EncodingAESKey from the API reception config |
|
|
||||||
| `wechat_kf_port` | Listening port, default 9888 |
|
|
||||||
</Tab>
|
|
||||||
</Tabs>
|
|
||||||
|
|
||||||
After connecting, start the program (the Web Console method restarts the channel automatically). When the log shows `Listening on http://0.0.0.0:9888/wxkf/`, the program is running successfully. You need to open this port externally (e.g., allow it in the cloud server security group).
|
|
||||||
|
|
||||||
Then go back to **Receive Messages → Set API Reception** in the WeCom console and set the callback URL to `http://<your-host>:9888/wxkf/`, then click Save. After saving successfully, you also need to add the server IP to **Enterprise Trusted IPs**, otherwise messages cannot be sent or received:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/wechat-com_config.png" width="600"/>
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103224.png" width="520"/>
|
|
||||||
|
|
||||||
<Warning>
|
|
||||||
If URL verification fails or the configuration is unsuccessful:
|
|
||||||
1. Ensure the server firewall is disabled and the security group allows the listening port (default 9888)
|
|
||||||
2. Carefully check that Token, Secret, EncodingAESKey and other parameters are consistent, and the URL format is correct
|
|
||||||
3. Verified WeCom accounts must use a filed domain matching the entity
|
|
||||||
</Warning>
|
|
||||||
|
|
||||||
## 4. Bind a WeCom Customer Service Account
|
|
||||||
|
|
||||||
In the WeCom Admin Console, go to **WeCom Customer Service**, create a customer service account, and bind it to the custom app you created above:
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/wxcustomer-hosting-step1.jpg" width="600"/>
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/wxcustomer-hosting-step2.jpg" width="600"/>
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/wxcustomer-hosting-step3.jpg" width="600"/>
|
|
||||||
|
|
||||||
After binding, go to **WeCom Customer Service → Account Details**, and under **"Access Link"**:
|
|
||||||
|
|
||||||
- Click **"Copy Link"** to get an access link like `https://work.weixin.qq.com/kfid/kfcd83e5896b9ba07be`
|
|
||||||
- Click **"Generate QR Code"** to get the corresponding QR code
|
|
||||||
|
|
||||||
Distribute the link or QR code to your WeChat customers:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/wechat-customer-service_use.png" width="600"/>
|
|
||||||
|
|
||||||
## 5. Usage
|
|
||||||
|
|
||||||
After WeChat users enter the customer service conversation via the link or QR code, they can chat with the AI across multiple turns, with support for text, image, and voice messages:
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/wxcustomer-hosting-chat-demo.jpg" width="900"/>
|
|
||||||
|
|
||||||
Beyond that, leveraging the official WeChat ecosystem, WeCom Customer Service can also be embedded into Official Accounts, Mini Programs, Video Channels and more. See the **WeCom Customer Service → Access Scenarios** section in the [WeCom Admin Console](https://work.weixin.qq.com/wework_admin/frame#/app/servicer) for details:
|
|
||||||
|
|
||||||
<img src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/wxcustomer-hosting-interface-demo.png" width="800"/>
|
|
||||||
|
|
||||||
## FAQ
|
|
||||||
|
|
||||||
Make sure the following dependencies are installed:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pip install websocket-client pycryptodome
|
|
||||||
```
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
---
|
|
||||||
title: WeChat Official Account
|
|
||||||
description: Integrate CowAgent with WeChat Official Accounts
|
|
||||||
---
|
|
||||||
|
|
||||||
CowAgent supports both personal subscription accounts and enterprise service accounts.
|
|
||||||
|
|
||||||
| Type | Requirements | Features |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| **Personal Subscription** | Available to individuals | Sends a placeholder reply first; users must send a message to retrieve the full response |
|
|
||||||
| **Enterprise Service** | Enterprise with verified customer service API | Can proactively push replies to users |
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
Official Accounts only support server and Docker deployment, not local run mode. Install extended dependencies: `pip3 install -r requirements-optional.txt`
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## 1. Personal Subscription Account
|
|
||||||
|
|
||||||
Add the following configuration to `config.json`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channel_type": "wechatmp",
|
|
||||||
"single_chat_prefix": [""],
|
|
||||||
"wechatmp_app_id": "wx73f9******d1e48",
|
|
||||||
"wechatmp_app_secret": "YOUR_APP_SECRET",
|
|
||||||
"wechatmp_aes_key": "",
|
|
||||||
"wechatmp_token": "YOUR_TOKEN",
|
|
||||||
"wechatmp_port": 80
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Setup Steps
|
|
||||||
|
|
||||||
These configurations must be consistent with the [WeChat Official Account Platform](https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev). Navigate to **Settings & Development → Basic Configuration → Server Configuration** and configure as shown below:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103506.png" width="480"/>
|
|
||||||
|
|
||||||
1. Enable the developer secret on the platform (corresponds to `wechatmp_app_secret`), and add the server IP to the whitelist
|
|
||||||
2. Fill in the `config.json` with the official account parameters matching the platform configuration
|
|
||||||
3. Start the program, which listens on port 80 (use `sudo` if you don't have permission; stop any process occupying port 80)
|
|
||||||
4. **Enable server configuration** on the official account platform and submit. A successful save means the configuration is complete. Note that the **"Server URL"** must be in the format `http://{HOST}/wx`, where `{HOST}` can be the server IP or domain
|
|
||||||
|
|
||||||
After following the account and sending a message, you should see the following result:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103522.png" width="720"/>
|
|
||||||
|
|
||||||
Due to subscription account limitations, short replies (within 15s) can be returned immediately, but longer replies will first send a "Thinking..." placeholder, requiring users to send any text to retrieve the answer. Enterprise service accounts can solve this with the customer service API.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
**Voice Recognition**: You can use WeChat's built-in voice recognition. Enable "Receive Voice Recognition Results" under "Settings & Development → API Permissions" on the official account management page.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## 2. Enterprise Service Account
|
|
||||||
|
|
||||||
The setup process for enterprise service accounts is essentially the same as personal subscription accounts, with the following differences:
|
|
||||||
|
|
||||||
1. Register an enterprise service account on the platform and complete WeChat certification. Confirm that the **Customer Service API** permission has been granted
|
|
||||||
2. Set `"channel_type": "wechatmp_service"` in `config.json`; other configurations remain the same
|
|
||||||
3. Even for longer replies, they can be proactively pushed to users without requiring manual retrieval
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channel_type": "wechatmp_service",
|
|
||||||
"single_chat_prefix": [""],
|
|
||||||
"wechatmp_app_id": "YOUR_APP_ID",
|
|
||||||
"wechatmp_app_secret": "YOUR_APP_SECRET",
|
|
||||||
"wechatmp_aes_key": "",
|
|
||||||
"wechatmp_token": "YOUR_TOKEN",
|
|
||||||
"wechatmp_port": 80
|
|
||||||
}
|
|
||||||
```
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
---
|
|
||||||
title: WeCom Bot
|
|
||||||
description: Connect CowAgent to WeCom AI Bot (WebSocket long connection)
|
|
||||||
---
|
|
||||||
|
|
||||||
> Connect CowAgent via WeCom AI Bot, supporting both internal direct messages and group chats. No public IP required — uses a WebSocket long connection, with Markdown rendering and streaming output.
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
WeCom Bot and WeCom App are two different integration methods. WeCom Bot uses a WebSocket long connection and requires no public IP or domain, making setup much simpler.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## 1. Connection methods
|
|
||||||
|
|
||||||
### Option A: One-click QR scan (recommended)
|
|
||||||
|
|
||||||
No need to create the bot ahead of time. Start CowAgent and open the Web console (local URL: http://127.0.0.1:9899/), go to the **Channels** tab, click **Connect Channel**, choose **WeCom Bot**, switch to **QR scan** mode, and scan the QR code with **WeCom** — bot creation and connection complete automatically.
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260401121213.png" width="800"/>
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
After a successful scan, you can further configure the bot (name, avatar, visibility scope, etc.) in **WeCom Workbench → AI Bot**.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
### Option B: Manual creation
|
|
||||||
|
|
||||||
Create the AI Bot in WeCom and obtain the Bot ID and Secret, then connect via the Web console or config file.
|
|
||||||
|
|
||||||
**Step 1: Create the AI Bot**
|
|
||||||
|
|
||||||
1. Open the WeCom client, go to **Workbench**, and click **AI Bot**:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260316180959.png" width="800"/>
|
|
||||||
|
|
||||||
2. Click **Create Bot → Manual Creation**:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260316181118.png" width="800"/>
|
|
||||||
|
|
||||||
3. Scroll to the bottom of the right panel and select **API Mode**:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260316181215.png" width="800"/>
|
|
||||||
|
|
||||||
4. Set the bot name, avatar, and visibility scope. Choose **Long Connection** mode, save the **Bot ID** and **Secret**, then click Save.
|
|
||||||
|
|
||||||
**Step 2: Connect to CowAgent**
|
|
||||||
|
|
||||||
<Tabs>
|
|
||||||
<Tab title="Web Console">
|
|
||||||
Open the Web console, go to the **Channels** tab, click **Connect Channel**, choose **WeCom Bot**, switch to **Manual** mode, enter the Bot ID and Secret, and click Connect.
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260316181711.png" width="800"/>
|
|
||||||
</Tab>
|
|
||||||
<Tab title="Config File">
|
|
||||||
Add the following to `config.json`, then start CowAgent:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channel_type": "wecom_bot",
|
|
||||||
"wecom_bot_id": "YOUR_BOT_ID",
|
|
||||||
"wecom_bot_secret": "YOUR_SECRET"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `wecom_bot_id` | Bot ID of the AI Bot |
|
|
||||||
| `wecom_bot_secret` | Secret of the AI Bot |
|
|
||||||
</Tab>
|
|
||||||
</Tabs>
|
|
||||||
|
|
||||||
The log line `[WecomBot] Subscribe success` confirms the connection is established.
|
|
||||||
|
|
||||||
## 2. Supported features
|
|
||||||
|
|
||||||
| Feature | Status |
|
|
||||||
| --- | --- |
|
|
||||||
| Direct chat | ✅ |
|
|
||||||
| Group chat (@bot) | ✅ |
|
|
||||||
| Text messages | ✅ Send / Receive |
|
|
||||||
| Image messages | ✅ Send / Receive |
|
|
||||||
| File messages | ✅ Send / Receive |
|
|
||||||
| Streaming replies | ✅ |
|
|
||||||
| Scheduled push messages | ✅ |
|
|
||||||
|
|
||||||
## 3. Usage
|
|
||||||
|
|
||||||
Search for the bot's name inside WeCom to start a direct chat.
|
|
||||||
|
|
||||||
To use the bot in an internal group chat, add it to the group and @-mention it.
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260316182902.png" width="800"/>
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
---
|
|
||||||
title: WeCom
|
|
||||||
description: Integrate CowAgent into WeCom enterprise app
|
|
||||||
---
|
|
||||||
|
|
||||||
Integrate CowAgent into WeCom through a custom enterprise app, supporting one-on-one chat for internal employees.
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
WeCom only supports Docker deployment or server Python deployment. Local run mode is not supported.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## 1. Prerequisites
|
|
||||||
|
|
||||||
Required resources:
|
|
||||||
|
|
||||||
1. A server with public IP (overseas server, or domestic server with a proxy for international API access)
|
|
||||||
2. A registered WeCom account (individual registration is possible but cannot be certified)
|
|
||||||
3. Certified WeCom accounts additionally require a domain filed under the corresponding entity
|
|
||||||
|
|
||||||
## 2. Create WeCom App
|
|
||||||
|
|
||||||
1. In the [WeCom Admin Console](https://work.weixin.qq.com/wework_admin/frame#profile), click **My Enterprise** and find the **Corp ID** at the bottom of the page. Save this ID for the `wechatcom_corp_id` configuration field.
|
|
||||||
|
|
||||||
2. Switch to **Application Management** and click Create Application:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103156.png" width="480"/>
|
|
||||||
|
|
||||||
3. On the application creation page, record the `AgentId` and `Secret`:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103218.png" width="580"/>
|
|
||||||
|
|
||||||
4. Click **Set API Reception** to configure the application interface:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103211.png" width="520"/>
|
|
||||||
|
|
||||||
- URL format: `http://ip:port/wxcomapp` (certified enterprises must use a filed domain)
|
|
||||||
- Generate random `Token` and `EncodingAESKey` and save them for the configuration file
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
The API reception configuration cannot be saved at this point because the program hasn't started yet. Come back to save it after the project is running.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## 3. Configuration and Run
|
|
||||||
|
|
||||||
Add the following configuration to `config.json` (the mapping between each parameter and the WeCom console is shown in the screenshots above):
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channel_type": "wechatcom_app",
|
|
||||||
"single_chat_prefix": [""],
|
|
||||||
"wechatcom_corp_id": "YOUR_CORP_ID",
|
|
||||||
"wechatcomapp_token": "YOUR_TOKEN",
|
|
||||||
"wechatcomapp_secret": "YOUR_SECRET",
|
|
||||||
"wechatcomapp_agent_id": "YOUR_AGENT_ID",
|
|
||||||
"wechatcomapp_aes_key": "YOUR_AES_KEY",
|
|
||||||
"wechatcomapp_port": 9898
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `wechatcom_corp_id` | Corp ID |
|
|
||||||
| `wechatcomapp_token` | Token from API reception config |
|
|
||||||
| `wechatcomapp_secret` | App Secret |
|
|
||||||
| `wechatcomapp_agent_id` | App AgentId |
|
|
||||||
| `wechatcomapp_aes_key` | EncodingAESKey from API reception config |
|
|
||||||
| `wechatcomapp_port` | Listen port, default 9898 |
|
|
||||||
|
|
||||||
After configuration, start the program. When the log shows `http://0.0.0.0:9898/`, the program is running successfully. You need to open this port externally (e.g., allow it in the cloud server security group).
|
|
||||||
|
|
||||||
After the program starts, return to the WeCom Admin Console to save the **Message Server Configuration**. After saving successfully, you also need to add the server IP to **Enterprise Trusted IPs**, otherwise messages cannot be sent or received:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103224.png" width="520"/>
|
|
||||||
|
|
||||||
<Warning>
|
|
||||||
If the URL configuration callback fails or the configuration is unsuccessful:
|
|
||||||
1. Ensure the server firewall is disabled and the security group allows the listening port
|
|
||||||
2. Carefully check that Token, Secret Key and other parameter configurations are consistent, and that the URL format is correct
|
|
||||||
3. Certified WeCom accounts must configure a filed domain matching the entity
|
|
||||||
</Warning>
|
|
||||||
|
|
||||||
## 4. Usage
|
|
||||||
|
|
||||||
Search for the app name you just created in WeCom to start chatting directly. You can run multiple instances listening on different ports to create multiple WeCom apps:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103228.png" width="720"/>
|
|
||||||
|
|
||||||
To allow external personal WeChat users to use the app, go to **My Enterprise → WeChat Plugin**, share the invite QR code. After scanning and following, personal WeChat users can join and chat with the app:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260228103232.png" width="520"/>
|
|
||||||
|
|
||||||
## FAQ
|
|
||||||
|
|
||||||
Make sure the following dependencies are installed:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pip install websocket-client pycryptodome
|
|
||||||
```
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
---
|
|
||||||
title: WeChat
|
|
||||||
description: Connect CowAgent to personal WeChat (via the official API)
|
|
||||||
---
|
|
||||||
|
|
||||||
> Connect CowAgent to your personal WeChat — scan to log in, no public IP required. Supports text, image, voice, file, and video messages in 1-on-1 chats. Backed by WeChat's official API; safe to use. After connecting, a bot assistant is added to your conversation list without affecting normal account usage.
|
|
||||||
|
|
||||||
## 1. Setup and run
|
|
||||||
|
|
||||||
### Option A: Web console
|
|
||||||
|
|
||||||
Start CowAgent and open the Web console (local URL: http://127.0.0.1:9899/). Go to the **Channels** tab, click **Connect Channel**, select **WeChat**, and follow the prompts to scan in.
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260322195114.png" width="800" />
|
|
||||||
|
|
||||||
### Option B: Config file
|
|
||||||
|
|
||||||
Set `channel_type` to `weixin` in `config.json`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channel_type": "weixin"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
After starting CowAgent, a QR code is displayed in the terminal. Scan it with WeChat to complete login.
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260322195509.png" width="800" />
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
1. For backward compatibility, setting `channel_type` to `wx` also activates the WeChat channel.
|
|
||||||
2. The WeChat client must be on version **8.0.69** or higher.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## 2. Usage
|
|
||||||
|
|
||||||
Once authorized, the integration completes and you can start chatting. A bot assistant is created in your WeChat conversation list, leaving normal account usage unaffected.
|
|
||||||
|
|
||||||
> You can find the bot at any time by searching for **"微信ClawBot"**. You may also rename it, change its avatar, pin it to the top of your conversation list, and so on.
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/83ae8251d896219fde4803f4205205be.jpg" width="250" />
|
|
||||||
|
|
||||||
## 3. Login
|
|
||||||
|
|
||||||
### QR code login
|
|
||||||
|
|
||||||
On first startup, a QR code appears in the terminal (valid for around 2 minutes). Scan it with WeChat and confirm on your phone to log in.
|
|
||||||
|
|
||||||
- The QR code refreshes automatically when it expires
|
|
||||||
- The `qrcode` dependency is already included in `requirements.txt`, so the QR code renders directly in the terminal after install
|
|
||||||
|
|
||||||
### Credential persistence
|
|
||||||
|
|
||||||
After a successful login, credentials are saved to `~/.weixin_cow_credentials.json`. Subsequent startups reuse the saved credentials with no need to re-scan.
|
|
||||||
|
|
||||||
To force a re-login, delete the credentials file and restart.
|
|
||||||
|
|
||||||
### Session expiry
|
|
||||||
|
|
||||||
When the WeChat session expires (errcode `-14`), CowAgent automatically clears old credentials and initiates a new QR login — no manual intervention required.
|
|
||||||
|
|
||||||
## 4. Supported features
|
|
||||||
|
|
||||||
| Feature | Status |
|
|
||||||
| --- | --- |
|
|
||||||
| Direct messages | ✅ |
|
|
||||||
| Text messages | ✅ Send & Receive |
|
|
||||||
| Image messages | ✅ Send & Receive |
|
|
||||||
| File messages | ✅ Send & Receive |
|
|
||||||
| Video messages | ✅ Send & Receive |
|
|
||||||
| Voice messages | ✅ Receive (built-in speech recognition) |
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
---
|
|
||||||
title: General Commands
|
|
||||||
description: View status, manage config, and control context with commonly used commands
|
|
||||||
---
|
|
||||||
|
|
||||||
The following commands can be used in chat with the `/` prefix or in the terminal with the `cow` prefix (some are chat-only).
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
In the Web console, typing `/` brings up an autocomplete menu with keyboard navigation and Tab completion.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## help
|
|
||||||
|
|
||||||
Show help information for all available commands.
|
|
||||||
|
|
||||||
```text
|
|
||||||
/help
|
|
||||||
```
|
|
||||||
|
|
||||||
## status
|
|
||||||
|
|
||||||
View current session and service status, including process info, model configuration, message count, and loaded skills.
|
|
||||||
|
|
||||||
```text
|
|
||||||
/status
|
|
||||||
```
|
|
||||||
|
|
||||||
## cancel
|
|
||||||
|
|
||||||
Abort the agent task currently running in this session. When the agent is busy with a long task (e.g. multi-turn tool calls or a long streaming response), send `/cancel` and the agent will stop before the next tool execution. Available across all channels — Web, WeChat, WeCom, Feishu, etc.
|
|
||||||
|
|
||||||
```text
|
|
||||||
/cancel
|
|
||||||
```
|
|
||||||
|
|
||||||
## config
|
|
||||||
|
|
||||||
View or modify runtime configuration. Changes take effect immediately without restarting.
|
|
||||||
|
|
||||||
**View all configurable items:**
|
|
||||||
|
|
||||||
```text
|
|
||||||
/config
|
|
||||||
```
|
|
||||||
|
|
||||||
**View a single item:**
|
|
||||||
|
|
||||||
```text
|
|
||||||
/config model
|
|
||||||
```
|
|
||||||
|
|
||||||
**Modify a config item:**
|
|
||||||
|
|
||||||
```text
|
|
||||||
/config model deepseek-v4-flash
|
|
||||||
```
|
|
||||||
|
|
||||||
**Configurable items:**
|
|
||||||
|
|
||||||
| Item | Description | Example |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `model` | AI model name | `deepseek-v4-flash` |
|
|
||||||
| `agent_max_context_tokens` | Max context tokens | `40000` |
|
|
||||||
| `agent_max_context_turns` | Max context memory turns | `30` |
|
|
||||||
| `agent_max_steps` | Max decision steps per task | `15` |
|
|
||||||
| `enable_thinking` | Enable deep thinking mode | `true` / `false` |
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
When changing `model`, the system automatically matches the corresponding model API. Configuration is persisted to `config.json`.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## context
|
|
||||||
|
|
||||||
View current session context statistics, including message count and content length.
|
|
||||||
|
|
||||||
```text
|
|
||||||
/context
|
|
||||||
```
|
|
||||||
|
|
||||||
**Clear current session context:**
|
|
||||||
|
|
||||||
```text
|
|
||||||
/context clear
|
|
||||||
```
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
Clearing context makes the Agent "forget" previous conversation, useful for switching topics or freeing context space.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## logs
|
|
||||||
|
|
||||||
View recent service logs. Shows the last 20 lines by default, up to 50.
|
|
||||||
|
|
||||||
```text
|
|
||||||
/logs
|
|
||||||
```
|
|
||||||
|
|
||||||
**Specify line count:**
|
|
||||||
|
|
||||||
```text
|
|
||||||
/logs 50
|
|
||||||
```
|
|
||||||
|
|
||||||
## version
|
|
||||||
|
|
||||||
Show the current CowAgent version.
|
|
||||||
|
|
||||||
```text
|
|
||||||
/version
|
|
||||||
```
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
---
|
|
||||||
title: Commands Overview
|
|
||||||
description: CowAgent command system — Terminal CLI and chat commands
|
|
||||||
---
|
|
||||||
|
|
||||||
CowAgent provides two ways to interact via commands:
|
|
||||||
|
|
||||||
- **Terminal CLI** — Run `cow <command>` in your system terminal for service management, skill management, and other operations
|
|
||||||
- **Chat Commands** — Type `/<command>` or `cow <command>` in any conversation to check status, manage skills, adjust configuration, etc.
|
|
||||||
|
|
||||||
## Cow CLI
|
|
||||||
|
|
||||||
After deploying with the one-click install script, the `cow` command is automatically available. For manual installations, run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pip install -e .
|
|
||||||
```
|
|
||||||
|
|
||||||
Then use the `cow` command from anywhere:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cow help
|
|
||||||
```
|
|
||||||
|
|
||||||
Example output:
|
|
||||||
|
|
||||||
```
|
|
||||||
🐮 CowAgent CLI
|
|
||||||
|
|
||||||
Usage: cow <command>
|
|
||||||
|
|
||||||
Service:
|
|
||||||
start Start the CowAgent service
|
|
||||||
stop Stop the CowAgent service
|
|
||||||
restart Restart the CowAgent service
|
|
||||||
update Update code and restart service
|
|
||||||
status Show service status
|
|
||||||
logs View service logs
|
|
||||||
|
|
||||||
Skills:
|
|
||||||
skill Manage skills (list / search / install / uninstall ...)
|
|
||||||
|
|
||||||
Memory & Knowledge:
|
|
||||||
memory Memory distillation (dream)
|
|
||||||
knowledge View knowledge base stats and structure
|
|
||||||
|
|
||||||
Others:
|
|
||||||
help Show this help message
|
|
||||||
version Show version
|
|
||||||
```
|
|
||||||
|
|
||||||
## Chat Commands
|
|
||||||
|
|
||||||
In the Web console or any connected channel, type `/` to see command suggestions. Supported commands:
|
|
||||||
|
|
||||||
| Command | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `/help` | Show command help |
|
|
||||||
| `/status` | View service status and configuration |
|
|
||||||
| `/cancel` | Abort the currently running agent task |
|
|
||||||
| `/config` | View or modify runtime configuration |
|
|
||||||
| `/skill` | Manage skills (install, uninstall, enable, disable, etc.) |
|
|
||||||
| `/memory dream [N]` | Manually trigger memory distillation (default 3 days, max 30) |
|
|
||||||
| `/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 |
|
|
||||||
| `/version` | Show version number |
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
Service management commands like `/start`, `/stop`, `/restart` will prompt you to use them in the terminal instead, as they involve process operations.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## Command Availability
|
|
||||||
|
|
||||||
| Command | Terminal (`cow`) | Chat (`/`) |
|
|
||||||
| --- | :---: | :---: |
|
|
||||||
| help | ✓ | ✓ |
|
|
||||||
| version | ✓ | ✓ |
|
|
||||||
| status | ✓ | ✓ |
|
|
||||||
| logs | ✓ | ✓ |
|
|
||||||
| cancel | ✗ | ✓ |
|
|
||||||
| config | ✗ | ✓ |
|
|
||||||
| context | — | ✓ |
|
|
||||||
| memory (subcommands) | ✗ | ✓ |
|
|
||||||
| knowledge (subcommands) | ✓ | ✓ |
|
|
||||||
| skill (subcommands) | ✓ | ✓ |
|
|
||||||
| start / stop / restart | ✓ | ✗ |
|
|
||||||
| update | ✓ | ✗ |
|
|
||||||
| install-browser | ✓ | ✗ |
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
`context` only shows a hint in the terminal to use it in chat. `config` is only available in chat.
|
|
||||||
</Note>
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
---
|
|
||||||
title: Memory & Knowledge
|
|
||||||
description: Memory distillation and knowledge base management commands
|
|
||||||
---
|
|
||||||
|
|
||||||
## memory
|
|
||||||
|
|
||||||
Manage the Agent's long-term memory system.
|
|
||||||
|
|
||||||
### memory dream
|
|
||||||
|
|
||||||
Manually trigger memory distillation (Deep Dream) — consolidate recent daily memories into MEMORY.md and generate a dream diary.
|
|
||||||
|
|
||||||
```text
|
|
||||||
/memory dream [N]
|
|
||||||
```
|
|
||||||
|
|
||||||
- `N`: Consolidate the last N days of memory (default 3, max 30)
|
|
||||||
- Runs asynchronously in the background; you'll be notified in chat when complete
|
|
||||||
- Works without Agent initialization — can be used before the first conversation
|
|
||||||
|
|
||||||
**Examples:**
|
|
||||||
|
|
||||||
```text
|
|
||||||
/memory dream # Consolidate last 3 days
|
|
||||||
/memory dream 7 # Consolidate last 7 days
|
|
||||||
/memory dream 30 # Consolidate last 30 days (full)
|
|
||||||
```
|
|
||||||
|
|
||||||
On the Web console, the completion notification includes clickable links to view the updated MEMORY.md and dream diary.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
The system automatically runs distillation daily at 23:55 (lookback 1 day). Manual trigger is useful for consolidating historical memories after first deployment, or when you need an immediate memory update.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## knowledge
|
|
||||||
|
|
||||||
View and manage the personal knowledge base. Shows statistics by default.
|
|
||||||
|
|
||||||
```text
|
|
||||||
/knowledge
|
|
||||||
```
|
|
||||||
|
|
||||||
### knowledge list
|
|
||||||
|
|
||||||
View the knowledge base directory tree.
|
|
||||||
|
|
||||||
```text
|
|
||||||
/knowledge list
|
|
||||||
```
|
|
||||||
|
|
||||||
### knowledge on / off
|
|
||||||
|
|
||||||
Enable or disable the knowledge base. When disabled, knowledge prompts and file indexing are not injected.
|
|
||||||
|
|
||||||
```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>
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
---
|
|
||||||
title: Process Management
|
|
||||||
description: Manage CowAgent process lifecycle with cow commands
|
|
||||||
---
|
|
||||||
|
|
||||||
Process management commands control the CowAgent background process. These commands are only available in the terminal.
|
|
||||||
|
|
||||||
## start
|
|
||||||
|
|
||||||
Start the CowAgent service. Runs as a background daemon by default and automatically tails logs.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cow start
|
|
||||||
```
|
|
||||||
|
|
||||||
**Options:**
|
|
||||||
|
|
||||||
| Option | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `-f`, `--foreground` | Run in foreground, not as a background daemon |
|
|
||||||
| `--no-logs` | Don't tail logs after starting |
|
|
||||||
|
|
||||||
## stop
|
|
||||||
|
|
||||||
Stop the running CowAgent service.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cow stop
|
|
||||||
```
|
|
||||||
|
|
||||||
## restart
|
|
||||||
|
|
||||||
Restart the CowAgent service (stop then start).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cow restart
|
|
||||||
```
|
|
||||||
|
|
||||||
**Options:**
|
|
||||||
|
|
||||||
| Option | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `--no-logs` | Don't tail logs after restart |
|
|
||||||
|
|
||||||
## update
|
|
||||||
|
|
||||||
Update code and restart the service. Automatically performs:
|
|
||||||
|
|
||||||
1. Pull latest code (`git pull`)
|
|
||||||
2. Stop current service
|
|
||||||
3. Update Python dependencies
|
|
||||||
4. Reinstall CLI
|
|
||||||
5. Start service
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cow update
|
|
||||||
```
|
|
||||||
|
|
||||||
<Warning>
|
|
||||||
If `git pull` fails (e.g., uncommitted local changes), the update aborts and the service remains unaffected.
|
|
||||||
</Warning>
|
|
||||||
|
|
||||||
## status
|
|
||||||
|
|
||||||
Check CowAgent service status, including process info, version, and current model/channel configuration.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cow status
|
|
||||||
```
|
|
||||||
|
|
||||||
## logs
|
|
||||||
|
|
||||||
View service logs.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cow logs
|
|
||||||
```
|
|
||||||
|
|
||||||
**Options:**
|
|
||||||
|
|
||||||
| Option | Description | Default |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `-f`, `--follow` | Continuously tail log output | No |
|
|
||||||
| `-n`, `--lines` | Show last N lines | 50 |
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# View last 100 lines
|
|
||||||
cow logs -n 100
|
|
||||||
|
|
||||||
# Continuously tail logs
|
|
||||||
cow logs -f
|
|
||||||
```
|
|
||||||
|
|
||||||
## install-browser
|
|
||||||
|
|
||||||
Install Playwright and Chromium browser for the [browser tool](/en/tools/browser).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cow install-browser
|
|
||||||
```
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
Only needed when using browser tools (web browsing, screenshots, etc.).
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## run.sh Compatibility
|
|
||||||
|
|
||||||
If Cow CLI is not installed, you can use `run.sh` to manage the service:
|
|
||||||
|
|
||||||
| cow command | run.sh equivalent |
|
|
||||||
| --- | --- |
|
|
||||||
| `cow start` | `./run.sh start` |
|
|
||||||
| `cow stop` | `./run.sh stop` |
|
|
||||||
| `cow restart` | `./run.sh restart` |
|
|
||||||
| `cow update` | `./run.sh update` |
|
|
||||||
| `cow status` | `./run.sh status` |
|
|
||||||
| `cow logs` | `./run.sh logs` |
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
The `cow` command is recommended — it provides cleaner syntax and richer features. It is automatically installed via the one-click install script.
|
|
||||||
</Note>
|
|
||||||
@@ -1,210 +0,0 @@
|
|||||||
---
|
|
||||||
title: Skill Management
|
|
||||||
description: Install, uninstall, enable, disable, and manage skills via commands
|
|
||||||
---
|
|
||||||
|
|
||||||
Skill management commands are used to install, query, and manage CowAgent skills. Use `/skill <subcommand>` in chat or `cow skill <subcommand>` in the terminal.
|
|
||||||
|
|
||||||
## list
|
|
||||||
|
|
||||||
List installed skills and their status.
|
|
||||||
|
|
||||||
<CodeGroup>
|
|
||||||
```text Chat
|
|
||||||
/skill list
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash Terminal
|
|
||||||
cow skill list
|
|
||||||
```
|
|
||||||
</CodeGroup>
|
|
||||||
|
|
||||||
Example output:
|
|
||||||
|
|
||||||
```
|
|
||||||
📦 Installed skills (3/4)
|
|
||||||
|
|
||||||
✅ pptx
|
|
||||||
Use this skill any time a .pptx file is involved…
|
|
||||||
Source: cowhub
|
|
||||||
|
|
||||||
✅ skill-creator
|
|
||||||
Create, install, or update skills…
|
|
||||||
Source: builtin
|
|
||||||
|
|
||||||
⏸️ image-vision (disabled)
|
|
||||||
Image understanding and visual analysis
|
|
||||||
Source: builtin
|
|
||||||
```
|
|
||||||
|
|
||||||
**Browse the Skill Hub** (view all available skills):
|
|
||||||
|
|
||||||
<CodeGroup>
|
|
||||||
```text Chat
|
|
||||||
/skill list --remote
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash Terminal
|
|
||||||
cow skill list --remote
|
|
||||||
```
|
|
||||||
</CodeGroup>
|
|
||||||
|
|
||||||
**Options:**
|
|
||||||
|
|
||||||
| Option | Description | Default |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `--remote`, `-r` | Browse Skill Hub remote skill list | No |
|
|
||||||
| `--page` | Page number for remote listing | 1 |
|
|
||||||
|
|
||||||
## search
|
|
||||||
|
|
||||||
Search for skills on the Skill Hub.
|
|
||||||
|
|
||||||
<CodeGroup>
|
|
||||||
```text Chat
|
|
||||||
/skill search pptx
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash Terminal
|
|
||||||
cow skill search pptx
|
|
||||||
```
|
|
||||||
</CodeGroup>
|
|
||||||
|
|
||||||
## install
|
|
||||||
|
|
||||||
Install skills with a single `install` command from Cow Skill Hub, GitHub, ClawHub, or any URL (zip archives, SKILL.md links) — no manual download or configuration required.
|
|
||||||
|
|
||||||
**From Skill Hub (recommended):**
|
|
||||||
|
|
||||||
<CodeGroup>
|
|
||||||
```text Chat
|
|
||||||
/skill install pptx
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash Terminal
|
|
||||||
cow skill install pptx
|
|
||||||
```
|
|
||||||
</CodeGroup>
|
|
||||||
|
|
||||||
**From GitHub:**
|
|
||||||
|
|
||||||
<CodeGroup>
|
|
||||||
```text Chat
|
|
||||||
# Install all skills in a repo (auto-discovers subdirectories with SKILL.md)
|
|
||||||
/skill install larksuite/cli
|
|
||||||
|
|
||||||
# Specify a subdirectory to install a single skill
|
|
||||||
/skill install https://github.com/larksuite/cli/tree/main/skills/lark-im
|
|
||||||
|
|
||||||
# Use # to specify a subdirectory
|
|
||||||
/skill install larksuite/cli#skills/lark-minutes
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash Terminal
|
|
||||||
# Install all skills in a repo (auto-discovers subdirectories with SKILL.md)
|
|
||||||
cow skill install larksuite/cli
|
|
||||||
|
|
||||||
# Specify a subdirectory to install a single skill
|
|
||||||
cow skill install https://github.com/larksuite/cli/tree/main/skills/lark-im
|
|
||||||
|
|
||||||
# Use # to specify a subdirectory
|
|
||||||
cow skill install larksuite/cli#skills/lark-minutes
|
|
||||||
```
|
|
||||||
</CodeGroup>
|
|
||||||
|
|
||||||
Supports full GitHub URLs and `owner/repo` shorthand. For mono-repos (multiple skills in one repository), omitting the subdirectory auto-discovers and batch-installs all skills; specifying a subdirectory installs only that skill.
|
|
||||||
|
|
||||||
**From ClawHub:**
|
|
||||||
|
|
||||||
<CodeGroup>
|
|
||||||
```text Chat
|
|
||||||
/skill install clawhub:baidu-search
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash Terminal
|
|
||||||
cow skill install clawhub:baidu-search
|
|
||||||
```
|
|
||||||
</CodeGroup>
|
|
||||||
|
|
||||||
**From URL:**
|
|
||||||
|
|
||||||
<CodeGroup>
|
|
||||||
```text Chat
|
|
||||||
# Install from a zip archive (single or batch)
|
|
||||||
/skill install https://cdn.link-ai.tech/skills/pptx.zip
|
|
||||||
|
|
||||||
# Install from a SKILL.md link
|
|
||||||
/skill install https://example.com/path/to/SKILL.md
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash Terminal
|
|
||||||
# Install from a zip archive (single or batch)
|
|
||||||
cow skill install https://cdn.link-ai.tech/skills/pptx.zip
|
|
||||||
|
|
||||||
# Install from a SKILL.md link
|
|
||||||
cow skill install https://example.com/path/to/SKILL.md
|
|
||||||
```
|
|
||||||
</CodeGroup>
|
|
||||||
|
|
||||||
Supports installing from zip / tar.gz archive URLs — automatically extracts and discovers directories containing `SKILL.md`, with support for single or batch install. Also supports installing directly from a `SKILL.md` file URL, automatically parsing the skill name and description.
|
|
||||||
|
|
||||||
## uninstall
|
|
||||||
|
|
||||||
Uninstall an installed skill.
|
|
||||||
|
|
||||||
<CodeGroup>
|
|
||||||
```text Chat
|
|
||||||
/skill uninstall pptx
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash Terminal
|
|
||||||
cow skill uninstall pptx
|
|
||||||
```
|
|
||||||
</CodeGroup>
|
|
||||||
|
|
||||||
<Warning>
|
|
||||||
Uninstalling deletes all files in the skill directory. This action cannot be undone.
|
|
||||||
</Warning>
|
|
||||||
|
|
||||||
## enable / disable
|
|
||||||
|
|
||||||
Enable or disable a skill. Disabled skills will not be invoked by the Agent.
|
|
||||||
|
|
||||||
<CodeGroup>
|
|
||||||
```text Chat
|
|
||||||
/skill enable pptx
|
|
||||||
/skill disable pptx
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash Terminal
|
|
||||||
cow skill enable pptx
|
|
||||||
cow skill disable pptx
|
|
||||||
```
|
|
||||||
</CodeGroup>
|
|
||||||
|
|
||||||
## info
|
|
||||||
|
|
||||||
View details of an installed skill, including a preview of its `SKILL.md`.
|
|
||||||
|
|
||||||
<CodeGroup>
|
|
||||||
```text Chat
|
|
||||||
/skill info pptx
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash Terminal
|
|
||||||
cow skill info pptx
|
|
||||||
```
|
|
||||||
</CodeGroup>
|
|
||||||
|
|
||||||
## Skill Sources
|
|
||||||
|
|
||||||
Installed skills track their origin, viewable via `/skill list`:
|
|
||||||
|
|
||||||
| Source | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `builtin` | Built-in project skills |
|
|
||||||
| `cowhub` | Installed from CowAgent Skill Hub |
|
|
||||||
| `github` | Installed directly from a GitHub URL |
|
|
||||||
| `clawhub` | Installed from ClawHub |
|
|
||||||
| `url` | Installed from a SKILL.md URL |
|
|
||||||
| `local` | Locally created skills |
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
---
|
|
||||||
title: Manual Install
|
|
||||||
description: Deploy CowAgent manually (source code / Docker)
|
|
||||||
---
|
|
||||||
|
|
||||||
## Source Code Deployment
|
|
||||||
|
|
||||||
### 1. Clone the project
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/zhayujie/CowAgent
|
|
||||||
cd CowAgent/
|
|
||||||
```
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
For network issues, use the mirror: https://gitee.com/zhayujie/CowAgent
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
### 2. Install dependencies
|
|
||||||
|
|
||||||
Core dependencies (required):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pip3 install -r requirements.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
Optional dependencies (recommended):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pip3 install -r requirements-optional.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Install Cow CLI
|
|
||||||
|
|
||||||
Install the command-line tool for managing services and skills:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pip3 install -e .
|
|
||||||
```
|
|
||||||
|
|
||||||
Then use the `cow` command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cow help
|
|
||||||
```
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
This step is recommended. After installation you can use `cow start`, `cow stop`, `cow update` to manage the service, and `cow skill` to manage skills. Without the CLI, you can use `./run.sh` or `python3 app.py` to run.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
### 4. Configure
|
|
||||||
|
|
||||||
Copy the config template and edit:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cp config-template.json config.json
|
|
||||||
```
|
|
||||||
|
|
||||||
Fill in model API keys, channel type, and other settings in `config.json`. See the [model docs](/en/models/index) for details.
|
|
||||||
|
|
||||||
### 5. Run
|
|
||||||
|
|
||||||
**Using Cow CLI (recommended):**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cow start
|
|
||||||
```
|
|
||||||
|
|
||||||
**Or run locally in foreground:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
python3 app.py
|
|
||||||
```
|
|
||||||
|
|
||||||
By default, the Web console starts. Access `http://localhost:9899` to chat.
|
|
||||||
|
|
||||||
**Background run on server (without CLI):**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nohup python3 app.py & tail -f nohup.out
|
|
||||||
```
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
**Deploying on a server?** By default `web_host` only listens on `127.0.0.1` (local access). Set `web_host` to `0.0.0.0` in `config.json` to make the console reachable from outside, and set `web_password` to protect it. Don't forget to open port `9899` in your firewall or security group — ideally restricted to specific IPs.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## Docker Deployment
|
|
||||||
|
|
||||||
Docker deployment does not require cloning source code or installing dependencies. For Agent mode, source deployment is recommended for broader system access.
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
Requires [Docker](https://docs.docker.com/engine/install/) and docker-compose.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
**1. Download config**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -O https://cdn.link-ai.tech/code/cow/docker-compose.yml
|
|
||||||
```
|
|
||||||
|
|
||||||
Edit `docker-compose.yml` with your configuration.
|
|
||||||
|
|
||||||
**2. Start container**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo docker compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
**3. View logs**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo docker logs -f chatgpt-on-wechat
|
|
||||||
```
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
**Running in Docker?** Set `WEB_HOST` to `0.0.0.0` in `docker-compose.yml` so the console is reachable from outside the container, and set `WEB_PASSWORD` to protect it. Make sure port `9899` is mapped to the host and open in your firewall or security group.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## Core Configuration
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channel_type": "web",
|
|
||||||
"model": "deepseek-v4-flash",
|
|
||||||
"deepseek_api_key": "",
|
|
||||||
"agent": true,
|
|
||||||
"agent_workspace": "~/cow",
|
|
||||||
"agent_max_context_tokens": 40000,
|
|
||||||
"agent_max_context_turns": 30,
|
|
||||||
"agent_max_steps": 15
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description | Default |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `channel_type` | Channel type | `web` |
|
|
||||||
| `model` | Model name | `deepseek-v4-flash` |
|
|
||||||
| `agent` | Enable Agent mode | `true` |
|
|
||||||
| `agent_workspace` | Agent workspace path | `~/cow` |
|
|
||||||
| `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` |
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
Full configuration options are in the project [`config.py`](https://github.com/zhayujie/CowAgent/blob/master/config.py).
|
|
||||||
</Tip>
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
---
|
|
||||||
title: One-click Install
|
|
||||||
description: One-click install and manage CowAgent with scripts
|
|
||||||
---
|
|
||||||
|
|
||||||
The project provides scripts for one-click install, configuration, startup, and management. Script-based deployment is recommended for quick setup.
|
|
||||||
|
|
||||||
Supports Linux, macOS, and Windows. Requires Python 3.7-3.12 (3.9 recommended).
|
|
||||||
|
|
||||||
## Install Command
|
|
||||||
|
|
||||||
<Tabs>
|
|
||||||
<Tab title="Linux / macOS">
|
|
||||||
```bash
|
|
||||||
bash <(curl -fsSL https://cdn.link-ai.tech/code/cow/run.sh)
|
|
||||||
```
|
|
||||||
</Tab>
|
|
||||||
<Tab title="Windows (PowerShell)">
|
|
||||||
```powershell
|
|
||||||
irm https://cdn.link-ai.tech/code/cow/run.ps1 | iex
|
|
||||||
```
|
|
||||||
</Tab>
|
|
||||||
</Tabs>
|
|
||||||
|
|
||||||
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 `~/CowAgent`
|
|
||||||
4. Install Python dependencies and Cow CLI
|
|
||||||
5. Guided configuration for AI model and channel
|
|
||||||
6. Start service
|
|
||||||
|
|
||||||
By default, the Web console starts after installation. Access `http://localhost:9899` to begin chatting.
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
**Deploying on a server?** By default `web_host` only listens on `127.0.0.1` (local access only). Set `web_host` to `0.0.0.0` in `config.json` to make the console reachable from outside, and set `web_password` to protect it. Don't forget to open port `9899` in your firewall or security group — ideally restricted to specific IPs.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## Management Commands
|
|
||||||
|
|
||||||
After installation, use the `cow` command to manage the service:
|
|
||||||
|
|
||||||
| Command | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `cow start` | Start service |
|
|
||||||
| `cow stop` | Stop service |
|
|
||||||
| `cow restart` | Restart service |
|
|
||||||
| `cow status` | Check run status |
|
|
||||||
| `cow logs` | View real-time logs |
|
|
||||||
| `cow update` | Update code and restart |
|
|
||||||
| `cow install-browser` | Install browser tool dependencies |
|
|
||||||
|
|
||||||
See the [Commands documentation](/en/cli/index) for more details.
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
If the `cow` command is not available, you can use `./run.sh <command>` (Linux/macOS) or `.\scripts\run.ps1 <command>` (Windows) as a fallback. Both are functionally equivalent.
|
|
||||||
</Note>
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
---
|
|
||||||
title: Upgrade
|
|
||||||
description: How to upgrade CowAgent
|
|
||||||
---
|
|
||||||
|
|
||||||
## Recommended: One-line upgrade
|
|
||||||
|
|
||||||
Use `cow update` to pull the latest code and restart the service in one step:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cow update
|
|
||||||
```
|
|
||||||
|
|
||||||
The command runs the following automatically:
|
|
||||||
|
|
||||||
1. Pull the latest code (`git pull`)
|
|
||||||
2. Stop the running service
|
|
||||||
3. Update Python dependencies
|
|
||||||
4. Reinstall the CLI
|
|
||||||
5. Start the service
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
If the Cow CLI is not installed, `./run.sh update` performs the same operations.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## Manual upgrade
|
|
||||||
|
|
||||||
Run the following inside the project root:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git pull
|
|
||||||
pip3 install -r requirements.txt
|
|
||||||
pip3 install -e .
|
|
||||||
```
|
|
||||||
|
|
||||||
Then restart the service:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Using Cow CLI (recommended)
|
|
||||||
cow restart
|
|
||||||
|
|
||||||
# Or using run.sh
|
|
||||||
./run.sh restart
|
|
||||||
|
|
||||||
# Or restart manually with nohup
|
|
||||||
kill $(ps -ef | grep app.py | grep -v grep | awk '{print $2}')
|
|
||||||
nohup python3 app.py & tail -f nohup.out
|
|
||||||
```
|
|
||||||
|
|
||||||
## Docker upgrade
|
|
||||||
|
|
||||||
Run the following in the directory containing `docker-compose.yml`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo docker compose pull
|
|
||||||
sudo docker compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
Back up `config.json` before upgrading. For Docker deployments, mount the workspace directory as a volume to persist data across upgrades.
|
|
||||||
</Tip>
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
---
|
|
||||||
title: Architecture
|
|
||||||
description: CowAgent 2.0 system architecture and core design
|
|
||||||
---
|
|
||||||
|
|
||||||
CowAgent 2.0 has evolved from a simple chatbot into a super intelligent assistant with Agent architecture, featuring autonomous thinking, task planning, long-term memory, and skill extensibility.
|
|
||||||
|
|
||||||
## System Architecture
|
|
||||||
|
|
||||||
CowAgent's architecture consists of the following core modules:
|
|
||||||
|
|
||||||
<img src="https://cdn.jsdelivr.net/gh/zhayujie/cowagent-assets@main/architecture/en/architecture.jpg" alt="CowAgent Architecture" />
|
|
||||||
|
|
||||||
| Module | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| **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
|
|
||||||
|
|
||||||
When Agent mode is enabled, CowAgent runs as an autonomous agent with the following workflow:
|
|
||||||
|
|
||||||
1. **Receive Message** — Receive user input through channels
|
|
||||||
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 & 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
|
|
||||||
|
|
||||||
The Agent workspace is located at `~/cow` by default and stores system prompts, memory files, and skill files:
|
|
||||||
|
|
||||||
```
|
|
||||||
~/cow/
|
|
||||||
├── SYSTEM.md # Agent system prompt
|
|
||||||
├── USER.md # User profile
|
|
||||||
├── MEMORY.md # Core memory
|
|
||||||
├── memory/ # Long-term memory storage
|
|
||||||
│ └── 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/
|
|
||||||
```
|
|
||||||
|
|
||||||
Secret keys are stored separately in `~/.cow` directory for security:
|
|
||||||
|
|
||||||
```
|
|
||||||
~/.cow/
|
|
||||||
└── .env # Secret keys for skills
|
|
||||||
```
|
|
||||||
|
|
||||||
## Core Configuration
|
|
||||||
|
|
||||||
Configure Agent mode parameters in `config.json`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"agent": true,
|
|
||||||
"agent_workspace": "~/cow",
|
|
||||||
"agent_max_context_tokens": 50000,
|
|
||||||
"agent_max_context_turns": 20,
|
|
||||||
"agent_max_steps": 20,
|
|
||||||
"enable_thinking": false
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description | Default |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `agent` | Enable Agent mode | `true` |
|
|
||||||
| `agent_workspace` | Workspace path | `~/cow` |
|
|
||||||
| `agent_max_context_tokens` | Max context tokens | `50000` |
|
|
||||||
| `agent_max_context_turns` | Max context turns | `20` |
|
|
||||||
| `agent_max_steps` | Max decision steps per task | `20` |
|
|
||||||
| `enable_thinking` | Enable deep-thinking mode | `false` |
|
|
||||||
| `knowledge` | Enable personal knowledge base | `true` |
|
|
||||||
| `knowledge` | Enable personal knowledge base | `true` |
|
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
---
|
|
||||||
title: Features
|
|
||||||
description: CowAgent long-term memory, task planning, skills system, CLI commands, and browser tool in detail
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Long-term Memory
|
|
||||||
|
|
||||||
The memory system enables the Agent to remember important information over time, using a three-tier memory flow: conversation context (short-term) → daily memory (mid-term) → MEMORY.md (long-term), forming a complete memory lifecycle.
|
|
||||||
|
|
||||||
On first launch, the Agent proactively asks the user for key information and records it in the workspace (default `~/cow`) — including agent settings, user identity, and memory files.
|
|
||||||
|
|
||||||
In subsequent long-term conversations, the Agent intelligently stores or retrieves memory as needed, continuously updating its own settings, user preferences, and memory files. **Deep Dream** distillation runs daily, consolidating scattered daily memories into refined long-term memory and generating a narrative-style dream diary.
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260203000455.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
See [Long-term Memory](/en/memory) and [Deep Dream](/en/memory/deep-dream) for details.
|
|
||||||
|
|
||||||
## 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`
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260413105435.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
### 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:
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260202181130.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
### 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:
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260318211018.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
### 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:
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260202195402.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
### 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:
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260401110103.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
### 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:
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260202234939.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
## 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.
|
|
||||||
|
|
||||||
- [Skill Hub](https://skills.cowagent.ai/): An open skill marketplace featuring official, community, and third-party skills. Install with one command.
|
|
||||||
- **Built-in skills:** Located in the project's `skills/` directory, including skill creator, image recognition, LinkAI agent, web fetch, and more. Built-in skills are automatically enabled based on dependency conditions (API keys, system commands, etc.).
|
|
||||||
- **Custom skills:** Created by users through conversation, stored in the workspace (`~/cow/skills/`), capable of implementing any complex business process or third-party integration.
|
|
||||||
|
|
||||||
Install skills: `/skill install <name>` or `cow skill install <name>`, supporting Skill Hub, GitHub, ClawHub, URL, and more.
|
|
||||||
|
|
||||||
### 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:
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260202202247.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
### 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`.
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260202213219.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
### 4.3 Skill Hub
|
|
||||||
|
|
||||||
Visit [skills.cowagent.ai](https://skills.cowagent.ai/) to browse all available skills, or use commands in conversation:
|
|
||||||
|
|
||||||
```text
|
|
||||||
/skill list --remote # Browse Skill Hub
|
|
||||||
/skill search <keyword> # Search skills
|
|
||||||
/skill install <name> # Install with one command
|
|
||||||
```
|
|
||||||
|
|
||||||
Also supports installing skills from GitHub, ClawHub, LinkAI, and other third-party platforms. See [Install Skills](/en/skills/install) for details.
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260401110103.png" width="750" />
|
|
||||||
|
|
||||||
## 5. CLI Command System
|
|
||||||
|
|
||||||
CowAgent provides two command interaction methods, covering service management, skill installation, configuration, and more:
|
|
||||||
|
|
||||||
- **Terminal CLI:** Run `cow <command>` in the system terminal, supporting `start`, `stop`, `restart`, `update`, `status`, `logs`, `skill`, etc.
|
|
||||||
- **Chat commands:** Type `/<command>` in conversation. The Web console shows a command menu when you type `/`.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cow start # Start service
|
|
||||||
cow stop # Stop service
|
|
||||||
cow update # Update and restart
|
|
||||||
cow skill install pptx # Install a skill
|
|
||||||
cow install-browser # Install browser tool
|
|
||||||
```
|
|
||||||
|
|
||||||
See [Command Overview](https://docs.cowagent.ai/en/cli) for details.
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
---
|
|
||||||
title: Introduction
|
|
||||||
description: CowAgent - Open-source super AI assistant and Agent Harness
|
|
||||||
---
|
|
||||||
|
|
||||||
<div align="center">
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/78c5dd674e2c828642ecc0406669fed7.png" alt="CowAgent" width="450px"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
**CowAgent** is an open-source super AI assistant and Agent Harness. It proactively plans tasks, runs tools and skills, and autonomously grows with memory and knowledge.
|
|
||||||
|
|
||||||
CowAgent is lightweight, easy to deploy, and built to extend. Plug in any major LLM provider, run it across Web and major IM platforms, 24/7 on a personal computer or server.
|
|
||||||
|
|
||||||
<CardGroup cols={2}>
|
|
||||||
<Card title="GitHub" icon="github" href="https://github.com/zhayujie/CowAgent">
|
|
||||||
Open-source repository — Star and contribute
|
|
||||||
</Card>
|
|
||||||
<Card title="Try Online" icon="cloud" href="https://link-ai.tech/cowagent/create">
|
|
||||||
No setup required — experience CowAgent instantly
|
|
||||||
</Card>
|
|
||||||
</CardGroup>
|
|
||||||
|
|
||||||
## Core Capabilities
|
|
||||||
|
|
||||||
<CardGroup cols={2}>
|
|
||||||
<Card title="Autonomous Task Planning" icon="brain" href="/en/intro/architecture">
|
|
||||||
Decomposes complex tasks and executes them step by step, looping over tools and skills until the goal is reached.
|
|
||||||
</Card>
|
|
||||||
<Card title="Long-term Memory" icon="database" href="/en/memory/index">
|
|
||||||
Three-tier architecture (context → daily → core), automatic Deep Dream distillation, hybrid keyword + vector retrieval.
|
|
||||||
</Card>
|
|
||||||
<Card title="Personal Knowledge Base" icon="book" href="/en/knowledge/index">
|
|
||||||
Auto-curates structured knowledge into a Markdown wiki, builds an evolving knowledge graph with visual browsing.
|
|
||||||
</Card>
|
|
||||||
<Card title="Skills System" icon="puzzle-piece" href="/en/skills/index">
|
|
||||||
A complete skill creation and execution engine. Install from Skill Hub or generate custom skills via natural-language conversation.
|
|
||||||
</Card>
|
|
||||||
<Card title="Multimodal Messaging" icon="image" href="/en/channels/web">
|
|
||||||
First-class support for text, images, voice, and files — recognition, generation, and delivery.
|
|
||||||
</Card>
|
|
||||||
<Card title="Tool System" icon="wrench" href="/en/tools/index">
|
|
||||||
Built-in file I/O, terminal, browser, scheduler, memory retrieval, web search, and more — with native MCP integration.
|
|
||||||
</Card>
|
|
||||||
<Card title="Command System" icon="terminal" href="/en/cli/index">
|
|
||||||
Terminal CLI and in-chat commands for process management, skill installation, configuration, and context inspection.
|
|
||||||
</Card>
|
|
||||||
<Card title="Pluggable Models" icon="microchip" href="/en/models/index">
|
|
||||||
Claude, GPT, Gemini, DeepSeek, Qwen, GLM, Kimi, MiniMax, Doubao, and more — swap providers from the Web console with one click.
|
|
||||||
</Card>
|
|
||||||
<Card title="Multi-channel Integration" icon="server" href="/en/channels/index">
|
|
||||||
A single Agent simultaneously serves Web, WeChat, Feishu, DingTalk, WeCom, QQ, and Official Accounts.
|
|
||||||
</Card>
|
|
||||||
</CardGroup>
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
|
|
||||||
Run one of the commands below to install, configure, and start CowAgent in a single step:
|
|
||||||
|
|
||||||
<Tabs>
|
|
||||||
<Tab title="Linux / macOS">
|
|
||||||
```bash
|
|
||||||
bash <(curl -fsSL https://cdn.link-ai.tech/code/cow/run.sh)
|
|
||||||
```
|
|
||||||
</Tab>
|
|
||||||
<Tab title="Windows (PowerShell)">
|
|
||||||
```powershell
|
|
||||||
irm https://cdn.link-ai.tech/code/cow/run.ps1 | iex
|
|
||||||
```
|
|
||||||
</Tab>
|
|
||||||
</Tabs>
|
|
||||||
|
|
||||||
Once started, open `http://localhost:9899` to access the **Web console** — the unified place to chat, configure providers, connect channels, and install skills.
|
|
||||||
|
|
||||||
<CardGroup cols={2}>
|
|
||||||
<Card title="Quick Start" icon="rocket" href="/en/guide/quick-start">
|
|
||||||
Complete installation and run guide
|
|
||||||
</Card>
|
|
||||||
<Card title="Architecture" icon="sitemap" href="/en/intro/architecture">
|
|
||||||
CowAgent system architecture
|
|
||||||
</Card>
|
|
||||||
</CardGroup>
|
|
||||||
|
|
||||||
## Disclaimer
|
|
||||||
|
|
||||||
1. This project is licensed under the [MIT License](https://github.com/zhayujie/CowAgent/blob/master/LICENSE) and is intended for technical research and learning. You are responsible for complying with applicable laws and regulations in your jurisdiction; the maintainers assume no liability for any consequences arising from use of this project.
|
|
||||||
2. **Cost & safety:** Agent mode consumes substantially more tokens than plain chat — pick models that balance quality and cost. The Agent has access to your local operating system; deploy only in trusted environments.
|
|
||||||
3. CowAgent is a pure open-source project and does not participate in, authorize, or issue any cryptocurrency.
|
|
||||||
|
|
||||||
## Community
|
|
||||||
|
|
||||||
Scan the WeChat QR code to join the open-source community group:
|
|
||||||
|
|
||||||
<img width="140" src="https://img-1317903499.cos.ap-guangzhou.myqcloud.com/docs/open-community.png" />
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
---
|
|
||||||
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.
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260413105435.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
## 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://cdn.link-ai.tech/doc/20260413110104.png" width="800" />
|
|
||||||
</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://cdn.link-ai.tech/doc/17aad553d3e9e428c52ff9dc31726fda.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260413105402.png" width="800" />
|
|
||||||
</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` |
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
---
|
|
||||||
title: Short-term Memory
|
|
||||||
description: Conversation context — message management, compression strategies, and context operations
|
|
||||||
---
|
|
||||||
|
|
||||||
Conversation context is the Agent's short-term memory, containing all messages in the current session (user input, Agent replies, tool calls and results). Proper context management is critical for the Agent's reasoning quality and cost control.
|
|
||||||
|
|
||||||
## Context Structure
|
|
||||||
|
|
||||||
Each conversation turn consists of:
|
|
||||||
|
|
||||||
```
|
|
||||||
User message → Agent thinking → Tool call → Tool result → ... → Agent final reply
|
|
||||||
```
|
|
||||||
|
|
||||||
A single turn may include multiple tool calls (controlled by `agent_max_steps`). All tool calls and results are retained in context until compressed or trimmed.
|
|
||||||
|
|
||||||
## Key Configuration
|
|
||||||
|
|
||||||
| Parameter | Description | Default |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `agent_max_context_tokens` | Maximum context token budget | `50000` |
|
|
||||||
| `agent_max_context_turns` | Maximum conversation turns in context | `20` |
|
|
||||||
| `agent_max_steps` | Maximum decision steps per turn (tool call count) | `15` |
|
|
||||||
|
|
||||||
Configurable via `config.json` or the `/config` chat command.
|
|
||||||
|
|
||||||
## Compression Strategy
|
|
||||||
|
|
||||||
When context exceeds limits, the system automatically compresses to free space. The process has multiple stages:
|
|
||||||
|
|
||||||
### 1. Tool Result Truncation
|
|
||||||
|
|
||||||
Before each decision loop, the system checks tool call results in historical turns. Results exceeding **20,000 characters** are truncated, keeping only the beginning and end with a truncation notice. Current turn results are not affected.
|
|
||||||
|
|
||||||
### 2. Turn Trimming
|
|
||||||
|
|
||||||
When conversation turns exceed `agent_max_context_turns`:
|
|
||||||
|
|
||||||
- The **oldest half** of complete turns is trimmed (preserving tool call chain integrity)
|
|
||||||
- Trimmed messages are summarized by LLM and **written to the daily memory file**
|
|
||||||
- Once the LLM summary is ready, it is also **injected into the first user message** of the retained context, helping the model maintain conversational continuity
|
|
||||||
- Summary injection runs asynchronously in the background and takes effect from the next turn onward
|
|
||||||
|
|
||||||
### 3. Token Budget Trimming
|
|
||||||
|
|
||||||
After turn trimming, if tokens still exceed the budget:
|
|
||||||
|
|
||||||
- **Fewer than 5 turns**: All turns undergo **text compression** — each turn keeps only the first user text and last Agent reply, removing intermediate tool call chains
|
|
||||||
- **5 or more turns**: The **first half** of turns is trimmed again, with discarded content written to memory and a context summary injected
|
|
||||||
|
|
||||||
### 4. Overflow Emergency Handling
|
|
||||||
|
|
||||||
When the model API returns a context overflow error:
|
|
||||||
|
|
||||||
1. All current messages are summarized and written to memory
|
|
||||||
2. Aggressive trimming is applied (tool results limited to 10K chars, user text to 10K, max 5 turns)
|
|
||||||
3. If still overflowing, the entire conversation context is cleared
|
|
||||||
|
|
||||||
## Session Persistence
|
|
||||||
|
|
||||||
Conversation messages are persisted to a local database, automatically restored after service restart. Restore strategy:
|
|
||||||
|
|
||||||
- Restores the most recent **`max(3, max_context_turns / 6)`** turns
|
|
||||||
- Only retains each turn's **user text and Agent final reply**, not intermediate tool call chains
|
|
||||||
- Sessions older than **30 days** are automatically cleaned up
|
|
||||||
|
|
||||||
## Commands
|
|
||||||
|
|
||||||
Use these commands in chat to manage context:
|
|
||||||
|
|
||||||
| Command | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `/context` | View current context statistics (message count, role distribution, total characters) |
|
|
||||||
| `/context clear` | Clear current session context |
|
|
||||||
| `/config agent_max_context_tokens 80000` | Adjust context token budget |
|
|
||||||
| `/config agent_max_context_turns 30` | Adjust context turn limit |
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
After clearing context, the Agent "forgets" previous conversation content. Content that was already written to long-term memory can still be retrieved via memory search.
|
|
||||||
</Tip>
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
---
|
|
||||||
title: Deep Dream
|
|
||||||
description: Deep Dream — automatic distillation from conversations to permanent memory
|
|
||||||
---
|
|
||||||
|
|
||||||
Deep Dream is the core consolidation mechanism of CowAgent's memory system, responsible for distilling scattered daily memories into refined long-term memory and generating dream diaries.
|
|
||||||
|
|
||||||
## Memory Flow
|
|
||||||
|
|
||||||
CowAgent's memory progresses through three stages from short-term to long-term:
|
|
||||||
|
|
||||||
```
|
|
||||||
Conversation context (short-term) → Daily memory (mid-term) → MEMORY.md (long-term)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 1. Conversation → Daily Memory
|
|
||||||
|
|
||||||
When conversation context is trimmed or during the daily scheduled summary, the system uses LLM to summarize conversation content into key events, writing them to the daily memory file `memory/YYYY-MM-DD.md`.
|
|
||||||
|
|
||||||
Triggers:
|
|
||||||
- **Context trimming** — Trimmed content is summarized when turn or token limits are exceeded
|
|
||||||
- **Daily schedule** — Automatically triggered at 23:55
|
|
||||||
- **API overflow** — Emergency save of current conversation summary
|
|
||||||
|
|
||||||
### 2. Daily Memory → MEMORY.md (Distillation)
|
|
||||||
|
|
||||||
After the daily summary completes, Deep Dream automatically runs distillation:
|
|
||||||
|
|
||||||
1. **Read materials** — Current `MEMORY.md` + today's daily memory
|
|
||||||
2. **LLM distillation** — Deduplicate, merge, prune, extract new information
|
|
||||||
3. **Overwrite MEMORY.md** — Output the refined long-term memory
|
|
||||||
4. **Generate dream diary** — Record discoveries and insights from the consolidation
|
|
||||||
|
|
||||||
### 3. Role of MEMORY.md
|
|
||||||
|
|
||||||
`MEMORY.md` is injected into the system prompt for every conversation, keeping the Agent aware of user preferences, decisions, and key facts. Therefore it must stay concise — Deep Dream targets approximately 30 entries or fewer.
|
|
||||||
|
|
||||||
## Distillation Rules
|
|
||||||
|
|
||||||
Deep Dream follows these consolidation rules:
|
|
||||||
|
|
||||||
| Operation | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| **Merge & refine** | Combine similar entries into single high-density statements |
|
|
||||||
| **Extract new** | Pull preferences, decisions, people, experiences from daily memory |
|
|
||||||
| **Conflict update** | When new info contradicts old entries, newer info takes precedence |
|
|
||||||
| **Clean invalid** | Remove temporary records, blank entries, formatting artifacts |
|
|
||||||
| **Remove redundancy** | Delete old entries already covered by more refined statements |
|
|
||||||
|
|
||||||
## Dream Diary
|
|
||||||
|
|
||||||
Each distillation generates a dream diary saved at `memory/dreams/YYYY-MM-DD.md`, written in a narrative style recording:
|
|
||||||
|
|
||||||
- Duplications or contradictions found
|
|
||||||
- New insights extracted from daily memory
|
|
||||||
- Cleanups and optimizations performed
|
|
||||||
- Overall observations
|
|
||||||
|
|
||||||
Dream diaries can be viewed in the Web console under "Memory → Dream Diary" tab.
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260414110032.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
## Manual Trigger
|
|
||||||
|
|
||||||
In addition to the automatic daily run, you can manually trigger distillation in chat:
|
|
||||||
|
|
||||||
```text
|
|
||||||
/memory dream [N]
|
|
||||||
```
|
|
||||||
|
|
||||||
- `N`: Consolidate the last N days of memory (default 3, max 30)
|
|
||||||
- Runs asynchronously in the background; you'll be notified in chat when complete
|
|
||||||
- Web notifications include clickable links to view MEMORY.md and dream diary
|
|
||||||
- Works without Agent initialization — can be used before the first conversation
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
After first deployment, it's recommended to run `/memory dream 30` once to distill all historical daily memories into MEMORY.md.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## Safety Mechanisms
|
|
||||||
|
|
||||||
| Mechanism | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| **Skip on no content** | Distillation skipped when no daily memory exists, avoiding empty overwrites |
|
|
||||||
| **Input dedup** | In scheduled tasks, automatically skipped when input materials haven't changed |
|
|
||||||
| **Async execution** | Distillation runs in a background thread, never blocking conversation |
|
|
||||||
| **Sequential guarantee** | In scheduled tasks, daily flush completes before distillation starts |
|
|
||||||
| **No fabrication** | Prompt explicitly constrains consolidation to existing materials only |
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
---
|
|
||||||
title: Long-term Memory
|
|
||||||
description: CowAgent long-term memory system — file persistence, automatic writing, and hybrid retrieval
|
|
||||||
---
|
|
||||||
|
|
||||||
Long-term memory is stored in workspace files, persisting across sessions. The Agent loads historical memory on demand via retrieval tools during conversation, and automatically writes conversation summaries to long-term memory when context is trimmed.
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/memory-architecture-en.jpg" alt="Memory Architecture" />
|
|
||||||
|
|
||||||
## Memory Types
|
|
||||||
|
|
||||||
### Core Memory (MEMORY.md)
|
|
||||||
|
|
||||||
Stored in `~/cow/MEMORY.md`, containing long-term user preferences, important decisions, key facts, and other information that doesn't fade over time. The Agent reads and writes this file via tools to maintain long-term knowledge.
|
|
||||||
|
|
||||||
### Daily Memory (memory/YYYY-MM-DD.md)
|
|
||||||
|
|
||||||
Stored in `~/cow/memory/` directory, named by date (e.g., `2026-03-08.md`), recording daily conversation summaries and key events. Files are only created on first write to avoid generating empty files.
|
|
||||||
|
|
||||||
### Dream Diary (memory/dreams/YYYY-MM-DD.md)
|
|
||||||
|
|
||||||
A byproduct of the Deep Dream (memory distillation) process, recording discoveries, deduplication operations, and new insights from each consolidation. Stored in `~/cow/memory/dreams/` directory, named by date.
|
|
||||||
|
|
||||||
## Automatic Writing
|
|
||||||
|
|
||||||
The Agent automatically persists conversation content to long-term memory through the following mechanisms:
|
|
||||||
|
|
||||||
- **On context trimming** — When conversation turns or tokens exceed the configured limit, the oldest half of the context is trimmed, and the discarded content is summarized by LLM into key information and written to the daily memory file. The summary is also asynchronously injected into the retained context for conversational continuity
|
|
||||||
- **Daily scheduled summary** — A full summary is automatically triggered at 23:55 every day, ensuring memory is preserved even on low-activity days (skipped if content hasn't changed)
|
|
||||||
- [Deep Dream (memory distillation)](/en/memory/deep-dream) — Runs automatically after the daily summary, distilling daily memories into MEMORY.md and generating a dream diary
|
|
||||||
- **On API context overflow** — When the model API returns a context overflow error, the current conversation summary is saved as an emergency measure
|
|
||||||
|
|
||||||
All memory writes run asynchronously in a background thread (LLM summarization + file writing), never blocking normal conversation replies.
|
|
||||||
|
|
||||||
## Memory Retrieval
|
|
||||||
|
|
||||||
The memory system supports hybrid retrieval modes:
|
|
||||||
|
|
||||||
- **Keyword retrieval** — FTS5 full-text index matching with BM25 ranking
|
|
||||||
- **Vector retrieval** — Embedding-based semantic similarity search, finds relevant memory even with different wording
|
|
||||||
|
|
||||||
The Agent automatically triggers memory retrieval during conversation as needed, incorporating relevant historical information into context. Results are ranked by a combined score (default: 0.7 vector weight + 0.3 keyword weight). Daily memory scores decay over time (30-day half-life), while core memory does not decay.
|
|
||||||
|
|
||||||
## Related Files
|
|
||||||
|
|
||||||
Files related to memory in the workspace (default `~/cow`):
|
|
||||||
|
|
||||||
| File | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `AGENT.md` | Agent personality and behavior settings |
|
|
||||||
| `USER.md` | User identity information and preferences |
|
|
||||||
| `RULE.md` | Custom rules and constraints |
|
|
||||||
| `MEMORY.md` | Core memory (long-term) |
|
|
||||||
| `memory/YYYY-MM-DD.md` | Daily memory (created on demand) |
|
|
||||||
| `memory/dreams/YYYY-MM-DD.md` | Dream diary (auto-generated by Deep Dream) |
|
|
||||||
|
|
||||||
## Web Console
|
|
||||||
|
|
||||||
The memory management page in the Web console allows browsing memory files and dream diaries, with tab switching support:
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260414171014.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
| Parameter | Description | Default |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `agent_workspace` | Workspace path, memory files stored under this directory | `~/cow` |
|
|
||||||
| `agent_max_context_tokens` | Max context tokens; when exceeded, content is trimmed and summarized into memory | `50000` |
|
|
||||||
| `agent_max_context_turns` | Max context turns; when exceeded, content is trimmed and summarized into memory | `20` |
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
---
|
|
||||||
title: Claude
|
|
||||||
description: Anthropic Claude model configuration (Text Chat + Image Understanding)
|
|
||||||
---
|
|
||||||
|
|
||||||
Claude is provided by Anthropic and supports both text chat and image understanding. The mainstream Sonnet / Opus models natively support vision, so no separate Vision model needs to be specified.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
All capabilities below can be configured in one place via the "Model Management" page in the Web Console, with no need to manually edit the configuration file.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## Text Chat
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"model": "claude-opus-4-8",
|
|
||||||
"claude_api_key": "YOUR_API_KEY"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `model` | Supports `claude-opus-4-8`, `claude-opus-4-7`, `claude-sonnet-4-6`, `claude-opus-4-6`, `claude-sonnet-4-5`, `claude-sonnet-4-0`, `claude-3-5-sonnet-latest`, etc. See [official models](https://docs.anthropic.com/en/docs/about-claude/models/overview) |
|
|
||||||
| `claude_api_key` | Create one in the [Claude Console](https://console.anthropic.com/settings/keys) |
|
|
||||||
| `claude_api_base` | Optional, defaults to `https://api.anthropic.com/v1`. Can be changed to a third-party proxy |
|
|
||||||
|
|
||||||
### Model Selection
|
|
||||||
|
|
||||||
| Model | Use Case |
|
|
||||||
| --- | --- |
|
|
||||||
| `claude-opus-4-8` | Default recommended, latest flagship; best for complex reasoning and long-running tasks |
|
|
||||||
| `claude-opus-4-7` | Previous-generation Opus flagship |
|
|
||||||
| `claude-sonnet-4-6` | Balanced cost and speed, lower cost |
|
|
||||||
| `claude-opus-4-6` / `claude-sonnet-4-5` / `claude-sonnet-4-0` | Earlier flagships at a lower price |
|
|
||||||
|
|
||||||
## Image Understanding
|
|
||||||
|
|
||||||
Once `claude_api_key` is configured, the Agent's Vision tool automatically uses the Claude main model to recognize images, with no extra setup required.
|
|
||||||
|
|
||||||
To manually specify a Vision model, set it explicitly in the configuration file:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"tools": {
|
|
||||||
"vision": {
|
|
||||||
"model": "claude-sonnet-4-6"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
---
|
|
||||||
title: Coding Plan
|
|
||||||
description: Coding Plan model configuration
|
|
||||||
---
|
|
||||||
|
|
||||||
> Coding Plan is a monthly subscription package offered by various providers, ideal for high-frequency Agent usage. CowAgent supports all Coding Plan providers via OpenAI-compatible mode.
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
Coding Plan API Base and API Key are usually separate from the standard pay-as-you-go ones. Please obtain them from each provider's platform.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## General Configuration
|
|
||||||
|
|
||||||
All providers can be accessed via the OpenAI-compatible protocol, and can be quickly configured through the web console. Set the model provider to **OpenAI**, select a custom model and enter the model code, then fill in the corresponding provider's API Base and API Key:
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260318113134.png" width="800"/>
|
|
||||||
|
|
||||||
You can also configure directly in `config.json`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"bot_type": "openai",
|
|
||||||
"model": "MODEL_NAME",
|
|
||||||
"open_ai_api_base": "PROVIDER_CODING_PLAN_API_BASE",
|
|
||||||
"open_ai_api_key": "YOUR_API_KEY"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `bot_type` | Must be `openai` (OpenAI-compatible mode) |
|
|
||||||
| `model` | Model name supported by the provider |
|
|
||||||
| `open_ai_api_base` | Provider's Coding Plan API Base URL |
|
|
||||||
| `open_ai_api_key` | Provider's Coding Plan API Key |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Alibaba Cloud
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"bot_type": "openai",
|
|
||||||
"model": "qwen3.5-plus",
|
|
||||||
"open_ai_api_base": "https://coding.dashscope.aliyuncs.com/v1",
|
|
||||||
"open_ai_api_key": "YOUR_API_KEY"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `model` | `qwen3.5-plus`, `qwen3-max-2026-01-23`, `qwen3-coder-next`, `qwen3-coder-plus`, `glm-5`, `glm-4.7`, `kimi-k2.5`, `MiniMax-M2.5` |
|
|
||||||
| `open_ai_api_base` | `https://coding.dashscope.aliyuncs.com/v1` |
|
|
||||||
| `open_ai_api_key` | Coding Plan specific key (not shared with pay-as-you-go) |
|
|
||||||
|
|
||||||
Reference: [Quick Start](https://help.aliyun.com/zh/model-studio/coding-plan-quickstart?spm=a2c4g.11186623.help-menu-2400256.d_0_2_1.70115203zi5Igc), [Model List](https://help.aliyun.com/zh/model-studio/coding-plan)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## MiniMax
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"bot_type": "openai",
|
|
||||||
"model": "MiniMax-M2.5",
|
|
||||||
"open_ai_api_base": "https://api.minimaxi.com/v1",
|
|
||||||
"open_ai_api_key": "YOUR_API_KEY"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `model` | `MiniMax-M2.5`, `MiniMax-M2.5-highspeed`, `MiniMax-M2.1`, `MiniMax-M2` |
|
|
||||||
| `open_ai_api_base` | China: `https://api.minimaxi.com/v1`; Global: `https://api.minimax.io/v1` |
|
|
||||||
| `open_ai_api_key` | Coding Plan specific key (not shared with pay-as-you-go) |
|
|
||||||
|
|
||||||
Reference: [China Key](https://platform.minimaxi.com/docs/coding-plan/quickstart), [Model List](https://platform.minimaxi.com/docs/guides/pricing-coding-plan), [Global Key](https://platform.minimax.io/docs/coding-plan/quickstart)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## GLM
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"bot_type": "openai",
|
|
||||||
"model": "glm-4.7",
|
|
||||||
"open_ai_api_base": "https://open.bigmodel.cn/api/coding/paas/v4",
|
|
||||||
"open_ai_api_key": "YOUR_API_KEY"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `model` | `glm-5`, `glm-4.7`, `glm-4.6`, `glm-4.5`, `glm-4.5-air` |
|
|
||||||
| `open_ai_api_base` | China: `https://open.bigmodel.cn/api/coding/paas/v4`; Global: `https://api.z.ai/api/coding/paas/v4` |
|
|
||||||
| `open_ai_api_key` | Shared with standard API |
|
|
||||||
|
|
||||||
Reference: [China Quick Start](https://docs.bigmodel.cn/cn/coding-plan/quick-start), [Global Quick Start](https://docs.z.ai/devpack/quick-start)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Kimi
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"bot_type": "moonshot",
|
|
||||||
"model": "kimi-for-coding",
|
|
||||||
"moonshot_base_url": "https://api.kimi.com/coding/v1",
|
|
||||||
"moonshot_api_key": "YOUR_API_KEY"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `model` | Use `kimi-for-coding` for auto-updating model, or specify a model such as `kimi-k2.6` |
|
|
||||||
| `moonshot_base_url` | `https://api.kimi.com/coding/v1` |
|
|
||||||
| `moonshot_api_key` | Coding Plan specific key (not shared with pay-as-you-go) |
|
|
||||||
|
|
||||||
Reference: [Key & Docs](https://www.kimi.com/code/docs/)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Volcengine
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"bot_type": "openai",
|
|
||||||
"model": "Doubao-Seed-2.0-Code",
|
|
||||||
"open_ai_api_base": "https://ark.cn-beijing.volces.com/api/coding/v3",
|
|
||||||
"open_ai_api_key": "YOUR_API_KEY"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `model` | `Doubao-Seed-2.0-Code`, `Doubao-Seed-2.0-pro`, `Doubao-Seed-2.0-lite`, `Doubao-Seed-Code`, `MiniMax-M2.5`, `Kimi-K2.5`, `GLM-4.7`, `DeepSeek-V3.2` |
|
|
||||||
| `open_ai_api_base` | `https://ark.cn-beijing.volces.com/api/coding/v3` |
|
|
||||||
| `open_ai_api_key` | Shared with standard API |
|
|
||||||
|
|
||||||
Reference: [Quick Start](https://www.volcengine.com/docs/82379/1928261?lang=zh)
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
---
|
|
||||||
title: Custom
|
|
||||||
description: Custom vendor configuration for third-party API proxies and local models
|
|
||||||
---
|
|
||||||
|
|
||||||
For model services accessed via the OpenAI-compatible protocol or locally deployed models, such as:
|
|
||||||
|
|
||||||
- **Third-party API proxies**: call multiple models through a unified API base
|
|
||||||
- **Local models**: models deployed locally with tools like Ollama, vLLM, LocalAI
|
|
||||||
- **Private deployments**: model services deployed inside an enterprise
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
Difference from the `openai` vendor: when a custom vendor is selected, switching models via `/config model` does not automatically switch the vendor type — the custom API address is always used.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## Text Chat
|
|
||||||
|
|
||||||
### Third-party API proxy
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"bot_type": "custom",
|
|
||||||
"model": "",
|
|
||||||
"custom_api_key": "YOUR_API_KEY",
|
|
||||||
"custom_api_base": "https://{your-proxy.com}/v1"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `bot_type` | Must be set to `custom` |
|
|
||||||
| `model` | Model name; any model name supported by the proxy service |
|
|
||||||
| `custom_api_key` | API key provided by the proxy service |
|
|
||||||
| `custom_api_base` | API endpoint provided by the proxy service; must be OpenAI-compatible |
|
|
||||||
|
|
||||||
### Local models
|
|
||||||
|
|
||||||
Local models usually do not require an API key — only the API base needs to be filled in:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"bot_type": "custom",
|
|
||||||
"model": "qwen3.5:27b",
|
|
||||||
"custom_api_base": "http://localhost:11434/v1"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Common local deployment tools and their default endpoints:
|
|
||||||
|
|
||||||
| Tool | Default API Base |
|
|
||||||
| --- | --- |
|
|
||||||
| [Ollama](https://ollama.com) | `http://localhost:11434/v1` |
|
|
||||||
| [vLLM](https://docs.vllm.ai) | `http://localhost:8000/v1` |
|
|
||||||
| [LocalAI](https://localai.io) | `http://localhost:8080/v1` |
|
|
||||||
|
|
||||||
### Switching Models
|
|
||||||
|
|
||||||
Switching models under a custom vendor only changes `model` — `bot_type` and the API endpoint remain unchanged:
|
|
||||||
|
|
||||||
```
|
|
||||||
/config model qwen3.5:27b
|
|
||||||
```
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
---
|
|
||||||
title: DeepSeek
|
|
||||||
description: DeepSeek model configuration (Text Chat + Thinking Mode)
|
|
||||||
---
|
|
||||||
|
|
||||||
DeepSeek is one of the default recommended vendors in Agent mode, focused on cost-effective text chat and task planning.
|
|
||||||
|
|
||||||
## Text Chat
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"model": "deepseek-v4-flash",
|
|
||||||
"deepseek_api_key": "YOUR_API_KEY"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `model` | Supports `deepseek-v4-flash` (Default), `deepseek-v4-pro` |
|
|
||||||
| `deepseek_api_key` | Create one on the [DeepSeek Platform](https://platform.deepseek.com/api_keys) |
|
|
||||||
| `deepseek_api_base` | Optional, defaults to `https://api.deepseek.com/v1`. Can be changed to a third-party proxy |
|
|
||||||
|
|
||||||
### Model Selection
|
|
||||||
|
|
||||||
| Model | Use Case |
|
|
||||||
| --- | --- |
|
|
||||||
| `deepseek-v4-flash` | Default recommended; fast and low cost |
|
|
||||||
| `deepseek-v4-pro` | Smarter; better for complex tasks |
|
|
||||||
|
|
||||||
## Thinking Mode
|
|
||||||
|
|
||||||
The V4 series (`deepseek-v4-flash` / `deepseek-v4-pro`) supports an explicit "thinking mode": before producing the final answer, the model emits a chain of thought (`reasoning_content`) to improve answer quality.
|
|
||||||
|
|
||||||
### Toggle
|
|
||||||
|
|
||||||
Controlled by the global `enable_thinking` config, and can also be toggled from the Web Console's configuration page:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"enable_thinking": true
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `true`: the model thinks before answering across all channels. The Web Console displays the thinking process; IM channels (WeChat / WeCom / DingTalk / Feishu) do not show it but still get better answers.
|
|
||||||
- `false`: thinking is disabled, responses are faster, and time-to-first-token is lower.
|
|
||||||
|
|
||||||
### Reasoning Effort
|
|
||||||
|
|
||||||
Under thinking mode, `reasoning_effort` controls reasoning intensity:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"enable_thinking": true,
|
|
||||||
"reasoning_effort": "high"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Value | Use Case |
|
|
||||||
| --- | --- |
|
|
||||||
| `high` (Default) | Day-to-day Agent tasks; balanced reasoning and speed |
|
|
||||||
| `max` | Complex coding, long-horizon planning, strictly constrained tasks; deeper reasoning but more time and output tokens |
|
|
||||||
|
|
||||||
`reasoning_effort` only takes effect when `enable_thinking` is `true`; it is ignored automatically when the model does not support thinking mode.
|
|
||||||
|
|
||||||
### Behavior Notes
|
|
||||||
|
|
||||||
- **Sampling parameters**: in thinking mode, `temperature`, `top_p`, `presence_penalty`, and `frequency_penalty` are ignored by the server (without errors). CowAgent automatically skips them.
|
|
||||||
- **Multi-turn tool calls**: when the history contains tool calls, DeepSeek requires every assistant message to include `reasoning_content`. CowAgent handles this automatically, so toggling thinking mode across turns will not cause errors.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
`deepseek-v4-flash` is used by default; switch to `deepseek-v4-pro` for complex tasks; enable `enable_thinking` when deep reasoning is needed.
|
|
||||||
</Tip>
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
---
|
|
||||||
title: Doubao
|
|
||||||
description: Doubao (Volcengine Ark) model configuration (Text / Image Understanding / Image Generation / Embedding)
|
|
||||||
---
|
|
||||||
|
|
||||||
Doubao (Volcengine Ark) supports text chat, image understanding, image generation (Seedream), and embedding. A single `ark_api_key` enables all capabilities.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
All capabilities below can be configured in one place via the "Model Management" page in the Web Console, with no need to manually edit the configuration file.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## Text Chat
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"model": "doubao-seed-2-0-pro-260215",
|
|
||||||
"ark_api_key": "YOUR_API_KEY"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `model` | Can be `doubao-seed-2-0-pro-260215`, `doubao-seed-2-0-code-preview-260215`, `doubao-seed-2-0-lite-260215`, etc. |
|
|
||||||
| `ark_api_key` | Create one in the [Volcengine Ark Console](https://console.volcengine.com/ark/region:ark+cn-beijing/apikey) |
|
|
||||||
| `ark_base_url` | Optional, defaults to `https://ark.cn-beijing.volces.com/api/v3` |
|
|
||||||
|
|
||||||
## Image Understanding
|
|
||||||
|
|
||||||
Once `ark_api_key` is configured, the Agent's Vision tool automatically uses `doubao-seed-2-0-pro-260215` to recognize images, with no extra setup required.
|
|
||||||
|
|
||||||
To manually specify a Vision model:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"tools": {
|
|
||||||
"vision": {
|
|
||||||
"model": "doubao-seed-2-0-pro-260215"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Image Generation
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"skills": {
|
|
||||||
"image-generation": {
|
|
||||||
"model": "seedream-5.0-lite"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Available models: `seedream-5.0-lite`, `seedream-4.5`.
|
|
||||||
|
|
||||||
## Embedding
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"embedding_provider": "doubao",
|
|
||||||
"embedding_model": "doubao-embedding-vision-251215"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The default model is `doubao-embedding-vision-251215` (multimodal embedding); the dimension (1024 or 2048) can be set via `embedding_dimensions` in the configuration file. After changing the embedding, run `/memory rebuild-index` to rebuild the index.
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
---
|
|
||||||
title: Gemini
|
|
||||||
description: Google Gemini model configuration (Text Chat + Image Understanding + Image Generation)
|
|
||||||
---
|
|
||||||
|
|
||||||
Google Gemini supports text chat, image understanding, and image generation (Nano Banana series). A single `gemini_api_key` enables all capabilities.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
All capabilities below can be configured in one place via the "Model Management" page in the Web Console, with no need to manually edit the configuration file.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## Text Chat
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"model": "gemini-3.5-flash",
|
|
||||||
"gemini_api_key": "YOUR_API_KEY"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `model` | Recommended: `gemini-3.5-flash`; also supports `gemini-3.1-pro-preview`, `gemini-3.1-flash-lite-preview`, `gemini-3-flash-preview`, `gemini-3-pro-preview`, etc. See [official docs](https://ai.google.dev/gemini-api/docs/models) |
|
|
||||||
| `gemini_api_key` | Create one in [Google AI Studio](https://aistudio.google.com/app/apikey) |
|
|
||||||
| `gemini_api_base` | Optional, defaults to `https://generativelanguage.googleapis.com`. Can be changed to a third-party proxy |
|
|
||||||
|
|
||||||
## Image Understanding
|
|
||||||
|
|
||||||
All Gemini models natively support vision. Once `gemini_api_key` is configured, the Agent's Vision tool automatically uses the main model to recognize images, with no extra setup required.
|
|
||||||
|
|
||||||
To manually specify a Vision model:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"tools": {
|
|
||||||
"vision": {
|
|
||||||
"model": "gemini-3.1-flash-lite-preview"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Image Generation
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"skills": {
|
|
||||||
"image-generation": {
|
|
||||||
"model": "gemini-3.1-flash-image-preview"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Model ID | Alias |
|
|
||||||
| --- | --- |
|
|
||||||
| `gemini-3.1-flash-image-preview` | Nano Banana 2 |
|
|
||||||
| `gemini-3-pro-image-preview` | Nano Banana Pro |
|
|
||||||
| `gemini-2.5-flash-image` | Nano Banana |
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
---
|
|
||||||
title: GLM
|
|
||||||
description: Zhipu AI GLM model configuration (Text / Image Understanding / Speech-to-Text / Embedding)
|
|
||||||
---
|
|
||||||
|
|
||||||
Zhipu AI supports text chat, image understanding, speech-to-text (ASR), and embedding. A single `zhipu_ai_api_key` enables all capabilities.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
All capabilities below can be configured in one place via the "Model Management" page in the Web Console, with no need to manually edit the configuration file.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## Text Chat
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"model": "glm-5.1",
|
|
||||||
"zhipu_ai_api_key": "YOUR_API_KEY"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `model` | Can be `glm-5.1`, `glm-5-turbo`, `glm-5`, `glm-4.7`, `glm-4-plus`, `glm-4-flash`, `glm-4-air`, etc. See [model codes](https://bigmodel.cn/dev/api/normal-model/glm-4) |
|
|
||||||
| `zhipu_ai_api_key` | Create one in the [Zhipu AI Console](https://www.bigmodel.cn/usercenter/proj-mgmt/apikeys) |
|
|
||||||
| `zhipu_ai_api_base` | Optional, defaults to `https://open.bigmodel.cn/api/paas/v4` |
|
|
||||||
|
|
||||||
## Image Understanding
|
|
||||||
|
|
||||||
Zhipu's chat models (`glm-5.1`, `glm-5-turbo`, etc.) do not support vision; vision calls are uniformly routed to `glm-5v-turbo`. Once `zhipu_ai_api_key` is configured, the Agent's Vision tool automatically uses this model, with no need to specify it explicitly in the configuration file.
|
|
||||||
|
|
||||||
## Speech-to-Text (ASR)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"voice_to_text": "zhipu",
|
|
||||||
"voice_to_text_model": "glm-asr-2512"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `voice_to_text` | Set to `zhipu` to enable Zhipu ASR |
|
|
||||||
| `voice_to_text_model` | Optional, defaults to `glm-asr-2512` |
|
|
||||||
|
|
||||||
Credentials are automatically reused from `zhipu_ai_api_key`. Audio files should be smaller than 25MB; oversized files may be rejected by the server.
|
|
||||||
|
|
||||||
## Embedding
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"embedding_provider": "zhipu",
|
|
||||||
"embedding_model": "embedding-3"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Available models: `embedding-3`, `embedding-2`. After changing the embedding, run `/memory rebuild-index` to rebuild the index.
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
---
|
|
||||||
title: Models Overview
|
|
||||||
description: Model vendors supported by CowAgent and their capability matrix
|
|
||||||
---
|
|
||||||
|
|
||||||
CowAgent supports a wide range of mainstream large language models. Model interfaces live under the project's `models/` directory. Beyond text chat, several vendors also provide vision understanding, image generation, speech-to-text, text-to-speech, and embeddings — all of which can be invoked on demand in the Agent flow.
|
|
||||||
|
|
||||||
## Capability Matrix
|
|
||||||
|
|
||||||
A snapshot of each vendor's capabilities. "Text" refers to the main chat model; the remaining columns show which Agent capabilities the vendor can power.
|
|
||||||
|
|
||||||
| Vendor | Representative Models | Text | Vision | Image Gen | STT | TTS | Embedding |
|
|
||||||
| --- | --- | :-: | :-: | :-: | :-: | :-: | :-: |
|
|
||||||
| [DeepSeek](/en/models/deepseek) | deepseek-v4-flash / pro | ✅ | | | | | |
|
|
||||||
| [MiniMax](/en/models/minimax) | MiniMax-M2.7 | ✅ | ✅ | ✅ | | ✅ | |
|
|
||||||
| [Claude](/en/models/claude) | claude-opus-4-8 | ✅ | ✅ | | | | |
|
|
||||||
| [Gemini](/en/models/gemini) | gemini-3.5-flash | ✅ | ✅ | ✅ | | | |
|
|
||||||
| [OpenAI](/en/models/openai) | gpt-5.5, o-series | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
||||||
| [GLM](/en/models/glm) | glm-5.1, glm-5v-turbo | ✅ | ✅ | | ✅ | | ✅ |
|
|
||||||
| [Qwen](/en/models/qwen) | qwen3.7-max | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
||||||
| [Doubao](/en/models/doubao) | doubao-seed-2.0 series | ✅ | ✅ | ✅ | | | ✅ |
|
|
||||||
| [Kimi](/en/models/kimi) | kimi-k2.6 | ✅ | ✅ | | | | |
|
|
||||||
| [ERNIE](/en/models/qianfan) | ernie-5.1 | ✅ | ✅ | | | | |
|
|
||||||
| [MiMo](/en/models/mimo) | mimo-v2.5-pro / v2.5 | ✅ | ✅ | | | ✅ | |
|
|
||||||
| [LinkAI](/en/models/linkai) | 100+ models from multiple vendors | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
||||||
| [Custom](/en/models/custom) | Local models / third-party proxies | ✅ | | | | | |
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
Every capability in the Web console (Vision / Image / STT / TTS / Embedding / Web Search) can be configured independently with its own vendor and model — there is no forced binding between them.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## How to Configure
|
|
||||||
|
|
||||||
**Option 1 (recommended):** Manage models and capabilities online via the [Web console](/en/channels/web), with no need to edit the configuration file:
|
|
||||||
|
|
||||||
<img width="900" src="https://cdn.jsdelivr.net/gh/zhayujie/cowagent-assets@main/screenshots/en/web-console-models-config.png" />
|
|
||||||
|
|
||||||
**Option 2:** Edit `config.json` manually and fill in the model name and API key for the selected vendor. Every model also supports OpenAI-compatible access — just set `bot_type` to `openai` and configure `open_ai_api_base` and `open_ai_api_key`.
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
---
|
|
||||||
title: Kimi
|
|
||||||
description: Kimi (Moonshot) model configuration (Text Chat + Image Understanding)
|
|
||||||
---
|
|
||||||
|
|
||||||
Kimi is provided by Moonshot and supports both text chat and image understanding. The `kimi-k2.x` series natively supports vision.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
All capabilities below can be configured in one place via the "Model Management" page in the Web Console, with no need to manually edit the configuration file.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## Text Chat
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"model": "kimi-k2.6",
|
|
||||||
"moonshot_api_key": "YOUR_API_KEY"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `model` | Can be `kimi-k2.6`, `kimi-k2.5`, `kimi-k2`, `moonshot-v1-8k`, `moonshot-v1-32k`, `moonshot-v1-128k` |
|
|
||||||
| `moonshot_api_key` | Create one in the [Moonshot Console](https://platform.moonshot.cn/console/api-keys) |
|
|
||||||
| `moonshot_base_url` | Optional, defaults to `https://api.moonshot.cn/v1` |
|
|
||||||
|
|
||||||
## Image Understanding
|
|
||||||
|
|
||||||
Once `moonshot_api_key` is configured, the Agent's Vision tool automatically uses `kimi-k2.6` to recognize images, with no extra setup required.
|
|
||||||
|
|
||||||
To manually specify a Vision model:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"tools": {
|
|
||||||
"vision": {
|
|
||||||
"model": "kimi-k2.6"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
---
|
|
||||||
title: LinkAI
|
|
||||||
description: Access text, vision, image, speech, and embedding capabilities through the LinkAI platform
|
|
||||||
---
|
|
||||||
|
|
||||||
A single `linkai_api_key` gives you access to all capabilities of mainstream vendors such as OpenAI, Claude, Gemini, DeepSeek, MiniMax, Qwen, Kimi, and Doubao.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
All capabilities below can be configured in one place via the "Model Management" page in the Web Console, with no need to manually edit the configuration file.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## Text Chat
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"use_linkai": true,
|
|
||||||
"linkai_api_key": "YOUR_API_KEY"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `use_linkai` | Set to `true` to enable |
|
|
||||||
| `linkai_api_key` | Create one in the [Console](https://link-ai.tech/console/interface) |
|
|
||||||
| `model` | Can be any code from the [model list](https://link-ai.tech/console/models) |
|
|
||||||
|
|
||||||
See [Model Service](https://link-ai.tech/console/models) for more.
|
|
||||||
|
|
||||||
## Image Understanding
|
|
||||||
|
|
||||||
Once configured, the Agent's Vision tool automatically calls multimodal models via the gateway, with no extra setup required. To manually specify a Vision model:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"tools": {
|
|
||||||
"vision": {
|
|
||||||
"model": "gpt-5.4-mini"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Available models: `gpt-4.1-mini`, `gpt-5.4-mini`, `qwen3.6-plus`, `doubao-seed-2-0-pro-260215`, `kimi-k2.6`, `claude-sonnet-4-6`, `gemini-3.1-flash-lite-preview`, etc.
|
|
||||||
|
|
||||||
## Image Generation
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"skills": {
|
|
||||||
"image-generation": {
|
|
||||||
"model": "gpt-image-2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Model ID | Alias |
|
|
||||||
| --- | --- |
|
|
||||||
| `gpt-image-2` | OpenAI |
|
|
||||||
| `gemini-3.1-flash-image-preview` | Nano Banana 2 |
|
|
||||||
| `gemini-3-pro-image-preview` | Nano Banana Pro |
|
|
||||||
| `seedream-5.0-lite` | ByteDance Doubao Seedream |
|
|
||||||
|
|
||||||
## Speech-to-Text (ASR)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"voice_to_text": "linkai"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
ASR uses Whisper by default; credentials are automatically reused from `linkai_api_key`.
|
|
||||||
|
|
||||||
## Text-to-Speech (TTS)
|
|
||||||
|
|
||||||
The TTS gateway supports multiple underlying engines. The engine is selected by `text_to_voice_model`, and the available voices change with the engine.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"text_to_voice": "linkai",
|
|
||||||
"text_to_voice_model": "doubao",
|
|
||||||
"tts_voice_id": "BV001_streaming"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| `text_to_voice_model` | Engine |
|
|
||||||
| --- | --- |
|
|
||||||
| `tts-1` | OpenAI · Multi-language (voices like `alloy` / `nova` / `echo`, etc.) |
|
|
||||||
| `doubao` | ByteDance Doubao · Rich Chinese voices |
|
|
||||||
| `baidu` | Baidu · Chinese broadcaster voices |
|
|
||||||
|
|
||||||
Voices differ by engine; we recommend selecting them visually in the Web Console under "Model Management → Text-to-Speech".
|
|
||||||
|
|
||||||
## Embedding
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"embedding_provider": "linkai",
|
|
||||||
"embedding_model": "text-embedding-3-small"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The default model is `text-embedding-3-small` (OpenAI-compatible). After changing the embedding, run `/memory rebuild-index` to rebuild the index.
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
---
|
|
||||||
title: MiMo
|
|
||||||
description: Xiaomi MiMo model configuration (Text Chat + Image Understanding + Text-to-Speech)
|
|
||||||
---
|
|
||||||
|
|
||||||
Xiaomi MiMo is a native omni-modal large model. A single `mimo_api_key` enables text chat, image understanding, and text-to-speech all at once.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
All capabilities below can be configured in one place via the "Model Management" page in the Web Console — no need to manually edit the configuration file.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## Text Chat
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"model": "mimo-v2.5-pro",
|
|
||||||
"mimo_api_key": "YOUR_API_KEY",
|
|
||||||
"mimo_api_base": "https://api.xiaomimimo.com/v1"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `model` | Default recommendation: `mimo-v2.5-pro`; `mimo-v2.5` is also supported |
|
|
||||||
| `mimo_api_key` | Create one in the [MiMo Open Platform](https://platform.xiaomimimo.com/console/api-keys) |
|
|
||||||
| `mimo_api_base` | Optional, defaults to `https://api.xiaomimimo.com/v1` |
|
|
||||||
|
|
||||||
### Model Selection
|
|
||||||
|
|
||||||
| Model | Use Case |
|
|
||||||
| --- | --- |
|
|
||||||
| `mimo-v2.5-pro` | Flagship: native omni-modal + Agent capability, up to 1M tokens context |
|
|
||||||
| `mimo-v2.5` | General-purpose, native omni-modal (text / image / video / audio) |
|
|
||||||
|
|
||||||
## Thinking Mode
|
|
||||||
|
|
||||||
The MiMo V2.5 series enables "thinking mode" by default: the model emits `reasoning_content` (chain-of-thought) before the final answer, improving performance on complex tasks.
|
|
||||||
|
|
||||||
Use the global `enable_thinking` flag to toggle visibility (also switchable from the Web Console settings):
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"enable_thinking": true
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Image Understanding
|
|
||||||
|
|
||||||
Once `mimo_api_key` is configured, the Agent's Vision tool can automatically use MiMo's vision models:
|
|
||||||
|
|
||||||
- When the main model itself is multimodal (`mimo-v2.5-pro` / `mimo-v2.5`), images are handled directly by the main model with no extra setup.
|
|
||||||
- When the main model belongs to another vendor, the Vision tool falls back to `mimo-v2.5-pro` in order.
|
|
||||||
|
|
||||||
To force a specific Vision model, set it explicitly in the configuration:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"tools": {
|
|
||||||
"vision": {
|
|
||||||
"provider": "mimo",
|
|
||||||
"model": "mimo-v2.5-pro"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Text-to-Speech (TTS)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"text_to_voice": "mimo",
|
|
||||||
"text_to_voice_model": "mimo-v2.5-tts",
|
|
||||||
"tts_voice_id": "冰糖"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `text_to_voice_model` | Currently only `mimo-v2.5-tts` (preset voices + singing mode) |
|
|
||||||
| `tts_voice_id` | Preset voice name (Chinese voice IDs use the Chinese name directly) |
|
|
||||||
|
|
||||||
### Preset Voices
|
|
||||||
|
|
||||||
| Voice ID | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `Mia` | English · Female |
|
|
||||||
| `Chloe` | English · Female |
|
|
||||||
| `Milo` | English · Male |
|
|
||||||
| `Dean` | English · Male |
|
|
||||||
| `冰糖` | Chinese · Female (default) |
|
|
||||||
| `茉莉` | Chinese · Female |
|
|
||||||
| `苏打` | Chinese · Male |
|
|
||||||
| `白桦` | Chinese · Male |
|
|
||||||
|
|
||||||
|
|
||||||
You can also pick a voice visually from the Web Console under "Model Management → Text-to-Speech".
|
|
||||||
|
|
||||||
### Style Control
|
|
||||||
|
|
||||||
MiMo TTS supports embedding **audio tags** in the synthesis text to control emotion, tone, dialect, persona, and even singing. Tags must appear in the **text that will be synthesized to speech (i.e. the Agent's reply)**, with the overall style tag placed at the very beginning:
|
|
||||||
|
|
||||||
```
|
|
||||||
(style)content-to-synthesize
|
|
||||||
```
|
|
||||||
|
|
||||||
Half-width `()`, full-width `()`, and `[]` brackets are all accepted. Both Chinese and English style descriptors work — pick whichever language expresses the timbre most precisely. Common examples:
|
|
||||||
|
|
||||||
| Category | Example tags |
|
|
||||||
| --- | --- |
|
|
||||||
| Basic emotions | `happy` `sad` `angry` `fear` `surprised` `excited` `aggrieved` `calm` `indifferent` |
|
|
||||||
| Compound emotions | `wistful` `relieved` `helpless` `guilty` `at ease` `uneasy` `touched` |
|
|
||||||
| Overall tone | `gentle` `aloof` `lively` `serious` `languid` `playful` `deep` `sharp` `cutting` |
|
|
||||||
| Voice character | `magnetic` `mellow` `bright` `ethereal` `childlike` `aged` `sweet` `husky` |
|
|
||||||
| Persona | `squeaky` `mature lady` `young boy` `uncle` `Taiwanese accent` |
|
|
||||||
| Dialect | `Northeastern` `Sichuan` `Henan` `Cantonese` |
|
|
||||||
| Role-play | `Sun Wukong` `Lin Daiyu` |
|
|
||||||
| Singing | `sing` / `singing` |
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
- `(magnetic)The night is deep, and the city is still breathing.`
|
|
||||||
- `(gentle)Take a breath. You've got this.`
|
|
||||||
- `(serious)This is the final warning before the system reboots.`
|
|
||||||
- `(singing)Oh, when the saints go marching in…`
|
|
||||||
|
|
||||||
You can also insert fine-grained audio tags at any position in the text to control breathing, laughter, pauses, etc. For example:
|
|
||||||
|
|
||||||
```
|
|
||||||
(nervous, deep breath) Phew… stay calm, stay calm. (faster pace) I've rehearsed this intro fifty times, it'll be fine.
|
|
||||||
```
|
|
||||||
|
|
||||||
See the [MiMo speech synthesis documentation](https://platform.xiaomimimo.com/docs/zh-CN/usage-guide/speech-synthesis-v2.5) for the full tag list.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
When CowAgent calls TTS, the Agent's reply text (including any `(...)` tags) is forwarded directly to MiMo for synthesis. Tell the model in its persona / system prompt to "prefix replies with a `(style)` tag to control the tone", and IM channels (WeChat / Feishu / DingTalk / WeCom) will play voice replies with the corresponding emotion, dialect, or even singing.
|
|
||||||
</Tip>
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
---
|
|
||||||
title: MiniMax
|
|
||||||
description: MiniMax model configuration (Text / Image Understanding / Image Generation / Text-to-Speech)
|
|
||||||
---
|
|
||||||
|
|
||||||
MiniMax supports text chat, image understanding, image generation, and text-to-speech. A single `minimax_api_key` enables all capabilities.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
All capabilities below can be configured in one place via the "Model Management" page in the Web Console, with no need to manually edit the configuration file.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## Text Chat
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"model": "MiniMax-M2.7",
|
|
||||||
"minimax_api_key": "YOUR_API_KEY"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `model` | Can be `MiniMax-M2.7`, `MiniMax-M2.7-highspeed`, `MiniMax-M2.5`, `MiniMax-M2.1`, `MiniMax-M2.1-lightning`, `MiniMax-M2`, etc. |
|
|
||||||
| `minimax_api_key` | Create one in the [MiniMax Console](https://platform.minimaxi.com/user-center/basic-information/interface-key) |
|
|
||||||
|
|
||||||
## Image Understanding
|
|
||||||
|
|
||||||
MiniMax's M2.x chat models do not support vision natively; vision calls are uniformly routed to `MiniMax-Text-01`. Once `minimax_api_key` is configured, the Agent's Vision tool automatically uses this model, with no need to specify it explicitly in the configuration file.
|
|
||||||
|
|
||||||
## Image Generation
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"skills": {
|
|
||||||
"image-generation": {
|
|
||||||
"model": "image-01"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Available models: `image-01`.
|
|
||||||
|
|
||||||
## Text-to-Speech (TTS)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"text_to_voice": "minimax",
|
|
||||||
"text_to_voice_model": "speech-2.8-hd",
|
|
||||||
"tts_voice_id": "female-shaonv"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `text_to_voice_model` | `speech-2.8-hd` (emotional rendering, natural sound), `speech-2.8-turbo` (ultra-fast), `speech-2.6-hd`, `speech-2.6-turbo` |
|
|
||||||
| `tts_voice_id` | Voice ID; supports Chinese / Cantonese / English / Japanese / Korean — 70+ voices in total |
|
|
||||||
|
|
||||||
Common voice examples:
|
|
||||||
|
|
||||||
| Voice ID | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `female-shaonv` | Chinese · Young Girl (Female) |
|
|
||||||
| `female-yujie` | Chinese · Mature Lady (Female) |
|
|
||||||
| `female-tianmei` | Chinese · Sweet Female (Female) |
|
|
||||||
| `male-qn-jingying` | Chinese · Elite Youth (Male) |
|
|
||||||
| `male-qn-badao` | Chinese · Dominant Youth (Male) |
|
|
||||||
| `Cantonese_GentleLady` | Cantonese · Gentle Female Voice |
|
|
||||||
| `English_Graceful_Lady` | English · Graceful Lady |
|
|
||||||
|
|
||||||
For the full voice list (70+ voices across Chinese / Cantonese / English / Japanese / Korean), see the [system voice list](https://platform.minimaxi.com/docs/faq/system-voice-id), or select visually in the Web Console under "Model Management → Text-to-Speech".
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
---
|
|
||||||
title: OpenAI
|
|
||||||
description: OpenAI model configuration (Text / Vision / Image / Speech / Embedding)
|
|
||||||
---
|
|
||||||
|
|
||||||
OpenAI offers the most complete coverage and can simultaneously serve text chat, vision understanding, image generation, speech-to-text (ASR), text-to-speech (TTS), and embedding. A single `open_ai_api_key` lets the Agent use all of these capabilities.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
All capabilities below can be configured in one place via the "Model Management" page in the Web Console, with no need to manually edit the configuration file.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
|
|
||||||
## Text Chat
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"model": "gpt-5.5",
|
|
||||||
"open_ai_api_key": "YOUR_API_KEY",
|
|
||||||
"open_ai_api_base": "https://api.openai.com/v1"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `model` | Same as OpenAI's [model parameter](https://platform.openai.com/docs/models); supports `gpt-5.5`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.4-nano`, the `gpt-5` series, `gpt-4.1`, the o-series, etc. Agent mode defaults to `gpt-5.5`; use `gpt-5.4` for better cost-efficiency |
|
|
||||||
| `open_ai_api_key` | Create one on the [OpenAI Platform](https://platform.openai.com/api-keys) |
|
|
||||||
| `open_ai_api_base` | Optional; change it to access a third-party proxy |
|
|
||||||
| `bot_type` | Not required when using OpenAI's official models; set to `openai` when accessing other vendors via the compatible protocol |
|
|
||||||
|
|
||||||
## Image Understanding
|
|
||||||
|
|
||||||
OpenAI models like `gpt-5.5`, `gpt-5.4`, `gpt-4o`, and `gpt-4.1` natively support vision. Once `open_ai_api_key` is configured, the Agent's Vision tool automatically uses the main model to recognize images. If the main model does not support vision or you want to specify it explicitly, set it in the configuration file:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"tools": {
|
|
||||||
"vision": {
|
|
||||||
"model": "gpt-5.4-mini"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Supported Vision models: `gpt-5.5`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.4-nano`, `gpt-5`, `gpt-4.1`, `gpt-4.1-mini`, `gpt-4o`.
|
|
||||||
|
|
||||||
## Image Generation
|
|
||||||
|
|
||||||
Specify the image generation model in the configuration file; the Agent automatically routes image generation skill calls to OpenAI:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"skills": {
|
|
||||||
"image-generation": {
|
|
||||||
"model": "gpt-image-2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Supported image generation models: `gpt-image-2`, `gpt-image-1`.
|
|
||||||
|
|
||||||
## Speech-to-Text (ASR)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"voice_to_text": "openai",
|
|
||||||
"voice_to_text_model": "gpt-4o-mini-transcribe"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `voice_to_text` | Set to `openai` to enable OpenAI speech-to-text |
|
|
||||||
| `voice_to_text_model` | Optional, defaults to `gpt-4o-mini-transcribe`; can also be `gpt-4o-transcribe`, `whisper-1` |
|
|
||||||
|
|
||||||
Credentials are automatically reused from `open_ai_api_key`.
|
|
||||||
|
|
||||||
## Text-to-Speech (TTS)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"text_to_voice": "openai",
|
|
||||||
"text_to_voice_model": "tts-1",
|
|
||||||
"tts_voice_id": "alloy"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `text_to_voice_model` | `tts-1`, `tts-1-hd`, `gpt-4o-mini-tts` |
|
|
||||||
| `tts_voice_id` | Voices: `alloy`, `echo`, `fable`, `onyx`, `nova`, `shimmer`, `ash`, `ballad`, `coral`, `sage`, `verse` |
|
|
||||||
|
|
||||||
## Embedding
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"embedding_provider": "openai",
|
|
||||||
"embedding_model": "text-embedding-3-small"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Available models: `text-embedding-3-small`, `text-embedding-3-large`, `text-embedding-ada-002`. After changing the embedding, run `/memory rebuild-index` to rebuild the index.
|
|
||||||
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
---
|
|
||||||
title: ERNIE
|
|
||||||
description: ERNIE model configuration (Baidu Qianfan)
|
|
||||||
---
|
|
||||||
|
|
||||||
Option 1: Native integration (recommended):
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"model": "ernie-5.1",
|
|
||||||
"qianfan_api_key": "",
|
|
||||||
"qianfan_api_base": "https://qianfan.baidubce.com/v2"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `model` | Default recommendation: `ernie-5.1`; also supports `ernie-5.0`, `ernie-x1.1`, `ernie-4.5-turbo-128k`, `ernie-4.5-turbo-32k` |
|
|
||||||
| `qianfan_api_key` | Qianfan API key, usually starting with `bce-v3/` |
|
|
||||||
| `qianfan_api_base` | Optional, defaults to `https://qianfan.baidubce.com/v2` |
|
|
||||||
|
|
||||||
## Model Selection
|
|
||||||
|
|
||||||
| Model | Use Case |
|
|
||||||
| --- | --- |
|
|
||||||
| `ernie-5.1` | Default recommendation; latest ERNIE flagship with the strongest overall capability |
|
|
||||||
| `ernie-5.0` | Previous-generation flagship with excellent overall capability |
|
|
||||||
| `ernie-x1.1` | Deep-thinking reasoning model with lower hallucination and stronger instruction following / tool calling |
|
|
||||||
| `ernie-4.5-turbo-128k` | Long-context and general chat |
|
|
||||||
| `ernie-4.5-turbo-32k` | General chat with a balanced context window and cost |
|
|
||||||
|
|
||||||
## Vision tool
|
|
||||||
|
|
||||||
Once `qianfan_api_key` is configured, Agent mode can auto-discover Qianfan for the Vision tool:
|
|
||||||
|
|
||||||
- When the main model itself is multimodal (e.g. `ernie-5.1`, `ernie-5.0`, `ernie-x1.1`, `ernie-4.5-turbo-vl`), images are handled directly by the main model with no extra setup.
|
|
||||||
- When the main model is text-only (e.g. `ernie-4.5-turbo-128k`), the Vision tool automatically falls back to `ernie-4.5-turbo-vl`.
|
|
||||||
|
|
||||||
To force a specific Vision model, set it explicitly in `config.json`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"tools": {
|
|
||||||
"vision": {
|
|
||||||
"model": "ernie-4.5-turbo-vl"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Option 2: OpenAI-compatible configuration:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"model": "ernie-5.1",
|
|
||||||
"bot_type": "openai",
|
|
||||||
"open_ai_api_key": "",
|
|
||||||
"open_ai_api_base": "https://qianfan.baidubce.com/v2"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
Prefer `qianfan_api_key` for new configurations. Existing `wenxin`, `wenxin-4`, `baidu_wenxin_api_key`, and `baidu_wenxin_secret_key` configurations remain supported.
|
|
||||||
</Tip>
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
---
|
|
||||||
title: Qwen
|
|
||||||
description: Qwen model configuration (Text / Image Understanding / Image Generation / Speech-to-Text / Text-to-Speech / Embedding)
|
|
||||||
---
|
|
||||||
|
|
||||||
Qwen (Alibaba DashScope / Bailian) is one of the most fully-featured vendors. Text, image understanding, image generation, speech-to-text, text-to-speech, and embedding can all be enabled with a single `dashscope_api_key`.
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
All capabilities below can be configured in one place via the "Model Management" page in the Web Console, with no need to manually edit the configuration file.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
## Text Chat
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"model": "qwen3.6-plus",
|
|
||||||
"dashscope_api_key": "YOUR_API_KEY"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `model` | Can be `qwen3.6-plus`, `qwen3.7-max`, `qwen3.5-plus`, `qwen3-max`, `qwen-max`, `qwen-plus`, `qwen-turbo`, `qwq-plus`, etc. |
|
|
||||||
| `dashscope_api_key` | Create one in the [Bailian Console](https://bailian.console.aliyun.com/?tab=model#/api-key); see the [official docs](https://bailian.console.aliyun.com/?tab=api#/api) |
|
|
||||||
|
|
||||||
## Image Understanding
|
|
||||||
|
|
||||||
Once `dashscope_api_key` is configured, the Agent's Vision tool automatically calls Qwen's vision models to recognize images. Models like `qwen3-max` / `qwen3.5-plus` / `qwen3.6-plus` are already multimodal; if the main model is text-only (e.g. `qwen-turbo`), it automatically falls back to `qwen-vl-max`.
|
|
||||||
|
|
||||||
To manually specify a Vision model:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"tools": {
|
|
||||||
"vision": {
|
|
||||||
"model": "qwen3.6-plus"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Supported models: `qwen3.6-plus`, `qwen3.5-plus`, `qwen3-max`.
|
|
||||||
|
|
||||||
## Image Generation
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"skills": {
|
|
||||||
"image-generation": {
|
|
||||||
"model": "qwen-image-2.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Available models: `qwen-image-2.0`, `qwen-image-2.0-pro`.
|
|
||||||
|
|
||||||
## Speech-to-Text (ASR)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"voice_to_text": "dashscope",
|
|
||||||
"voice_to_text_model": "qwen3-asr-flash"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `voice_to_text` | Set to `dashscope` to enable Qwen ASR |
|
|
||||||
| `voice_to_text_model` | Optional, defaults to `qwen3-asr-flash` |
|
|
||||||
|
|
||||||
Credentials are automatically reused from `dashscope_api_key`. A single audio segment should be smaller than 10MB and no longer than 300 seconds.
|
|
||||||
|
|
||||||
## Text-to-Speech (TTS)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"text_to_voice": "dashscope",
|
|
||||||
"text_to_voice_model": "qwen3-tts-flash",
|
|
||||||
"tts_voice_id": "Cherry"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
| Parameter | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `text_to_voice_model` | Optional, defaults to `qwen3-tts-flash`; covers Mandarin, dialects, and major foreign languages |
|
|
||||||
| `tts_voice_id` | Voice ID; see the common list below |
|
|
||||||
|
|
||||||
Common voice examples:
|
|
||||||
|
|
||||||
| Voice ID | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `Cherry` | Qianyue · Sunny Female Voice |
|
|
||||||
| `Serena` | Suyao · Gentle Female Voice |
|
|
||||||
| `Ethan` | Chenxu · Sunny Male Voice |
|
|
||||||
| `Chelsie` | Qianxue · Anime Girl |
|
|
||||||
| `Dylan` | Beijing Dialect · Xiaodong |
|
|
||||||
| `Rocky` | Cantonese · Aqiang |
|
|
||||||
| `Sunny` | Sichuan Dialect · Qing'er |
|
|
||||||
|
|
||||||
The full voice list (Mandarin / regional dialects / bilingual, etc.) can be selected visually in the Web Console under "Model Management → Text-to-Speech".
|
|
||||||
|
|
||||||
## Embedding
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"embedding_provider": "dashscope",
|
|
||||||
"embedding_model": "text-embedding-v4"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The default model is `text-embedding-v4`. After changing the embedding, run `/memory rebuild-index` to rebuild the index.
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
---
|
|
||||||
title: Changelog
|
|
||||||
description: CowAgent version history
|
|
||||||
---
|
|
||||||
|
|
||||||
| Version | Date | Description |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| [2.0.9](/en/releases/v2.0.9) | 2026.05.22 | Model management console, MCP protocol support, browser persistent login, new models (gpt-5.5, gemini-3.5-flash, qwen3.7-max, etc.), deployment hardening |
|
|
||||||
| [2.0.8](/en/releases/v2.0.8) | 2026.05.06 | Major Feishu channel upgrade (voice, streaming and Markdown, one-click QR-scan setup), DeepSeek V4 and Baidu models, scheduler tool enhancements |
|
|
||||||
| [2.0.7](/en/releases/v2.0.7) | 2026.04.22 | Image Generation Skill (6-provider auto-routing), new models (Kimi K2.6, Claude Opus 4.7, GLM 5.1), knowledge base and Web Console improvements |
|
|
||||||
| [2.0.6](/en/releases/v2.0.6) | 2026.04.14 | Project rename, Knowledge Base system, Deep Dream Memory Distillation, Smart Context Compression, Web Console multi-session and various improvements |
|
|
||||||
| [2.0.5](/en/releases/v2.0.5) | 2026.04.01 | Cow CLI, Skill Hub open source, Browser tool, WeCom Bot QR scan, and more |
|
|
||||||
| [2.0.4](/en/releases/v2.0.4) | 2026.03.22 | Personal WeChat channel, new model support, Japanese docs, script refactoring and bug fixes |
|
|
||||||
| [2.0.3](/en/releases/v2.0.3) | 2026.03.18 | WeCom Smart Bot and QQ channels, Coding Plan support, multiple new models, Web file processing, memory system upgrade |
|
|
||||||
| [2.0.2](/en/releases/v2.0.2) | 2026.02.27 | Web Console upgrade, multi-channel concurrency, session persistence |
|
|
||||||
| [2.0.1](/en/releases/v2.0.1) | 2026.02.13 | Built-in Web Search tool, smart context management, multiple fixes |
|
|
||||||
| [2.0.0](/en/releases/v2.0.0) | 2026.02.03 | Full upgrade to AI super assistant |
|
|
||||||
| 1.7.6 | 2025.05.23 | Web Channel optimization, AgentMesh plugin |
|
|
||||||
| 1.7.5 | 2025.04.11 | DeepSeek model |
|
|
||||||
| 1.7.4 | 2024.12.13 | Gemini 2.0 model, Web Channel |
|
|
||||||
| 1.7.3 | 2024.10.31 | Stability improvements, database features |
|
|
||||||
| 1.7.2 | 2024.09.26 | One-click install script, o1 model |
|
|
||||||
| 1.7.0 | 2024.08.02 | iFlytek 4.0 model, knowledge base references |
|
|
||||||
| 1.6.9 | 2024.07.19 | gpt-4o-mini, Alibaba voice recognition |
|
|
||||||
| 1.6.8 | 2024.07.05 | Claude 3.5, Gemini 1.5 Pro |
|
|
||||||
| 1.6.0 | 2024.04.26 | Kimi integration, gpt-4-turbo upgrade |
|
|
||||||
| 1.5.8 | 2024.03.26 | GLM-4, Claude-3, edge-tts |
|
|
||||||
| 1.5.2 | 2023.11.10 | Feishu channel, image recognition chat |
|
|
||||||
| 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/CowAgent/releases) for full history.
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
---
|
|
||||||
title: v2.0.0
|
|
||||||
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/CowAgent/releases/tag/2.0.0)
|
|
||||||
|
|
||||||
## Key Updates
|
|
||||||
|
|
||||||
### Agent Core
|
|
||||||
|
|
||||||
- **Complex Task Planning**: Autonomous planning with multi-turn reasoning
|
|
||||||
- **Long-term Memory**: Persistent memory with keyword and vector search
|
|
||||||
- **Built-in Tools**: 10+ tools including file ops, Bash, browser, scheduler
|
|
||||||
- **Web search**: Built-in `web_search` tool, supports multiple search engines, configure corresponding API key to use
|
|
||||||
- **Skills System**: Skill engine with built-in and custom skill support
|
|
||||||
- **Security & Cost**: Secret management, prompt controls, token limits
|
|
||||||
|
|
||||||
### Other
|
|
||||||
|
|
||||||
- **Channels**: Feishu/DingTalk WebSocket support, image/file messages
|
|
||||||
- **Models**: claude-sonnet-4-5, gemini-3-pro-preview, glm-4.7, MiniMax-M2.1, qwen3-max
|
|
||||||
- **Deployment**: One-click install, configure, run, and management script
|
|
||||||
|
|
||||||
## Long-term Memory
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260203000455.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
## Task Planning & Tools
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260202181130.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260203121008.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260202195402.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
## Skills System
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260202202247.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260202213219.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260202234350.png" width="750" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Welcome to [submit feedback](https://github.com/zhayujie/CowAgent/issues) and [contribute code](https://github.com/zhayujie/CowAgent/pulls).
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
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/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/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/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/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/CowAgent/commit/051ffd78a372f71a967fd3259e37fe19131f83cf), [5264f7c](https://github.com/zhayujie/CowAgent/commit/5264f7ce18360ee4db5dcb4ebe67307977d40014))
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
---
|
|
||||||
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/CowAgent/compare/2.0.1...master)
|
|
||||||
|
|
||||||
## Highlights
|
|
||||||
|
|
||||||
### 🖥️ Web Console Upgrade
|
|
||||||
|
|
||||||
The Web Console has been fully upgraded with streaming conversation output, visual display of tool execution and reasoning processes, and online management of **models, skills, memory, channels, and Agent configuration**.
|
|
||||||
|
|
||||||
#### Chat Interface
|
|
||||||
|
|
||||||
Supports streaming output with real-time display of the Agent's reasoning process and tool calls, providing intuitive observation of the Agent's decision-making:
|
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227180120.png" />
|
|
||||||
|
|
||||||
#### Model Management
|
|
||||||
|
|
||||||
Manage model configurations online without manually editing config files:
|
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173811.png" />
|
|
||||||
|
|
||||||
#### Skill Management
|
|
||||||
|
|
||||||
View and manage Agent skills (Skills) online:
|
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173403.png" />
|
|
||||||
|
|
||||||
#### Memory Management
|
|
||||||
|
|
||||||
View and manage Agent memory online:
|
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173349.png" />
|
|
||||||
|
|
||||||
#### Channel Management
|
|
||||||
|
|
||||||
Manage connected channels online with real-time connect/disconnect operations:
|
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173331.png" />
|
|
||||||
|
|
||||||
#### Scheduled Tasks
|
|
||||||
|
|
||||||
View and manage scheduled tasks online, including one-time tasks, fixed intervals, and Cron expressions:
|
|
||||||
|
|
||||||
<img width="850" src="https://cdn.link-ai.tech/doc/20260227173704.png" />
|
|
||||||
|
|
||||||
#### Logs
|
|
||||||
|
|
||||||
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/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
|
|
||||||
|
|
||||||
Multiple channels (e.g., Feishu, DingTalk, WeCom, Web) can now run simultaneously, each in an independent thread without interference.
|
|
||||||
|
|
||||||
Configuration: Set multiple channels in `config.json` via `channel_type` separated by commas, or connect/disconnect channels in real-time from the Web Console's channel management page.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channel_type": "web,feishu,dingtalk"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
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/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/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
|
|
||||||
|
|
||||||
- **Official Website**: [cowagent.ai](https://cowagent.ai/)
|
|
||||||
- **Documentation**: [docs.cowagent.ai](https://docs.cowagent.ai/)
|
|
||||||
|
|
||||||
## Bug Fixes
|
|
||||||
|
|
||||||
- **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)
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
---
|
|
||||||
title: v2.0.3
|
|
||||||
description: CowAgent 2.0.3 - WeCom Smart Bot and QQ channels, Web Console file handling, memory system upgrade
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔌 New Channels
|
|
||||||
|
|
||||||
### WeCom Smart Bot
|
|
||||||
|
|
||||||
Added the WeCom Smart Bot (`wecom_bot`) channel with streaming card output, support for receiving and replying to text and image messages, and full configuration through the Web Console.
|
|
||||||
|
|
||||||
Documentation: [WeCom Smart Bot](https://docs.cowagent.ai/en/channels/wecom-bot).
|
|
||||||
|
|
||||||
Related commits: [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 Channel
|
|
||||||
|
|
||||||
Added the QQ official bot (`qq`) channel with support for text and image messages in both private chats and group chats.
|
|
||||||
|
|
||||||
Documentation: [QQ Bot](https://docs.cowagent.ai/en/channels/qq).
|
|
||||||
|
|
||||||
Related commits: [005a0e1](https://github.com/zhayujie/CowAgent/commit/005a0e1), [a4d54f5](https://github.com/zhayujie/CowAgent/commit/a4d54f5)
|
|
||||||
|
|
||||||
## 🖥️ Web Console File Input and Processing
|
|
||||||
|
|
||||||
The Web Console chat UI now supports file and image uploads — files can be sent directly to the agent for processing. The Read tool gains parsing support for Office documents (Word, Excel, PPT).
|
|
||||||
|
|
||||||
Related commits: [30c6d9b](https://github.com/zhayujie/CowAgent/commit/30c6d9b)
|
|
||||||
|
|
||||||
## 🤖 New Models
|
|
||||||
|
|
||||||
- **GPT-5.4 Series**: Added `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**: Added `gemini-3.1-flash-lite-preview` ([ba915f2](https://github.com/zhayujie/CowAgent/commit/ba915f2))
|
|
||||||
|
|
||||||
## 💰 Coding Plan Support
|
|
||||||
|
|
||||||
Added integration with vendor Coding Plan (monthly programming subscription) tiers via the unified OpenAI-compatible path. Supported vendors include Aliyun, MiniMax, GLM, Kimi, and Volcengine.
|
|
||||||
|
|
||||||
See [Coding Plan docs](https://docs.cowagent.ai/en/models/coding-plan) for detailed configuration.
|
|
||||||
|
|
||||||
## 🧠 Memory System Upgrade
|
|
||||||
|
|
||||||
Memory flush improvements:
|
|
||||||
|
|
||||||
- Use the LLM to summarize out-of-window conversations into compact daily memory entries
|
|
||||||
- Summarization runs asynchronously on a background thread, never blocking replies
|
|
||||||
- Smarter batch trimming policy reduces flush frequency
|
|
||||||
- Daily scheduled flush as a safety net for low-activity scenarios
|
|
||||||
- Fixed context-memory loss issues
|
|
||||||
|
|
||||||
Related commits: [022c13f](https://github.com/zhayujie/CowAgent/commit/022c13f), [c116235](https://github.com/zhayujie/CowAgent/commit/c116235)
|
|
||||||
|
|
||||||
## 🔧 Tool Refactoring
|
|
||||||
|
|
||||||
- **Image Vision**: Image recognition (Vision) is refactored from a Skill into a built-in Tool with a dedicated Vision Provider configuration, improving stability and maintainability ([a50fafa](https://github.com/zhayujie/CowAgent/commit/a50fafa), [3b8b562](https://github.com/zhayujie/CowAgent/commit/3b8b562))
|
|
||||||
- **Web Fetch**: Web fetch is refactored from a Skill into a built-in Tool with support for downloading and parsing remote documents (PDF, Word, Excel, PPT) ([ccb9030](https://github.com/zhayujie/CowAgent/commit/ccb9030), [fa61744](https://github.com/zhayujie/CowAgent/commit/fa61744))
|
|
||||||
|
|
||||||
## 🐳 Docker Deployment Improvements
|
|
||||||
|
|
||||||
- **Config Template Alignment**: `docker-compose.yml` env vars aligned with `config-template.json`, covering full model API key and Agent settings
|
|
||||||
- **Web Console Port Mapping**: Added `9899` port mapping so the Web Console is reachable in browser after Docker deployment
|
|
||||||
- **Hot Config Reload**: Bot API key and API base are now read at request time — changes from the Web Console take effect without restart
|
|
||||||
- **Workspace Persistence**: Added a `./cow` volume mount so agent workspace data (memories, persona, skills, etc.) persists across container rebuilds and upgrades
|
|
||||||
|
|
||||||
## ⚡ Performance Improvements
|
|
||||||
|
|
||||||
- **Faster Startup**: The Feishu channel imports its dependencies lazily, avoiding a 4–10s startup delay ([924dc79](https://github.com/zhayujie/CowAgent/commit/924dc79))
|
|
||||||
- **Channel Stability**: Improved channel connection stability and added env-var support for channel configuration ([f1c04bc](https://github.com/zhayujie/CowAgent/commit/f1c04bc), [46d97fd](https://github.com/zhayujie/CowAgent/commit/46d97fd))
|
|
||||||
|
|
||||||
## 🐛 Bug Fixes
|
|
||||||
|
|
||||||
- **bot_type Propagation**: Fixed `bot_type` propagation under Agent mode ([#2691](https://github.com/zhayujie/CowAgent/pull/2691)) Thanks [@Weikjssss](https://github.com/Weikjssss)
|
|
||||||
- **bot_type Resolution Priority**: Adjusted `bot_type` resolution priority under Agent mode ([#2692](https://github.com/zhayujie/CowAgent/pull/2692)) Thanks [@6vision](https://github.com/6vision)
|
|
||||||
- **Zhipu Config**: Fixed Zhipu `bot_type` naming, Web Console persistence, and regex escaping ([#2693](https://github.com/zhayujie/CowAgent/pull/2693)) Thanks [@6vision](https://github.com/6vision)
|
|
||||||
- **OpenAI-Compat Layer**: Unified error handling via the `openai_compat` layer ([#2688](https://github.com/zhayujie/CowAgent/pull/2688)) Thanks [@JasonOA888](https://github.com/JasonOA888)
|
|
||||||
- **OpenAI-Compat Migration**: Completed the `openai_compat` migration across all model bots ([#2689](https://github.com/zhayujie/CowAgent/pull/2689))
|
|
||||||
- **Gemini Tool Calling**: Fixed tool-call matching for Gemini ([eda82ba](https://github.com/zhayujie/CowAgent/commit/eda82ba))
|
|
||||||
- **Session Concurrency**: Fixed race conditions in concurrent session scenarios ([9879878](https://github.com/zhayujie/CowAgent/commit/9879878))
|
|
||||||
- **History Recovery**: Fixed incomplete history recovery — only user/assistant text messages are restored, tool calls are stripped ([b788a3d](https://github.com/zhayujie/CowAgent/commit/b788a3d), [a33ce97](https://github.com/zhayujie/CowAgent/commit/a33ce97))
|
|
||||||
- **Feishu Group Chat**: Removed the `bot_name` dependency for Feishu group chats ([b641bff](https://github.com/zhayujie/CowAgent/commit/b641bff))
|
|
||||||
- **Safari Compatibility**: Fixed an IME Enter key issue that mistakenly sent messages on Safari ([0687916](https://github.com/zhayujie/CowAgent/commit/0687916))
|
|
||||||
- **Windows Compatibility**: Fixed bash-style `$VAR` to `%VAR%` env-var conversion on Windows ([7c67513](https://github.com/zhayujie/CowAgent/commit/7c67513))
|
|
||||||
- **MiniMax Params**: Added a `max_tokens` cap for MiniMax models ([1767413](https://github.com/zhayujie/CowAgent/commit/1767413))
|
|
||||||
- **.gitignore**: Added Python directory ignore rules ([#2683](https://github.com/zhayujie/CowAgent/pull/2683)) Thanks [@pelioo](https://github.com/pelioo)
|
|
||||||
- **AGENT.md Proactive Evolution**: Improved the system prompt guidance around AGENT.md — instead of waiting for explicit user edits, the agent now proactively detects persona/style shifts in the conversation and updates AGENT.md accordingly
|
|
||||||
|
|
||||||
## 📦 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/en/guide/upgrade) for details.
|
|
||||||
|
|
||||||
**Release Date**: 2026.03.18 | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.2...2.0.3)
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
---
|
|
||||||
title: v2.0.4
|
|
||||||
description: CowAgent 2.0.4 - Personal WeChat channel, new model support, Japanese docs, script refactoring and bug fixes
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔌 Personal WeChat Channel
|
|
||||||
|
|
||||||
Added personal WeChat (`weixin`) channel — the most important update in this release. Simply scan a QR code to connect CowAgent to your personal WeChat account, with support for:
|
|
||||||
|
|
||||||
- **Messaging**: Send and receive text, image, file, and video messages; receive voice messages
|
|
||||||
- **QR Code Login**: QR code displayed in terminal, scan with WeChat to log in; auto-refresh on expiry
|
|
||||||
- **Credential Persistence**: Login credentials saved to `~/.weixin_cow_credentials.json` automatically, no re-scan needed on restart
|
|
||||||
- **Session Auto-Reconnect**: Automatically clears expired credentials and re-initiates QR code login
|
|
||||||
- **Web Console Integration**: Add WeChat channel from the Web Console with synchronized QR code login flow
|
|
||||||
- **Docker & Script Support**: Both `run.sh` and `docker-compose.yml` now support the WeChat channel
|
|
||||||
|
|
||||||
Documentation: [WeChat Channel](https://docs.cowagent.ai/channels/weixin).
|
|
||||||
|
|
||||||
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/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/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/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/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/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/CowAgent/compare/2.0.3...master)
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
---
|
|
||||||
title: v2.0.5
|
|
||||||
description: CowAgent 2.0.5 - Cow CLI, Skill Hub open source, Browser tool, WeCom Bot QR scan, and more
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🖥️ Cow CLI
|
|
||||||
|
|
||||||
New CLI command system for managing CowAgent from terminal and chat:
|
|
||||||
|
|
||||||
- **Terminal commands**: Run `cow <command>` for `start`, `stop`, `restart`, `update`, `status`, `logs`, etc.
|
|
||||||
- **Chat commands**: Type `/<command>` in conversation for `/help`, `/status`, `/config`, `/skill`, `/context`, `/logs`, `/version`, etc.
|
|
||||||
- **Web console**: Type `/` in the input box to open a slash command menu, with arrow-key input history
|
|
||||||
- **Windows support**: New PowerShell script `scripts/run.ps1` with `cow` command support
|
|
||||||
|
|
||||||
Docs: [Command Overview](https://docs.cowagent.ai/en/cli)
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260401114549.png" width="750" />
|
|
||||||
|
|
||||||
## 🧩 Cow Skill Hub Open Source
|
|
||||||
|
|
||||||
[Cow Skill Hub](https://skills.cowagent.ai) is now open source and live — browse, search, install, and publish AI Agent skills:
|
|
||||||
|
|
||||||
- **One-command install**: `/skill install <name>` in chat or `cow skill install <name>` in terminal
|
|
||||||
- **Multi-source**: Install from Skill Hub, GitHub, ClawHub, LinkAI, and more
|
|
||||||
- **Search**: `/skill search` and `/skill list --remote` to browse the hub
|
|
||||||
- **Publish**: Submit your own skills at [skills.cowagent.ai/submit](https://skills.cowagent.ai/submit)
|
|
||||||
- **Mirror**: Mirror acceleration for faster downloads in China
|
|
||||||
|
|
||||||
Open source repo: [cow-skill-hub](https://github.com/zhayujie/cow-skill-hub)
|
|
||||||
|
|
||||||
Docs: [Skill Hub](https://docs.cowagent.ai/en/skills/hub), [Install Skills](https://docs.cowagent.ai/en/skills/install)
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260401110103.png" width="750" />
|
|
||||||
|
|
||||||
## 🌐 Browser Tool
|
|
||||||
|
|
||||||
New Browser tool — Agent can control a Chromium browser to visit and interact with web pages:
|
|
||||||
|
|
||||||
- **Navigation & interaction**: `navigate`, `click`, `fill`, `select`, `scroll`, `press`, etc.
|
|
||||||
- **Page snapshot**: Compact DOM snapshot for efficient page understanding, auto-snapshot after navigation
|
|
||||||
- **Screenshot**: Save page screenshots to workspace
|
|
||||||
- **JavaScript execution**: Run custom scripts on pages
|
|
||||||
- **CLI install**: `cow install-browser` for one-command setup
|
|
||||||
- **Docker support**: Browser install built into Docker image
|
|
||||||
|
|
||||||
Docs: [Browser Tool](https://docs.cowagent.ai/en/tools/browser)
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260401115728.png" width="750" />
|
|
||||||
|
|
||||||
## 🤖 WeCom Bot QR Code Setup
|
|
||||||
|
|
||||||
WeCom Bot channel now supports QR code scan for one-click bot creation:
|
|
||||||
|
|
||||||
- **QR scan in Web console**: Select "Scan QR" mode, scan with WeCom to auto-create and connect a bot — no manual configuration needed
|
|
||||||
- **Manual mode**: Still supports manual Bot ID and Secret input
|
|
||||||
- **Stream push optimization**: Throttled push to avoid WebSocket congestion
|
|
||||||
|
|
||||||
Docs: [WeCom Bot](https://docs.cowagent.ai/en/channels/wecom-bot)
|
|
||||||
|
|
||||||
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/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/CowAgent/compare/2.0.4...master)
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
---
|
|
||||||
title: v2.0.6
|
|
||||||
description: CowAgent 2.0.6 - Knowledge Base, Deep Dream Memory Distillation, Smart Context Compression, Web Console Multi-Session and More
|
|
||||||
---
|
|
||||||
|
|
||||||
## Project Renamed to CowAgent
|
|
||||||
|
|
||||||
The repository has been officially renamed from `chatgpt-on-wechat` to **CowAgent**, evolving into a full-featured AI Agent assistant.
|
|
||||||
|
|
||||||
- New URL: [github.com/zhayujie/CowAgent](https://github.com/zhayujie/CowAgent) — GitHub auto-redirects the old URL
|
|
||||||
- CLI commands, config files, and documentation links remain compatible — no extra steps needed
|
|
||||||
|
|
||||||
## 📚 Knowledge Base
|
|
||||||
|
|
||||||
New personal knowledge base system — Agent can autonomously build and maintain structured knowledge, retrieving it on demand during conversations:
|
|
||||||
|
|
||||||
- **Index-driven self-organizing structure**: Knowledge is stored in `knowledge/` directory, auto-organized by category, with each knowledge page as an independent Markdown file
|
|
||||||
- **Auto-write**: Send files, links, or other knowledge to the Agent, or it will automatically create/update knowledge pages when valuable information is identified in conversation
|
|
||||||
- **Hybrid retrieval**: Supports keyword full-text search and vector semantic retrieval, loading relevant knowledge on demand during conversations
|
|
||||||
- **Visualization**: File tree browsing and knowledge graph visualization, with in-document links for direct navigation
|
|
||||||
- **Command management**: `/knowledge` for stats, `/knowledge list` for directory structure, `/knowledge on|off` to toggle
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260413105435.png" width="750" />
|
|
||||||
|
|
||||||
|
|
||||||
Docs: [Knowledge Base](https://docs.cowagent.ai/en/knowledge)
|
|
||||||
|
|
||||||
## 🌙 Deep Dream Memory Distillation
|
|
||||||
|
|
||||||
A new memory consolidation mechanism that automatically distills scattered conversation memories into refined long-term memory daily:
|
|
||||||
|
|
||||||
- **Three-tier memory flow**: Conversation context (short-term) → Daily memory (mid-term) → MEMORY.md (long-term), forming a complete memory lifecycle
|
|
||||||
- **Auto-distillation**: Runs daily at 23:55, reads the day's daily memory and MEMORY.md, performs deduplication, merging, and pruning via LLM, outputting a refined MEMORY.md
|
|
||||||
- **Dream diary**: Each distillation generates a narrative-style dream diary recording discoveries and insights, stored in `memory/dreams/`
|
|
||||||
- **Manual trigger**: `/memory dream [N]` to manually trigger with configurable lookback days (default 3, max 30), with chat notification on completion
|
|
||||||
- **Web console**: Memory management page now includes a "Dream Diary" tab for browsing all dream diaries
|
|
||||||
|
|
||||||
Docs: [Deep Dream](https://docs.cowagent.ai/en/memory/deep-dream)
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260414120158.png" width="750" />
|
|
||||||
|
|
||||||
## 🧠 Smart Context Compression
|
|
||||||
|
|
||||||
When context exceeds limits, trimmed portions are summarized by LLM and asynchronously injected to maintain conversation continuity:
|
|
||||||
|
|
||||||
- **Async LLM summary**: Trimmed messages are summarized into key information by LLM, written to daily memory files and injected into retained context
|
|
||||||
- **Multi-model compatible**: Uses the primary model for summarization, compatible with Claude, OpenAI, MiniMax and other model message format requirements
|
|
||||||
|
|
||||||
Docs: [Short-term Memory](https://docs.cowagent.ai/en/memory/context)
|
|
||||||
|
|
||||||
## 💬 Web Console Upgrades
|
|
||||||
|
|
||||||
Multiple enhancements to the Web console:
|
|
||||||
|
|
||||||
- **Multi-session management**: Create and switch between independent sessions, sidebar session list with auto-generated and manually editable titles
|
|
||||||
- **Password protection**: Set a login password via `web_console_password` config option
|
|
||||||
- **Deep thinking**: Display model thinking process in Web console, controlled by `enable_thinking` config option
|
|
||||||
- **Scheduled push**: Scheduled task results can be pushed to Web console
|
|
||||||
- **Message copy**: One-click copy of raw Markdown content from AI reply bubbles
|
|
||||||
- **Language toggle**: Top language switch button now shows current language for more intuitive interaction
|
|
||||||
|
|
||||||
## 🤖 Model Updates
|
|
||||||
|
|
||||||
- **Vision optimization**: Image recognition tool prefers the primary model with automatic multi-provider fallback. Docs: [Vision Tool](https://docs.cowagent.ai/en/tools/vision)
|
|
||||||
- **MiniMax new model**: Added MiniMax-M2.7-highspeed model and MiniMax TTS voice synthesis support. Thanks @octo-patch
|
|
||||||
- **Qwen**: Added qwen3.6-plus model support
|
|
||||||
|
|
||||||
## 🐛 Other Improvements & Fixes
|
|
||||||
|
|
||||||
- **Memory prompts**: `MEMORY.md` injected into system prompt by default, with refined memory retrieval and write trigger conditions for enhanced proactive writing
|
|
||||||
- **System prompt**: Optimized system prompt style and tone guidance
|
|
||||||
- **Browser tool**: Enhanced implicit interactive element detection
|
|
||||||
- **File send**: Fixed common file types (tar.gz, zip, etc.) not being sent correctly. Thanks @6vision
|
|
||||||
- **macOS compatibility**: Fixed network pre-check timeout compatibility issue. Thanks @Moliang Zhou
|
|
||||||
- **Windows compatibility**: Fixed PowerShell compatibility, process updates, terminal encoding and other issues on Windows
|
|
||||||
- **Python 3.13+**: Fixed missing `legacy-cgi` dependency for Python 3.13+
|
|
||||||
- **WeChat channel**: Updated personal WeChat channel version
|
|
||||||
|
|
||||||
## 📦 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.14 | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.5...master)
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
---
|
|
||||||
title: v2.0.7
|
|
||||||
description: CowAgent 2.0.7 - Image Generation Skill (6-provider auto-routing), new models, knowledge base enhancements, Web Console improvements and bug fixes
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎨 Image Generation Skill
|
|
||||||
|
|
||||||
New built-in `image-generation` skill supporting text-to-image, image-to-image, and multi-image fusion across six major providers:
|
|
||||||
|
|
||||||
- **6-provider auto-routing**: OpenAI (GPT-Image-2) → Gemini (Nano Banana) → Seedream (Volcengine Ark) → Qwen (DashScope) → MiniMax → LinkAI — automatically selects from configured providers in fixed priority order, with automatic fallback on failure
|
|
||||||
- **Zero model selection**: Just configure an API key and it works — no need to manually specify a model. You can also name a specific model in conversation (e.g. "draw a cat with seedream")
|
|
||||||
- **Flexible control**: Supports `quality`, `size` (512/1K–4K), and `aspect_ratio` parameters, with each provider automatically mapping to its supported values
|
|
||||||
- **Image editing**: Pass existing images for editing, style transfer, or multi-image fusion (Seedream supports up to 14 reference images)
|
|
||||||
- **Skill-level config**: Pin a default model via `skills.image-generation.model` in `config.json`
|
|
||||||
- **Image lightbox**: All images in the Web console now support click-to-enlarge preview
|
|
||||||
|
|
||||||
Docs: [Image Generation Skill](https://docs.cowagent.ai/en/skills/image-generation)
|
|
||||||
|
|
||||||
## 🤖 New Model Support
|
|
||||||
|
|
||||||
- **Kimi K2.6**: Added `kimi-k2.6` model support
|
|
||||||
- **Claude Opus 4.7**: Added `claude-opus-4-7` model support
|
|
||||||
- **GLM 5.1**: Added `glm-5.1` model support
|
|
||||||
- **Kimi Coding Plan**: Support for Kimi Coding Plan mode
|
|
||||||
- **Custom model providers**: New custom model provider configuration for easier integration with additional vendors
|
|
||||||
|
|
||||||
## 💬 Web Console Improvements
|
|
||||||
|
|
||||||
- **Smart auto-scroll**: Improved chat scroll behaviour — no longer forces scroll to bottom while the user is reading earlier messages
|
|
||||||
- **Reasoning content cap**: Deep thinking content capped at 4 KB to prevent frontend lag
|
|
||||||
- **Mobile optimisation**: Session sidebar hidden by default on mobile, with overlay dismiss support
|
|
||||||
- **Session title fix**: Fixed title auto-generation fallback logic and Bridge reset on config change
|
|
||||||
- **Image preview dedup**: Fixed duplicate image rendering within the same message
|
|
||||||
|
|
||||||
## 📚 Knowledge Base Enhancements
|
|
||||||
|
|
||||||
- **Nested directory support**: Knowledge base listing and display now support multi-level nested directories
|
|
||||||
- **Root-level file display**: Show `index.md`, `log.md` and other root-level files in the knowledge tree
|
|
||||||
- **Empty state stats fix**: Root-level files no longer interfere with empty-state detection
|
|
||||||
|
|
||||||
## 🌙 Dream Memory Improvements
|
|
||||||
|
|
||||||
- **Structured organisation**: Dream memory files are now auto-archived by date with a cleaner directory structure
|
|
||||||
- **Schedule jitter**: Daily dream trigger includes random jitter to avoid concurrency conflicts in cluster deployments
|
|
||||||
|
|
||||||
## 🛠 Skill System Improvements
|
|
||||||
|
|
||||||
- **Skill manager refresh**: `/skill` commands now automatically refresh the skill manager to keep state in sync
|
|
||||||
- **Installation sources**: Skill installation supports multiple source formats (URL, zip, local file, etc.) with automatic target directory handling
|
|
||||||
|
|
||||||
## 🐛 Other Fixes
|
|
||||||
|
|
||||||
- **Gemini fix**: Fixed Gemini tool calls not returning results
|
|
||||||
- **Agent retry**: Empty-response retries no longer drop `tool_calls`
|
|
||||||
- **Docker env sync**: Fixed environment variables not syncing after config update in Docker environments
|
|
||||||
- **Python 3.7 compat**: Deferred `Literal` import for Python 3.7 compatibility
|
|
||||||
- **Model switch notification**: Fixed bot_type change notification not showing after model switch. Thanks @6vision
|
|
||||||
- **Config command**: `/config` now supports setting `enable_thinking`
|
|
||||||
- **Thinking display**: Deep thinking display disabled by default
|
|
||||||
|
|
||||||
## 📦 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.22 | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.6...master)
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
---
|
|
||||||
title: v2.0.8
|
|
||||||
description: CowAgent 2.0.8 - Major Feishu channel upgrade (voice, streaming typewriter, one-click QR app creation), DeepSeek V4 / ERNIE 5.0 support, scheduler memory enhancements and multiple fixes
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🪶 Major Feishu Channel Upgrade
|
|
||||||
|
|
||||||
### 1. One-click QR-scan App Creation
|
|
||||||
|
|
||||||
No more manual app setup, permission scopes and event subscriptions in the Feishu Open Platform. When `feishu_app_id` is not configured, both the Web Console and CLI startup flow now show a QR-scan entry — scan with Feishu, authorize, and the bot is created and config is filled back automatically. Out-of-the-box.
|
|
||||||
|
|
||||||
Documentation: [Feishu Channel](https://docs.cowagent.ai/en/channels/feishu)
|
|
||||||
|
|
||||||
### 2. Voice Messages
|
|
||||||
|
|
||||||
Receive Feishu voice messages with automatic speech-to-text, and reply in voice via TTS. Recognition accuracy for short Chinese voice messages has been improved.
|
|
||||||
|
|
||||||
### 3. Streaming Typewriter Replies
|
|
||||||
|
|
||||||
Integrated with Feishu CardKit streaming cards, **enabled by default**, matching the Web Console experience:
|
|
||||||
|
|
||||||
- Multi-turn agent flows render intermediate updates and the final reply on separate cards
|
|
||||||
- Tuned for high-throughput models like DeepSeek to keep pace with the Web Console
|
|
||||||
- Falls back to plain text replies automatically when not supported, no manual config needed
|
|
||||||
- Requires Feishu client ≥ 7.20
|
|
||||||
|
|
||||||
The voice and streaming building blocks come from a community contribution #2791. Thanks [@yangluxin613](https://github.com/yangluxin613)
|
|
||||||
|
|
||||||
## 🤖 New Model Support
|
|
||||||
|
|
||||||
- **DeepSeek V4 series**: Added `deepseek-v4-pro` / `deepseek-v4-flash`, with `deepseek-v4-flash` set as the new default
|
|
||||||
- **Unified thinking-mode toggle**: DeepSeek V4, Qwen3 and other thinking-capable models now share the same `enable_thinking` switch
|
|
||||||
- **ERNIE first-class integration**: New `qianfan` provider supporting `ernie-5.0` (default recommendation), `ernie-x1.1`, `ernie-4.5-turbo-128k`, `ernie-4.5-turbo-32k`. Dedicated `qianfan_api_key` / `qianfan_api_base` settings keep OpenAI config clean; legacy `wenxin` / `wenxin-4` paths are fully preserved. #2790 Thanks [@jimmyzhuu](https://github.com/jimmyzhuu)
|
|
||||||
|
|
||||||
Documentation: [ERNIE](https://docs.cowagent.ai/en/models/qianfan)
|
|
||||||
|
|
||||||
## 🌐 Translation Provider
|
|
||||||
|
|
||||||
- **Youdao translator**: Added a Youdao provider to the `translate/` module using the v3 SHA-256 signing scheme, with automatic ISO 639-1 language-code mapping (`zh`, `zh-TW`, etc.) #2797 Thanks [@Zmjjeff7](https://github.com/Zmjjeff7)
|
|
||||||
|
|
||||||
## 🛠 OpenAI Client Refactor
|
|
||||||
|
|
||||||
- **Drop SDK dependency**: The OpenAI bot is reimplemented on a native HTTP client — leaner startup, fewer dependency conflicts
|
|
||||||
- **Web Console hint**: API base inputs in the model config UI now include version-path placeholder hints
|
|
||||||
|
|
||||||
## ⏰ Scheduler Memory Enhancements
|
|
||||||
|
|
||||||
- **Follow-up on task results**: Scheduled task results are automatically injected into the receiver's session history — the next turn can ask follow-up questions without re-stating context. Thanks [@huangrichao2020](https://github.com/huangrichao2020)
|
|
||||||
- **No long-term memory pollution**: Scheduler-injected pairs are excluded from the daily memory flush so high-frequency tasks don't drown the memory store
|
|
||||||
- **Bounded scheduler context**: The scheduler's own session context is automatically capped, so long-running periodic tasks don't accumulate state and slow down replies
|
|
||||||
|
|
||||||
## 🔧 Tools and Safety
|
|
||||||
|
|
||||||
- **Vision model selection**: `tools.vision.model` config now actually takes effect, with automatic fallback when unconfigured #2792
|
|
||||||
- **Bash safety prompt**: The destructive-deletion confirm prompt is now scoped to paths outside the workspace — routine in-workspace operations are no longer interrupted
|
|
||||||
|
|
||||||
## 🐛 Other Fixes
|
|
||||||
|
|
||||||
- Fixed Deep Dream firing duplicate runs in multi-instance setups
|
|
||||||
- Fixed missing `reasoning_content` on some history turns in DeepSeek multi-turn conversations
|
|
||||||
|
|
||||||
## 📦 Upgrade
|
|
||||||
|
|
||||||
Source-code deployments can run `cow update` or `./run.sh update` for a one-click upgrade, or pull the latest code and restart manually. See [Upgrade Guide](https://docs.cowagent.ai/en/guide/upgrade) for details.
|
|
||||||
|
|
||||||
> ⚠️ One-click Feishu app creation requires `lark-oapi>=1.5.5`. `cow update` pulls it automatically; manual deployments must update dependencies.
|
|
||||||
|
|
||||||
**Release Date**: 2026.05.05 | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.7...2.0.8)
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
---
|
|
||||||
title: v2.0.9
|
|
||||||
description: CowAgent 2.0.9 - Web Console model management, MCP protocol support, browser persistent login, new models and deployment hardening
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🖥️ Model Management Console
|
|
||||||
|
|
||||||
The Web Console adds a new **Models** page that organizes everything by **provider × capability**, covering chat, image, voice, embedding and search models in one place:
|
|
||||||
|
|
||||||
- **Per-provider configuration**: Each provider's API Key / API Base is configured once at the top, and every capability below picks it up automatically — no more re-entering credentials
|
|
||||||
- **Image models**: Image understanding and image generation can each pick their own provider and model independently; falls back to the main model when unspecified
|
|
||||||
- **Voice models**: ASR (speech-to-text) and TTS (text-to-speech) can be configured independently, with new Qwen and Zhipu ASR/TTS models added
|
|
||||||
- **Embedding models**: Configurable embedding models (used for memory and knowledge-base retrieval), with new support for OpenAI, Tongyi, Doubao, Zhipu and others; run `/memory rebuild-index` after switching to rebuild the index online
|
|
||||||
- **Search capability**: Web search has been upgraded to support Bocha, Baidu, Zhipu and more providers — in auto mode the agent can synthesize results from multiple sources for deeper research
|
|
||||||
|
|
||||||
Documentation: [Models Overview](https://docs.cowagent.ai/en/models)
|
|
||||||
|
|
||||||
<img width="720" alt="20260522113305" src="https://cdn.jsdelivr.net/gh/zhayujie/cowagent-assets@main/screenshots/en/web-console-models-config.png" />
|
|
||||||
|
|
||||||
|
|
||||||
## 🧩 MCP Protocol Support
|
|
||||||
|
|
||||||
Adds support for **MCP (Model Context Protocol)**, expanding from a fixed built-in toolset to an open, pluggable tool ecosystem — any MCP-compatible service can be plugged in directly as an agent tool.
|
|
||||||
|
|
||||||
- Native JSON-RPC implementation, zero extra dependencies, supports both `stdio` and `sse` transports
|
|
||||||
- Compatible with the `mcpServers` configuration style used by Claude Desktop / Cursor, reads `~/cow/mcp.json` by default
|
|
||||||
|
|
||||||
Documentation: [MCP Tools](https://docs.cowagent.ai/en/tools/mcp). Thanks [@yangluxin613](https://github.com/yangluxin613) (#2801)
|
|
||||||
|
|
||||||
## 🌐 Browser Persistent Login
|
|
||||||
|
|
||||||
For sites that require login or have anti-bot protection, the browser tool can now persist a login session for long-term reuse, and supports attaching to your real Chrome browser to bypass fingerprint detection:
|
|
||||||
|
|
||||||
- **Persistent user profile (default)**: Uses `~/.cow/browser_profile` as the browser user data dir by default; once logged in, sessions are reused automatically on subsequent runs
|
|
||||||
- **CDP mode**: Configure `tools.browser.cdp_endpoint` to take over a real Chrome instance with full browser permissions
|
|
||||||
|
|
||||||
Documentation: [Browser Tool](https://docs.cowagent.ai/en/tools/browser). Thanks [@leafmove](https://github.com/leafmove) (#2809)
|
|
||||||
|
|
||||||
## 🤖 New Models and Improvements
|
|
||||||
|
|
||||||
- **New models**: `gpt-5.5`, `gemini-3.5-flash`, `qwen3.7-max`, `ernie-5.1`
|
|
||||||
- **Improvements**: DeepSeek V4 supports the `reasoning_effort` thinking-depth parameter; fixed thinking models like MiMo failing to connect via the OpenAI-compatible protocol
|
|
||||||
|
|
||||||
## 🔒 Deployment & Security
|
|
||||||
|
|
||||||
- **Bind to localhost by default**: The Web Console `web_host` now defaults to `127.0.0.1`; for server deployments, set it to `0.0.0.0` and configure a password manually. Thanks @August829, @yidaozhongqing, @YLChen-007, @icysun
|
|
||||||
- **Fully bundled frontend assets**: All third-party CSS / JS are now served locally — the console works offline and on intranet deployments. Thanks [@gitlayzer](https://github.com/gitlayzer) (#2816)
|
|
||||||
|
|
||||||
## 🛠 UX Improvements & Fixes
|
|
||||||
|
|
||||||
- **TTS rolls out to more channels**: Web Console, Personal WeChat, Feishu, DingTalk and WeCom Smart Bot all support voice replies — see the [Channels Overview](https://docs.cowagent.ai/en/channels)
|
|
||||||
- **Log panel enhancements**: Differentiated highlighting by log level, with level-based filtering. Thanks [@yangluxin613](https://github.com/yangluxin613) (#2807)
|
|
||||||
- **Auto-launch Web Console**: The Web Console now opens automatically on startup. Thanks [@yangluxin613](https://github.com/yangluxin613) (#2804)
|
|
||||||
- **Clean Ctrl+C exit**: No more long `KeyboardInterrupt` stack traces. Thanks [@yangluxin613](https://github.com/yangluxin613) (#2806)
|
|
||||||
- **Folder upload**: Web Console supports directory uploads, with path validation adapted for Windows. Thanks [@TryToMakeUsBetter](https://github.com/TryToMakeUsBetter) (#2814)
|
|
||||||
- Fixed scheduled tasks executing duplicates under certain conditions. Thanks [@CNXudiandian](https://github.com/CNXudiandian) (#2820)
|
|
||||||
- Fixed one-shot scheduled tasks with timezone not firing. Thanks @AethericSpace
|
|
||||||
- Fixed failed tool calls not being displayed after page refresh. Thanks [@a1094174619](https://github.com/a1094174619) (#2822)
|
|
||||||
- Fixed WeCom bot messages with illegal control characters failing to be delivered. Thanks [@Jacques-Zhao](https://github.com/Jacques-Zhao) (#2810)
|
|
||||||
|
|
||||||
## 📦 Upgrade
|
|
||||||
|
|
||||||
Source-code deployments can run `cow update` for a one-click upgrade, or pull the latest code and restart manually. See the [Upgrade Guide](https://docs.cowagent.ai/en/guide/upgrade) for details.
|
|
||||||
|
|
||||||
**Release Date**: 2026.05.22 | [Full Changelog](https://github.com/zhayujie/CowAgent/compare/2.0.8...2.0.9)
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
---
|
|
||||||
title: Create Skills
|
|
||||||
description: Create custom skills through conversation
|
|
||||||
---
|
|
||||||
|
|
||||||
CowAgent includes a built-in Skill Creator that lets you quickly create, install, or update skills through natural language conversation.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Simply describe the skill you want in a conversation, and the Agent will handle the creation:
|
|
||||||
|
|
||||||
- Codify workflows as skills: "Create a skill from this deployment process"
|
|
||||||
- Integrate third-party APIs: "Create a skill based on this API documentation"
|
|
||||||
- Install remote skills: "Install xxx skill for me"
|
|
||||||
|
|
||||||
## Creation Flow
|
|
||||||
|
|
||||||
1. Tell the Agent what skill you want to create
|
|
||||||
2. Agent automatically generates `SKILL.md` description and execution scripts
|
|
||||||
3. Skill is saved to the workspace `~/cow/skills/` directory
|
|
||||||
4. Agent will automatically recognize and use the skill in future conversations
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260202202247.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
|
|
||||||
## SKILL.md Format
|
|
||||||
|
|
||||||
Created skills follow the standard SKILL.md format:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
---
|
|
||||||
name: my-skill
|
|
||||||
description: Brief description of the skill
|
|
||||||
metadata:
|
|
||||||
emoji: 🔧
|
|
||||||
requires:
|
|
||||||
bins: ["curl"]
|
|
||||||
env: ["MY_API_KEY"]
|
|
||||||
primaryEnv: "MY_API_KEY"
|
|
||||||
---
|
|
||||||
|
|
||||||
# My Skill
|
|
||||||
|
|
||||||
Detailed instructions...
|
|
||||||
```
|
|
||||||
|
|
||||||
| Field | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `name` | Skill name, must match directory name |
|
|
||||||
| `description` | Skill description, Agent decides whether to invoke based on this |
|
|
||||||
| `metadata.requires.bins` | Required system commands |
|
|
||||||
| `metadata.requires.env` | Required environment variables |
|
|
||||||
| `metadata.always` | Always load (default false) |
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
See the [Skill Creator documentation](https://github.com/zhayujie/CowAgent/blob/master/skills/skill-creator/SKILL.md) for details.
|
|
||||||
</Tip>
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
---
|
|
||||||
title: Skill Hub
|
|
||||||
description: Browse, search, and install AI Agent skills
|
|
||||||
---
|
|
||||||
|
|
||||||
[Cow Skill Hub](https://skills.cowagent.ai/) is an open-source skill marketplace for AI Agents, aggregating official picks, community contributions, and third-party skills from GitHub, ClawHub, and beyond.
|
|
||||||
|
|
||||||
Source code: [github.com/zhayujie/cow-skill-hub](https://github.com/zhayujie/cow-skill-hub)
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260401110103.png" width="800" />
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- **Browse skills** — filter by category (Featured / Community / Third-party) and tags
|
|
||||||
- **Search skills** — find skills by name or description
|
|
||||||
- **View details** — read the skill manifest, file contents, install command, and required environment variables
|
|
||||||
- **One-click install** — copy the install command and run it in CowAgent
|
|
||||||
|
|
||||||
## Installing a skill
|
|
||||||
|
|
||||||
Run the install command in chat or in your terminal:
|
|
||||||
|
|
||||||
<CodeGroup>
|
|
||||||
```text Chat
|
|
||||||
/skill install <name>
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash Terminal
|
|
||||||
cow skill install <name>
|
|
||||||
```
|
|
||||||
</CodeGroup>
|
|
||||||
|
|
||||||
You can also browse the marketplace directly from chat:
|
|
||||||
|
|
||||||
```text
|
|
||||||
/skill list --remote
|
|
||||||
/skill search <keyword>
|
|
||||||
```
|
|
||||||
|
|
||||||
Beyond the curated list, you can install third-party skills from **GitHub, ClawHub, LinkAI, or any URL** via the CLI. See [Installing skills](/en/skills/install) for details.
|
|
||||||
|
|
||||||
## Contributing a skill
|
|
||||||
|
|
||||||
To submit your own skill:
|
|
||||||
|
|
||||||
1. Visit [skills.cowagent.ai/submit](https://skills.cowagent.ai/submit)
|
|
||||||
2. Sign in with GitHub or Google
|
|
||||||
3. Upload a folder or zip file containing `SKILL.md`
|
|
||||||
4. Skill name, display name, and description are auto-detected — adjust as needed
|
|
||||||
5. Submit for review; skills go live after security and quality checks
|
|
||||||
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260401111904.png" width="800" />
|
|
||||||
|
|
||||||
Skill file layout:
|
|
||||||
|
|
||||||
```
|
|
||||||
your-skill/
|
|
||||||
├── SKILL.md # required, in the root
|
|
||||||
├── scripts/ # optional, runtime scripts
|
|
||||||
└── resources/ # optional, additional assets
|
|
||||||
```
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
Skills are built around the `SKILL.md` manifest. You can also download `SKILL.md` from a skill's detail page and use it with any Agent that supports custom instructions (OpenClaw, Cursor, Claude Code, and more).
|
|
||||||
</Tip>
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
---
|
|
||||||
title: image-generation
|
|
||||||
description: Text-to-image / image-to-image / multi-image fusion with automatic multi-provider routing and fallback
|
|
||||||
---
|
|
||||||
|
|
||||||
A general-purpose image generation and editing skill supporting six providers: OpenAI, Gemini, Seedream (Volcengine Ark), Qwen (DashScope), MiniMax, and LinkAI. Configure any one provider's key to start using it; configure multiple to enable automatic fallback.
|
|
||||||
|
|
||||||
## Supported Models
|
|
||||||
|
|
||||||
| Provider | Models / Aliases | Notes |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| OpenAI | `gpt-image-2`, `gpt-image-1` | General-purpose, high quality, supports `quality` parameter |
|
|
||||||
| Gemini Nano Banana | `nano-banana-2`, `nano-banana-pro`, `nano-banana` | Corresponds to the image variants of `gemini-3.1-flash`, `gemini-3-pro`, `gemini-2.5-flash` |
|
|
||||||
| Seedream (Volcengine Ark) | `seedream-5.0-lite`, `seedream-4.5` | Native 2K–4K, up to 14 reference images for fusion |
|
|
||||||
| Qwen (DashScope) | `qwen-image-2.0`, `qwen-image-2.0-pro` | Strong with Chinese text rendering and text-image layouts |
|
|
||||||
| MiniMax | `image-01` | Fast and simple |
|
|
||||||
| LinkAI | Any model | Universal gateway, used as fallback |
|
|
||||||
|
|
||||||
## Model Selection
|
|
||||||
|
|
||||||
By default, "auto routing + automatic fallback" is used:
|
|
||||||
|
|
||||||
1. Pick the first configured provider in the order `OpenAI → Gemini → Seedream → Qwen → MiniMax → LinkAI`
|
|
||||||
2. On errors such as 401, model not enabled, or network issues, automatically switch to the next provider
|
|
||||||
3. If the user specifies a model in the conversation (e.g. "use seedream to draw a cat"), the corresponding provider is promoted to the front
|
|
||||||
|
|
||||||
To pin a specific model:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"skills": {
|
|
||||||
"image-generation": {
|
|
||||||
"model": "seedream-5.0-lite"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuring API Keys
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
It is recommended to configure providers from the "Model Management" page in the [Web console](/en/channels/web). Chat model keys configured there are automatically reused by the image generation skill — no need to set them twice. You can also edit the configuration file manually or temporarily set keys in a conversation using the `env_config` tool.
|
|
||||||
</Tip>
|
|
||||||
|
|
||||||
Credentials are shared with the main model providers:
|
|
||||||
|
|
||||||
| Field | Provider |
|
|
||||||
| --- | --- |
|
|
||||||
| `openai_api_key` | OpenAI |
|
|
||||||
| `gemini_api_key` | Gemini |
|
|
||||||
| `ark_api_key` | Volcengine Ark (Seedream) |
|
|
||||||
| `dashscope_api_key` | Alibaba DashScope (Qwen) |
|
|
||||||
| `minimax_api_key` | MiniMax |
|
|
||||||
| `linkai_api_key` | LinkAI |
|
|
||||||
|
|
||||||
|
|
||||||
## Enabling and Disabling
|
|
||||||
|
|
||||||
The skill automatically adjusts its status based on API keys:
|
|
||||||
|
|
||||||
- **Key configured**: the Agent calls the skill directly when it receives a drawing request
|
|
||||||
- **Key not configured**: the skill still appears in context (marked as "needs configuration") — the Agent will guide the user to set up a key
|
|
||||||
|
|
||||||
To control it manually:
|
|
||||||
|
|
||||||
```text
|
|
||||||
/skill disable image-generation # Disable
|
|
||||||
/skill enable image-generation # Re-enable
|
|
||||||
```
|
|
||||||
|
|
||||||
Equivalent terminal commands: `cow skill disable image-generation` / `cow skill enable image-generation`.
|
|
||||||
|
|
||||||
## Parameters
|
|
||||||
|
|
||||||
| Parameter | Type | Required | Default | Description |
|
|
||||||
| --- | --- | --- | --- | --- |
|
|
||||||
| `prompt` | string | Yes | — | Image description |
|
|
||||||
| `image_url` | string / list | No | null | Input image for editing — local path or URL; pass a list for multi-image fusion |
|
|
||||||
| `quality` | string | No | auto | `low` / `medium` / `high`, supported only by some providers |
|
|
||||||
| `size` | string | No | auto | `512` / `1K` / `2K` / `3K` / `4K`, or pixel value like `1024x1024` |
|
|
||||||
| `aspect_ratio` | string | No | null | `1:1` / `3:2` / `2:3` / `16:9` / `9:16` / `21:9`; Gemini also supports `1:4` / `4:1` / `1:8` / `8:1` |
|
|
||||||
|
|
||||||
<Warning>
|
|
||||||
**Higher quality and larger size cost more and take longer.** For everyday conversations, use the defaults (`auto`) or `quality=low` + `size=1K` — about 20 seconds per image. For posters or when high resolution is explicitly requested, use `quality=high` + `size=2K/4K` — may take 1–5 minutes.
|
|
||||||
</Warning>
|
|
||||||
|
|
||||||
## Common Use Cases
|
|
||||||
|
|
||||||
- **Text-to-image**: generate illustrations, posters, icons, avatars, storyboards, etc. from a description
|
|
||||||
- **Image-to-image**: change styles, swap elements, add decorations or text on an existing image
|
|
||||||
- **Multi-image fusion**: combine multiple reference images into one (outfit swaps, character group photos, etc.)
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
- Bash timeout should be set to 600 seconds: each provider has a 300-second HTTP timeout, and the script may try multiple providers sequentially
|
|
||||||
- Input images are automatically compressed to ≤ 4 MB with the longest edge ≤ 4096 px
|
|
||||||
- Gemini / Seedream / Qwen / MiniMax do not support the `quality` parameter
|
|
||||||
- Seedream defaults to 2K; `seedream-5.0-lite` supports up to 3K; `seedream-4.5` supports up to 4K
|
|
||||||
</Note>
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
---
|
|
||||||
title: Skills Overview
|
|
||||||
description: CowAgent skills system introduction
|
|
||||||
---
|
|
||||||
|
|
||||||
Skills provide infinite extensibility for the Agent. Each Skill consists of a description file (`SKILL.md`), execution scripts (optional), and resources (optional), describing how to accomplish specific types of tasks.
|
|
||||||
|
|
||||||
The difference between Skills and Tools: Tools are atomic operations implemented in code (e.g., file read/write, command execution), while Skills are high-level workflows based on description files that can combine multiple Tools to complete complex tasks.
|
|
||||||
|
|
||||||
## Getting Skills
|
|
||||||
|
|
||||||
CowAgent offers multiple ways to acquire skills:
|
|
||||||
|
|
||||||
- **Cow Skill Hub** — Browse and install community skills via `/skill list --remote`
|
|
||||||
- **GitHub** — Install directly from GitHub repositories, with batch install support
|
|
||||||
- **ClawHub** — Install ClawHub skills via `/skill install clawhub:name`
|
|
||||||
- **URL** — Install from zip archives or SKILL.md links
|
|
||||||
- **Conversational creation** — Let the Agent create skills through natural language conversation
|
|
||||||
|
|
||||||
See [Install Skills](/en/skills/install) and [Skill Management Commands](/en/cli/skill) for details. You can also [create skills](/en/skills/create) through conversation.
|
|
||||||
|
|
||||||
## Skill Loading Priority
|
|
||||||
|
|
||||||
1. **Workspace skills** (highest): `~/cow/skills/`
|
|
||||||
2. **Project built-in skills** (lowest): `skills/`
|
|
||||||
|
|
||||||
Skills with the same name are overridden by priority.
|
|
||||||
|
|
||||||
## Skill File Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
skills/
|
|
||||||
├── my-skill/
|
|
||||||
│ ├── SKILL.md # Skill description (frontmatter + instructions)
|
|
||||||
│ ├── scripts/ # Execution scripts (optional)
|
|
||||||
│ └── resources/ # Additional resources (optional)
|
|
||||||
```
|
|
||||||
|
|
||||||
### SKILL.md Format
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
---
|
|
||||||
name: my-skill
|
|
||||||
description: Brief description of the skill
|
|
||||||
metadata:
|
|
||||||
emoji: 🔧
|
|
||||||
requires:
|
|
||||||
bins: ["curl"]
|
|
||||||
env: ["MY_API_KEY"]
|
|
||||||
primaryEnv: "MY_API_KEY"
|
|
||||||
---
|
|
||||||
|
|
||||||
# My Skill
|
|
||||||
|
|
||||||
Detailed instructions...
|
|
||||||
```
|
|
||||||
|
|
||||||
| Field | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `name` | Skill name, must match directory name |
|
|
||||||
| `description` | Skill description, Agent decides whether to invoke based on this |
|
|
||||||
| `metadata.requires.bins` | Required system commands |
|
|
||||||
| `metadata.requires.env` | Required environment variables |
|
|
||||||
| `metadata.always` | Always load (default false) |
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
---
|
|
||||||
title: Install Skills
|
|
||||||
description: Install skills from multiple sources with a single command
|
|
||||||
---
|
|
||||||
|
|
||||||
CowAgent supports installing skills from [Cow Skill Hub](https://skills.cowagent.ai/), GitHub, ClawHub, LinkAI, and any URL via a unified `install` command. Use `/skill install` in chat or `cow skill install` in the terminal.
|
|
||||||
|
|
||||||
## From the Skill Hub
|
|
||||||
|
|
||||||
Browse all available skills at [skills.cowagent.ai](https://skills.cowagent.ai/) and install by name:
|
|
||||||
|
|
||||||
```text
|
|
||||||
/skill list --remote
|
|
||||||
/skill install pptx
|
|
||||||
```
|
|
||||||
|
|
||||||
## From GitHub
|
|
||||||
|
|
||||||
Any GitHub-hosted skill can be installed directly. Supports both repository-level batch install and subdirectory-level single install:
|
|
||||||
|
|
||||||
```text
|
|
||||||
/skill install larksuite/cli
|
|
||||||
/skill install https://github.com/larksuite/cli/tree/main/skills/lark-im
|
|
||||||
```
|
|
||||||
|
|
||||||
## From ClawHub
|
|
||||||
|
|
||||||
All [ClawHub](https://clawhub.ai/) skills (40k+) can be installed with a single command:
|
|
||||||
|
|
||||||
```text
|
|
||||||
/skill install clawhub:<name>
|
|
||||||
```
|
|
||||||
|
|
||||||
## From LinkAI
|
|
||||||
|
|
||||||
All public resources on [LinkAI](https://link-ai.tech/console) (10k+ apps / workflows / plugins), as well as your own resources (apps, workflows, knowledge bases, databases, plugins), can be installed via:
|
|
||||||
|
|
||||||
```text
|
|
||||||
/skill install linkai:<code>
|
|
||||||
```
|
|
||||||
|
|
||||||
> Every resource created on the LinkAI platform has a unique `code`. Find it on each resource's page in the [console](https://link-ai.tech/console).
|
|
||||||
|
|
||||||
## From URL
|
|
||||||
|
|
||||||
Supports zip archives and SKILL.md file links:
|
|
||||||
|
|
||||||
```text
|
|
||||||
/skill install https://cdn.link-ai.tech/skills/pptx.zip
|
|
||||||
/skill install https://example.com/path/to/SKILL.md
|
|
||||||
```
|
|
||||||
|
|
||||||
## Manage Skills
|
|
||||||
|
|
||||||
```text
|
|
||||||
/skill list # View installed skills
|
|
||||||
/skill info pptx # View skill details
|
|
||||||
/skill enable pptx # Enable a skill
|
|
||||||
/skill disable pptx # Disable a skill
|
|
||||||
/skill uninstall pptx # Uninstall a skill
|
|
||||||
```
|
|
||||||
|
|
||||||
<Tip>
|
|
||||||
All commands above work in the terminal by replacing `/skill` with `cow skill`. See [Skill Management Commands](/en/cli/skill) for full documentation.
|
|
||||||
</Tip>
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
---
|
|
||||||
title: knowledge-wiki
|
|
||||||
description: Maintain a local structured knowledge base with automatic archiving, categorisation, and cross-referencing
|
|
||||||
---
|
|
||||||
|
|
||||||
Organises notes, insights, and reference materials from your conversations into a structured local knowledge base, automatically maintaining an index and cross-references between pages.
|
|
||||||
|
|
||||||
`knowledge-wiki` maintains a `knowledge/` directory in your workspace — essentially the Agent's "second brain". The skill is marked `always: true`, so it is **always loaded** and requires no external dependencies.
|
|
||||||
|
|
||||||
## When It Triggers
|
|
||||||
|
|
||||||
- You share an article, document, or URL that you want to keep for future reference
|
|
||||||
- A conversation produces conclusions worth retaining long-term
|
|
||||||
- You want to look up something you accumulated earlier
|
|
||||||
|
|
||||||
## Directory Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
knowledge/
|
|
||||||
├── index.md # Global index (must be maintained)
|
|
||||||
├── log.md # Operation log (append-only)
|
|
||||||
└── <category>/ # Category subdirectories (grouped by content)
|
|
||||||
└── <slug>.md # Knowledge page (lowercase-hyphenated filename)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Three Core Operations
|
|
||||||
|
|
||||||
### 1. Ingest
|
|
||||||
|
|
||||||
When you share some material, the Agent will:
|
|
||||||
|
|
||||||
1. Read and understand the original content, extracting key information
|
|
||||||
2. Decide which category it belongs to — check `index.md` first; create a new category if none fits
|
|
||||||
3. Generate a knowledge page at `knowledge/<category>/<slug>.md`
|
|
||||||
4. Update the index `index.md` and the log `log.md`
|
|
||||||
|
|
||||||
### 2. Synthesise
|
|
||||||
|
|
||||||
When a conversation produces new conclusions or insights:
|
|
||||||
|
|
||||||
1. Create a new knowledge page under an appropriate category
|
|
||||||
2. Add cross-links to and from related existing pages
|
|
||||||
3. Update the index and log
|
|
||||||
|
|
||||||
### 3. Query
|
|
||||||
|
|
||||||
When you ask about previously accumulated knowledge:
|
|
||||||
|
|
||||||
1. Search `index.md` for potentially relevant pages
|
|
||||||
2. Open specific pages with the `read` tool
|
|
||||||
3. Supplement with `memory_search` if needed
|
|
||||||
4. Include links to knowledge pages in the answer so you can click through to the source
|
|
||||||
|
|
||||||
## Page Format
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# Page Title
|
|
||||||
|
|
||||||
> Source: <source URL or brief description>
|
|
||||||
|
|
||||||
Body content. Link between pages using relative paths:
|
|
||||||
[Related Page](../category/related-page.md)
|
|
||||||
|
|
||||||
## Key Points
|
|
||||||
|
|
||||||
- ...
|
|
||||||
|
|
||||||
## Related Pages
|
|
||||||
|
|
||||||
- [Page A](../category/page-a.md) — why it's related
|
|
||||||
```
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
- `> Source:` records where this knowledge came from. Always include it when there is a clear source
|
|
||||||
- Cross-references are important: when creating or updating a page, remember to add back-links in the related pages too
|
|
||||||
- **Only link to pages that already exist.** If a concept deserves its own page, create it first, then add the link
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## Index Format
|
|
||||||
|
|
||||||
`knowledge/index.md` uses a flat list grouped by category, one knowledge page per line:
|
|
||||||
|
|
||||||
```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
|
|
||||||
```
|
|
||||||
|
|
||||||
No tables, no emojis. Category names and organisation can be adjusted freely.
|
|
||||||
|
|
||||||
## Log Format
|
|
||||||
|
|
||||||
`knowledge/log.md` is append-only — newest entries go at the bottom:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
## [YYYY-MM-DD] ingest | Page Title
|
|
||||||
## [YYYY-MM-DD] synthesize | Page Title
|
|
||||||
```
|
|
||||||
|
|
||||||
## Writing Guidelines
|
|
||||||
|
|
||||||
- **Filenames**: lowercase with hyphens, e.g. `machine-learning.md`
|
|
||||||
- **One topic per page** — link related content across pages
|
|
||||||
- **Update, don't duplicate** — if a page already exists, update it rather than creating a new one
|
|
||||||
- **Always update the index** `knowledge/index.md` after any change
|
|
||||||
- **Distill, don't copy** — capture the key points, not the entire source
|
|
||||||
- **Use full paths when referencing knowledge pages in conversations**, e.g. `[Title](knowledge/<category>/<slug>.md)`. Use relative paths only for inter-page links
|
|
||||||
- **Include links when answering questions based on knowledge pages** so users can dig deeper
|
|
||||||
@@ -1,180 +0,0 @@
|
|||||||
---
|
|
||||||
title: skill-creator
|
|
||||||
description: Create, install, and update skills — standardises SKILL.md format and directory structure
|
|
||||||
---
|
|
||||||
|
|
||||||
`skill-creator` is a "meta-skill" that helps the Agent create, install, and update other skills, ensuring every skill follows a consistent `SKILL.md` format and directory layout.
|
|
||||||
|
|
||||||
## When It Triggers
|
|
||||||
|
|
||||||
- The user wants to install a skill from a URL or remote repository
|
|
||||||
- The user wants to create a brand-new skill from scratch
|
|
||||||
- An existing skill needs upgrading or restructuring
|
|
||||||
|
|
||||||
## What Is a Skill?
|
|
||||||
|
|
||||||
A skill is a reusable instruction set plus optional scripts and assets. It injects domain expertise into the Agent so it can handle specific tasks like a specialist.
|
|
||||||
|
|
||||||
A skill typically contains:
|
|
||||||
|
|
||||||
1. **Specialised workflow** — step-by-step instructions for a category of tasks
|
|
||||||
2. **Tool usage** — how to call a particular API or process a particular file format
|
|
||||||
3. **Domain knowledge** — team conventions, business rules, data schemas, etc.
|
|
||||||
4. **Attached resources** — scripts, reference docs, templates, etc.
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
**Core principle: less is more.** Only write what the Agent wouldn't figure out on its own. For every line you add, ask yourself: is it worth the tokens?
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
## Directory Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
skill-name/
|
|
||||||
├── SKILL.md # Required: skill definition
|
|
||||||
│ ├── YAML frontmatter (name / description are mandatory)
|
|
||||||
│ └── Markdown body (instructions + examples)
|
|
||||||
└── Optional resources
|
|
||||||
├── scripts/ # Executable scripts (Python / Bash, etc.)
|
|
||||||
├── references/ # Large reference docs the Agent reads on demand
|
|
||||||
└── assets/ # Templates, icons, etc. used directly in output
|
|
||||||
```
|
|
||||||
|
|
||||||
## SKILL.md Specification
|
|
||||||
|
|
||||||
Frontmatter fields in the SKILL.md header:
|
|
||||||
|
|
||||||
| Field | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| `name` | Skill name — lowercase with hyphens, must match the directory name |
|
|
||||||
| `description` | **The most important field.** Clearly state what the skill does and when to use it. The Agent reads this to decide whether to invoke it. All trigger-related descriptions go here, not in the body |
|
|
||||||
| `metadata.cowagent.requires.bins` | System CLI tools that must be installed |
|
|
||||||
| `metadata.cowagent.requires.env` | Required environment variables (all must be present) |
|
|
||||||
| `metadata.cowagent.requires.anyEnv` | Multiple API keys — at least one must be set |
|
|
||||||
| `metadata.cowagent.requires.anyBins` | Multiple tools — at least one must be installed |
|
|
||||||
| `metadata.cowagent.always` | Set to `true` to always load, skipping dependency checks |
|
|
||||||
| `metadata.cowagent.emoji` | Display emoji (optional) |
|
|
||||||
| `metadata.cowagent.os` | OS restriction, e.g. `["darwin", "linux"]` |
|
|
||||||
|
|
||||||
<Note>
|
|
||||||
The `category` field does not need to be set manually — the system automatically sets it to `skill`.
|
|
||||||
</Note>
|
|
||||||
|
|
||||||
Two ways to declare API key dependencies:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
metadata:
|
|
||||||
cowagent:
|
|
||||||
requires:
|
|
||||||
env: ["MYAPI_KEY"] # Must be present
|
|
||||||
```
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
metadata:
|
|
||||||
cowagent:
|
|
||||||
requires:
|
|
||||||
anyEnv: ["OPENAI_API_KEY", "LINKAI_API_KEY"] # At least one
|
|
||||||
```
|
|
||||||
|
|
||||||
**Skills are auto-enabled/disabled based on dependencies**: they activate when all required environment variables are present and deactivate when any are missing — no need for manual `/skill enable`.
|
|
||||||
|
|
||||||
## Resource Directories
|
|
||||||
|
|
||||||
| Directory | What goes here | What does NOT go here |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `scripts/` | Code that needs to run repeatedly, or scripts that produce deterministic results | Demo-only code snippets |
|
|
||||||
| `references/` | Documents **over 500 lines** that genuinely won't fit in SKILL.md (e.g. a full DB schema) | General API docs, tutorials, examples |
|
|
||||||
| `assets/` | Files that appear in the final output (templates, icons, boilerplate, etc.) | Explanatory documentation |
|
|
||||||
|
|
||||||
<Warning>
|
|
||||||
**In principle, everything goes in `SKILL.md`** — only split into resource directories when it truly won't fit.
|
|
||||||
|
|
||||||
Do not add `README.md`, `CHANGELOG.md`, or `INSTALLATION_GUIDE.md` to a skill — put everything in `SKILL.md`. Resource directories should only contain scripts that actually run or assets that are actually used.
|
|
||||||
</Warning>
|
|
||||||
|
|
||||||
## Installing External Skills
|
|
||||||
|
|
||||||
After installation, the skill lands in `<workspace>/skills/<name>/`.
|
|
||||||
|
|
||||||
| Source | How to install |
|
|
||||||
| --- | --- |
|
|
||||||
| URL (single file) | curl / web_fetch |
|
|
||||||
| URL (zip archive) | Download and extract |
|
|
||||||
| Local SKILL.md | Read directly |
|
|
||||||
| Local zip archive | Extract |
|
|
||||||
|
|
||||||
Installation steps:
|
|
||||||
|
|
||||||
1. Locate the `SKILL.md` (may be at the root or in a subdirectory of the archive)
|
|
||||||
2. Read the `name` from the frontmatter
|
|
||||||
3. Copy the **entire skill directory** (including `SKILL.md`, `scripts/`, `assets/`, etc.) to `<workspace>/skills/<name>/`
|
|
||||||
4. If the archive contains an `INSTALL.md` or similar setup script, run it — but the final result must still reside under `<workspace>/skills/<name>/`
|
|
||||||
|
|
||||||
## Creating a Skill from Scratch
|
|
||||||
|
|
||||||
Recommended order:
|
|
||||||
|
|
||||||
1. **Clarify requirements** — ask the user for a few concrete use cases (don't ask too many at once)
|
|
||||||
2. **Plan the structure** — does this skill need scripts? Reference docs? Template assets?
|
|
||||||
3. **Scaffold** — use the init script:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
scripts/init_skill.py <skill-name> --path <workspace>/skills [--resources scripts,references,assets] [--examples]
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Fill in content** — write SKILL.md, add scripts and resources. Always test scripts after writing them
|
|
||||||
5. **Validate** (optional):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
scripts/quick_validate.py <workspace>/skills/<skill-name>
|
|
||||||
```
|
|
||||||
|
|
||||||
6. **Iterate** — keep improving based on real-world usage feedback
|
|
||||||
|
|
||||||
## Naming Conventions
|
|
||||||
|
|
||||||
- Use only lowercase letters, digits, and hyphens. Normalise user-given names, e.g. `Plan Mode` → `plan-mode`
|
|
||||||
- Maximum 64 characters
|
|
||||||
- Keep it short, start with a verb, make it self-explanatory
|
|
||||||
- Use tool names as prefixes when appropriate, e.g. `gh-address-comments`, `linear-address-issue`
|
|
||||||
- The directory name and the `name` field must match exactly
|
|
||||||
|
|
||||||
## Three-Level Loading
|
|
||||||
|
|
||||||
Skills are not loaded into context all at once — they use a three-level progressive loading mechanism:
|
|
||||||
|
|
||||||
1. **Metadata** (`name` + `description`) — always in context (~100 words). The Agent uses this to decide whether to invoke the skill
|
|
||||||
2. **SKILL.md body** — loaded only when the skill is activated; keep it under 500 lines
|
|
||||||
3. **Resource files** — read on demand by the Agent
|
|
||||||
|
|
||||||
For skills with multiple variants (e.g. multi-cloud deployment), organise like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
cloud-deploy/
|
|
||||||
├── SKILL.md # Main workflow and provider selection logic
|
|
||||||
└── references/
|
|
||||||
├── aws.md
|
|
||||||
├── gcp.md
|
|
||||||
└── azure.md
|
|
||||||
```
|
|
||||||
|
|
||||||
When the user picks AWS, the Agent only reads `aws.md` — no need to load all three providers.
|
|
||||||
|
|
||||||
## Common Design Patterns
|
|
||||||
|
|
||||||
**Step-by-step**: numbered steps with corresponding scripts.
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
1. Analyse form structure (run analyze_form.py)
|
|
||||||
2. Generate field mappings (edit fields.json)
|
|
||||||
3. Auto-fill the form (run fill_form.py)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Branching**: different flows based on user intent.
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
1. Determine operation type:
|
|
||||||
**Creating new content?** → follow the "Create" workflow
|
|
||||||
**Editing existing content?** → follow the "Edit" workflow
|
|
||||||
```
|
|
||||||
|
|
||||||
**Template-based**: when output format has strict requirements, include a template in SKILL.md for the Agent to follow.
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
---
|
|
||||||
title: bash - Terminal
|
|
||||||
description: Execute system commands
|
|
||||||
---
|
|
||||||
|
|
||||||
Execute Bash commands in the current working directory, returns stdout and stderr. API keys configured via `env_config` are automatically injected into the environment.
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
No extra dependencies, available by default.
|
|
||||||
|
|
||||||
## Parameters
|
|
||||||
|
|
||||||
| Parameter | Type | Required | Description |
|
|
||||||
| --- | --- | --- | --- |
|
|
||||||
| `command` | string | Yes | Command to execute |
|
|
||||||
| `timeout` | integer | No | Timeout in seconds |
|
|
||||||
|
|
||||||
## Use Cases
|
|
||||||
|
|
||||||
- Install packages and dependencies
|
|
||||||
- Run code and tests
|
|
||||||
- Deploy applications and services (Nginx config, process management, etc.)
|
|
||||||
- System administration and troubleshooting
|
|
||||||
|
|
||||||
<Frame>
|
|
||||||
<img src="https://cdn.link-ai.tech/doc/20260203121008.png" width="800" />
|
|
||||||
</Frame>
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user