Copaw AI Assistant
Personal AI assistant framework supporting multiple chat channels (DingTalk, Feishu, QQ, Discord, etc.) with extensible skills, local/cloud deployment, and cron scheduling.
- Skill ID
- reason-machines/trending-skills/copaw-ai-assistant
- Publisher
- reason-machines
- Repository
- trending-skills
- Installs
- 0
- Files
- 1
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
reason-machines/trending-skills/copaw-ai-assistantInstalls these files- SKILL.md
What this skill tells the agent
CoPaw AI Assistant Skill
Skill by ara.so — Daily 2026 Skills collection.
CoPaw is a personal AI assistant framework you deploy on your own machine or in the cloud. It connects to multiple chat platforms (DingTalk, Feishu, QQ, Discord, iMessage, Telegram, Mattermost, Matrix, MQTT) through a single agent, supports custom Python skills, scheduled cron jobs, local and cloud LLMs, and provides a web Console at http://127.0.0.1:8088/.
Installation
pip (recommended if Python 3.10–3.13 is available)
pip install copaw
copaw init --defaults # non-interactive setup with sensible defaults
copaw app # starts the web Console + backendScript install (no Python setup required)
macOS / Linux:
curl -fsSL https://copaw.agentscope.io/install.sh | bash
# With Ollama support:
curl -fsSL https://copaw.agentscope.io/install.sh | bash -s -- --extras ollama
# Multiple extras:
curl -fsSL https://copaw.agentscope.io/install.sh | bash -s -- --extras ollama,llamacppWindows CMD:
curl -fsSL https://copaw.agentscope.io/install.bat -o install.bat && install.batWindows PowerShell:
irm https://copaw.agentscope.io/install.ps1 | iexAfter script install, open a new terminal:
copaw init --defaults
copaw appInstall from source
git clone https://github.com/agentscope-ai/CoPaw.git
cd CoPaw
pip install -e ".[dev]"
copaw init --defaults
copaw appCLI Reference
copaw init # interactive workspace setup
copaw init --defaults # non-interactive setup
copaw app # start the Console (http://127.0.0.1:8088/)
copaw app --port 8090 # use a custom port
copaw --help # list all commandsWorkspace Structure
After copaw init, a workspace is created (default: ~/.copaw/workspace/):
~/.copaw/workspace/
├── config.yaml # agent, provider, channel configuration
├── skills/ # custom skill files (auto-loaded)
│ └── my_skill.py
├── memory/ # conversation memory storage
└── logs/ # runtime logsConfiguration (config.yaml)
copaw init generates this file. Edit it directly or use the Console UI.
LLM Provider (OpenAI-compatible)
providers:
- id: openai-main
type: openai
api_key: ${OPENAI_API_KEY} # use env var reference
model: gpt-4o
base_url: https://api.openai.com/v1
- id: local-ollama
type: ollama
model: llama3.2
base_url: http://localhost:11434Agent Settings
agent:
name: CoPaw
language: en # en, zh, ja, etc.
provider_id: openai-main
context_limit: 8000Channel: DingTalk
channels:
- type: dingtalk
app_key: ${DINGTALK_APP_KEY}
app_secret: ${DINGTALK_APP_SECRET}
agent_id: ${DINGTALK_AGENT_ID}
mention_only: true # only respond when @mentioned in groupsChannel: Feishu (Lark)
channels:
- type: feishu
app_id: ${FEISHU_APP_ID}
app_secret: ${FEISHU_APP_SECRET}
mention_only: falseChannel: Discord
channels:
- type: discord
token: ${DISCORD_BOT_TOKEN}
mention_only: trueChannel: Telegram
channels:
- type: telegram
token: ${TELEGRAM_BOT_TOKEN}Channel: QQ
channels:
- type: qq
uin: ${QQ_UIN}
password: ${QQ_PASSWORD}Channel: Mattermost
channels:
- type: mattermost
url: ${MATTERMOST_URL}
token: ${MATTERMOST_TOKEN}
team: my-teamChannel: Matrix
channels:
- type: matrix
homeserver: ${MATRIX_HOMESERVER}
user_id: ${MATRIX_USER_ID}
access_token: ${MATRIX_ACCESS_TOKEN}Custom Skills
Skills are Python files placed in ~/.copaw/workspace/skills/. They are auto-loaded when CoPaw starts — no registration step needed.
Minimal skill structure
# ~/.copaw/workspace/skills/weather.py
SKILL_NAME = "get_weather"
SKILL_DESCRIPTION = "Get current weather for a city"
# Tool schema (OpenAI function-calling format)
SKILL_SCHEMA = {
"type": "function",
"function": {
"name": SKILL_NAME,
"description": SKILL_DESCRIPTION,
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name, e.g. 'Tokyo'"
}
},
"required": ["city"]
}
}
}
def get_weather(city: str) -> str:
"""Fetch weather data for the given city."""
import os
import requests
api_key = os.environ["OPENWEATHER_API_KEY"]
url = f"https://api.openweathermap.org/data/2.5/weather"
resp = requests.get(url, params={"q": city, "appid": api_key, "units": "metric"})
resp.raise_for_status()
data = resp.json()
temp = data["main"]["temp"]
desc = data["weather"][0]["description"]
return f"{city}: {temp}°C, {desc}"Skill with async support
# ~/.copaw/workspace/skills/summarize_url.py
SKILL_NAME = "summarize_url"
SKILL_DESCRIPTION = "Fetch and summarize the content of a URL"
SKILL_SCHEMA = {
"type": "function",
"function": {
"name": SKILL_NAME,
"description": SKILL_DESCRIPTION,
"parameters": {
"type": "object",
"properties": {
"url": {"type": "string", "description": "The URL to summarize"}
},
"required": ["url"]
}
}
}
async def summarize_url(url: str) -> str:
import httpx
async with httpx.AsyncClient(timeout=15) as client:
resp = await client.get(url)
text = resp.text[:4000] # truncate for context limit
return f"Content preview from {url}:\n{text}"Skill returning structured data
# ~/.copaw/workspace/skills/list_files.py
import os
import json
SKILL_NAME = "list_files"
SKILL_DESCRIPTION = "List files in a directory"
SKILL_SCHEMA = {
"type": "function",
"function": {
"name": SKILL_NAME,
"description": SKILL_DESCRIPTION,
"parameters": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Absolute or relative directory path"
},
"extension": {
"type": "string",
"description": "Filter by extension, e.g. '.py'. Optional."
}
},
"required": ["path"]
}
}
}
def list_files(path: str, extension: str = "") -> str:
entries = os.listdir(os.path.expanduser(path))
if extension:
entries = [e for e in entries if e.endswith(extension)]
return json.dumps(sorted(entries))Cron / Scheduled Tasks
Define cron jobs in config.yaml to run skills on a schedule and push results to a channel:
cron:
- id: daily-digest
schedule: "0 8 * * *" # every day at 08:00
skill: get_weather
skill_args:
city: "Tokyo"
channel_id: dingtalk-main # matches a channel id below
message_template: "Good morning! Today's weather: {result}"
- id: hourly-news
schedule: "0 * * * *"
skill: fetch_tech_news
channel_id: discord-mainLocal Model Setup
Ollama
# Install Ollama: https://ollama.ai
ollama pull llama3.2
ollama serve # starts on http://localhost:11434# config.yaml
providers:
- id: ollama-local
type: ollama
model: llama3.2
base_url: http://localhost:11434LM Studio
providers:
- id: lmstudio-local
type: lmstudio
model: lmstudio-community/Meta-Llama-3-8B-Instruct-GGUF
base_url: http://localhost:1234/v1llama.cpp (extra required)
pip install "copaw[llamacpp]"More from reason-machines
Use this skill in a project
Open any RiverX project, search the Skills panel for reason-machines/trending-skills/copaw-ai-assistant, and install it in one click.
