Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
2ccb85d
统一路径类,旧函数已弃用
LIghtJUNction Nov 2, 2025
1151677
fix/ 抽象基类装饰器顺序写反了
LIghtJUNction Nov 2, 2025
36de3c5
Update astrbot/base/paths.py
LIghtJUNction Nov 2, 2025
212d8cc
版本号统一,常量移动至base包 (#3281)
LIghtJUNction Nov 2, 2025
b3f23b2
chore: 使用 ruff format 格式化代码 (#3283)
Copilot Nov 2, 2025
983264d
fix: 移除未使用的临时目录变量 (#3286)
Copilot Nov 2, 2025
9e4fec8
[WIP] Update path class and deprecate old functions (#3287)
Copilot Nov 2, 2025
8e3bd92
Update astrbot/core/utils/astrbot_path.py
LIghtJUNction Nov 2, 2025
7518c4a
Update astrbot/core/utils/astrbot_path.py
LIghtJUNction Nov 3, 2025
36a3b4d
chore: 运行 ruff format 修复代码格式 (#3291)
Copilot Nov 3, 2025
15aafa2
Update astrbot/core/config/default.py
LIghtJUNction Nov 3, 2025
629af21
同步主分支 (#3294)
LIghtJUNction Nov 3, 2025
530cc95
Update abc.py
LIghtJUNction Nov 3, 2025
ac53c6f
Merge branch 'chore/uni-paths' of https://github.com/AstrBotDevs/Astr…
LIghtJUNction Nov 3, 2025
b805d09
Update pyproject.toml
LIghtJUNction Nov 3, 2025
9c344b0
Update cmd_init.py
LIghtJUNction Nov 3, 2025
4db1a95
Update tool.py
LIghtJUNction Nov 3, 2025
01e6c05
CLI检查,以及一些错误修正
LIghtJUNction Nov 3, 2025
3df29d7
Update components.py
LIghtJUNction Nov 3, 2025
6e6bd1b
Update wechatpadpro_adapter.py
LIghtJUNction Nov 3, 2025
a4967b3
Update components.py
LIghtJUNction Nov 3, 2025
372663f
同步主线 (#3298)
LIghtJUNction Nov 4, 2025
b8ec5ba
更新 updator.py
LIghtJUNction Nov 4, 2025
8f68629
Update updator.py
LIghtJUNction Nov 4, 2025
3df0693
Update updator.py
LIghtJUNction Nov 4, 2025
a1c744e
恢复原命名
LIghtJUNction Nov 4, 2025
47eb3c6
Update astrbot_path.py
LIghtJUNction Nov 4, 2025
de00fb4
新增一个私有辅助函数,报错时指导用户
LIghtJUNction Nov 4, 2025
9fd2624
格式化
LIghtJUNction Nov 4, 2025
36b7a13
Update astrbot_config.py
LIghtJUNction Nov 4, 2025
34951d0
版本号后缀
LIghtJUNction Nov 4, 2025
138843b
修正
LIghtJUNction Nov 4, 2025
26b2a2e
pip安装器install函数优化
LIghtJUNction Nov 4, 2025
0373840
Update pip_installer.py
LIghtJUNction Nov 4, 2025
c51b495
格式修复
LIghtJUNction Nov 4, 2025
5ffaa97
同步 (#3303)
LIghtJUNction Nov 4, 2025
9a55461
更新 cmd_plug.py
LIghtJUNction Nov 5, 2025
637d347
fix(cli): 移除重复创建的data/data/空目录
Dt8333 Nov 5, 2025
8a61848
chore(cli): 移除未使用的依赖
Dt8333 Nov 5, 2025
ef68c82
Merge branch 'master' into chore/uni-paths
LIghtJUNction Nov 5, 2025
6b6f97b
Update astrbot/__main__.py
LIghtJUNction Nov 5, 2025
6fdb65e
Update tests/test_paths.py
LIghtJUNction Nov 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ASTRBOT_ROOT = ./data
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# ASTRBOT 数据目录
# ASTRBOT_ROOT = ./data
126 changes: 63 additions & 63 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,63 @@
# AstrBot Development Instructions

AstrBot is a multi-platform LLM chatbot and development framework written in Python with a Vue.js dashboard. It supports multiple messaging platforms (QQ, Telegram, Discord, etc.) and various LLM providers (OpenAI, Anthropic, Google Gemini, etc.).

Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.

## Working Effectively

### Bootstrap and Install Dependencies
- **Python 3.10+ required** - Check `.python-version` file
- Install UV package manager: `pip install uv`
- Install project dependencies: `uv sync` -- takes 6-7 minutes. NEVER CANCEL. Set timeout to 10+ minutes.
- Create required directories: `mkdir -p data/plugins data/config data/temp`

### Running the Application
- Run main application: `uv run main.py` -- starts in ~3 seconds
- Application creates WebUI on http://localhost:6185 (default credentials: `astrbot`/`astrbot`)
- Application loads plugins automatically from `packages/` and `data/plugins/` directories

### Dashboard Build (Vue.js/Node.js)
- **Prerequisites**: Node.js 20+ and npm 10+ required
- Navigate to dashboard: `cd dashboard`
- Install dashboard dependencies: `npm install` -- takes 2-3 minutes. NEVER CANCEL. Set timeout to 5+ minutes.
- Build dashboard: `npm run build` -- takes 25-30 seconds. NEVER CANCEL.
- Dashboard creates optimized production build in `dashboard/dist/`

### Testing
- Do not generate test files for now.

### Code Quality and Linting
- Install ruff linter: `uv add --dev ruff`
- Check code style: `uv run ruff check .` -- takes <1 second
- Check formatting: `uv run ruff format --check .` -- takes <1 second
- Fix formatting: `uv run ruff format .`
- **ALWAYS** run `uv run ruff check .` and `uv run ruff format .` before committing changes

### Plugin Development
- Plugins load from `packages/` (built-in) and `data/plugins/` (user-installed)
- Plugin system supports function tools and message handlers
- Key plugins: python_interpreter, web_searcher, astrbot, reminder, session_controller

### Common Issues and Workarounds
- **Dashboard download fails**: Known issue with "division by zero" error - application still works
- **Import errors in tests**: Ensure `uv run` is used to run tests in proper environment
=- **Build timeouts**: Always set appropriate timeouts (10+ minutes for uv sync, 5+ minutes for npm install)

## CI/CD Integration
- GitHub Actions workflows in `.github/workflows/`
- Docker builds supported via `Dockerfile`
- Pre-commit hooks enforce ruff formatting and linting

## Docker Support
- Primary deployment method: `docker run soulter/astrbot:latest`
- Compose file available: `compose.yml`
- Exposes ports: 6185 (WebUI), 6195 (WeChat), 6199 (QQ), etc.
- Volume mount required: `./data:/AstrBot/data`

## Multi-language Support
- Documentation in Chinese (README.md), English (README_en.md), Japanese (README_ja.md)
- UI supports internationalization
- Default language is Chinese

Remember: This is a production chatbot framework with real users. Always test thoroughly and ensure changes don't break existing functionality.
# AstrBot 开发指南

AstrBot 是一个使用 Python 编写、配备 Vue.js 仪表盘的多平台 LLM 聊天机器人开发框架。它支持多个消息平台(QQ、TelegramDiscord 等)和多种 LLM 提供商(OpenAIAnthropicGoogle Gemini 等)。

始终优先参考这些指南,仅在遇到与此处信息不符的意外情况时才回退到搜索或 bash 命令。

## 高效工作

### 引导和安装依赖
- **需要 Python 3.10+** - 检查 `.python-version` 文件
- 安装 UV 包管理器:`pip install uv`
- 安装项目依赖:`uv sync` -- 很快几分钟。绝不要取消。设置超时时间为 10+ 分钟。
- 创建必需的目录:`mkdir -p data/plugins data/config data/temp`

### 运行应用程序
- 运行主应用程序:`uv run main.py` -- 约 3 秒启动
- 应用程序在 http://localhost:6185 创建 WebUI(默认凭据:`astrbot`/`astrbot`
- 应用程序自动从 `packages/` `data/plugins/` 目录加载插件

### 仪表盘构建(Vue.js/Node.js
- **前置要求**:需要 Node.js 20+ npm 10+
- 导航到仪表盘:`cd dashboard`
- 安装仪表盘依赖:`npm install` -- 需要 2-3 分钟。绝不要取消。设置超时时间为 5+ 分钟。
- 构建仪表盘:`npm run build` -- 需要 25-30 秒。绝不要取消。
- 仪表盘在 `dashboard/dist/` 创建优化的生产构建

### 测试
- 暂时不要生成测试文件。

### 代码质量和检查
- 安装 ruff 检查器:`uv add --dev ruff`
- 检查代码风格:`uv run ruff check .` -- 耗时 <1
- 检查格式:`uv run ruff format --check .` -- 耗时 <1
- 修复格式:`uv run ruff format .`
- **始终**在提交更改前运行 `uv run ruff check .` `uv run ruff format .`

### 插件开发
- 插件从 `packages/`(内置)和 `data/plugins/`(用户安装)加载
- 插件系统支持函数工具和消息处理器
- 关键插件:python_interpreterweb_searcherastrbotremindersession_controller

### 常见问题和解决方法
- **仪表盘下载失败**:已知的"除以零"错误问题 - 应用程序仍可正常工作
- **测试中的导入错误**:确保使用 `uv run` 在适当的环境中运行测试
- **构建超时**:始终设置适当的超时时间(uv sync 为 10+ 分钟,npm install 为 5+ 分钟)

## CI/CD 集成
- GitHub Actions 工作流在 `.github/workflows/`
- 通过 `Dockerfile` 支持 Docker 构建
- Pre-commit 钩子强制执行 ruff 格式化和检查

## Docker 支持
- 主要部署方法:`docker run soulter/astrbot:latest`
- 可用的 Compose 文件:`compose.yml`
- 暴露端口:6185WebUI)、6195WeChat)、6199(QQ)等
- 需要挂载卷:`./data:/AstrBot/data`

## 多语言支持
- 文档包括中文(README.md)、英文(README_en.md)、日文(README_ja.md
- UI 支持国际化
- 默认语言为中文

请记住:这是一个有真实用户的生产聊天机器人框架。始终进行彻底测试,确保更改不会破坏现有功能。
95 changes: 95 additions & 0 deletions astrbot/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import argparse
import asyncio
import mimetypes
import os
import sys

from astrbot.base import LOGO, AstrbotPaths
from astrbot.core import LogBroker, LogManager, db_helper, logger
from astrbot.core.config.default import VERSION
from astrbot.core.initial_loader import InitialLoader
from astrbot.core.utils.io import download_dashboard, get_dashboard_version


def check_env():
if sys.version_info.major != 3 or sys.version_info.minor < 10:
logger.error("请使用 Python3.10+ 运行本项目。")
exit()

# os.makedirs("data/config", exist_ok=True)
# os.makedirs("data/plugins", exist_ok=True)
# os.makedirs("data/temp", exist_ok=True)
Comment thread
LIghtJUNction marked this conversation as resolved.

# 针对问题 #181 的临时解决方案
mimetypes.add_type("text/javascript", ".js")
mimetypes.add_type("text/javascript", ".mjs")
mimetypes.add_type("application/json", ".json")


async def check_dashboard_files(webui_dir: str | None = None):
"""下载管理面板文件"""
# 指定webui目录
if webui_dir:
if os.path.exists(webui_dir):
logger.info(f"使用指定的 WebUI 目录: {webui_dir}")
return webui_dir
logger.warning(f"指定的 WebUI 目录 {webui_dir} 不存在,将使用默认逻辑。")

data_dist_path = str(AstrbotPaths.astrbot_root / "dist")
if os.path.exists(data_dist_path):
v = await get_dashboard_version()
if v is not None:
# 存在文件
if v == f"v{VERSION}":
logger.info("WebUI 版本已是最新。")
else:
logger.warning(
f"检测到 WebUI 版本 ({v}) 与当前 AstrBot 版本 (v{VERSION}) 不符。",
)
return data_dist_path

logger.info(
"开始下载管理面板文件...高峰期(晚上)可能导致较慢的速度。如多次下载失败,请前往 https://github.com/AstrBotDevs/AstrBot/releases/latest 下载 dist.zip,并将其中的 dist 文件夹解压至 data 目录下。",
)

try:
await download_dashboard(version=f"v{VERSION}", latest=False)
except Exception as e:
logger.critical(f"下载管理面板文件失败: {e}。")
return None

logger.info("管理面板下载完成。")
return data_dist_path


def main():
parser = argparse.ArgumentParser(description="AstrBot")
parser.add_argument(
"--webui-dir",
type=str,
help="指定 WebUI 静态文件目录路径",
default=None,
)
args = parser.parse_args()

check_env()

# 启动日志代理
log_broker = LogBroker()
LogManager.set_queue_handler(logger, log_broker)

# 检查仪表板文件
webui_dir = asyncio.run(check_dashboard_files(args.webui_dir))

db = db_helper

# 打印 logo
logger.info(LOGO)

core_lifecycle = InitialLoader(db, log_broker)
core_lifecycle.webui_dir = webui_dir
asyncio.run(core_lifecycle.start())


if __name__ == "__main__":
main()
3 changes: 3 additions & 0 deletions astrbot/base/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Base 包

- 此包内容仅可单向导出
9 changes: 9 additions & 0 deletions astrbot/base/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from .abc import IAstrbotPaths
from .const import LOGO
from .paths import AstrbotPaths

__all__ = [
"IAstrbotPaths",
"AstrbotPaths",
"LOGO",
]
70 changes: 70 additions & 0 deletions astrbot/base/abc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from __future__ import annotations

from abc import ABC, abstractmethod
from contextlib import AbstractAsyncContextManager, AbstractContextManager
from pathlib import Path


class IAstrbotPaths(ABC):
"""路径管理的抽象基类."""

@abstractmethod
def __init__(self, name: str) -> None:
"""初始化路径管理器."""

@classmethod
@abstractmethod
def getPaths(cls, name: str) -> IAstrbotPaths:
"""返回Paths实例,用于访问模块的各类目录."""

@property
@abstractmethod
def root(self) -> Path:
"""获取根目录."""

@property
@abstractmethod
def home(self) -> Path:
"""获取模块/插件主目录."""

@property
@abstractmethod
def config(self) -> Path:
"""获取模块配置目录."""

@property
@abstractmethod
def data(self) -> Path:
"""获取模块数据目录."""

@property
@abstractmethod
def log(self) -> Path:
"""获取模块日志目录."""

@property
@abstractmethod
def temp(self) -> Path:
"""获取模块临时目录."""

@property
@abstractmethod
def plugins(self) -> Path:
"""获取插件目录."""

@abstractmethod
def reload(self) -> None:
"""重新加载环境变量."""

@classmethod
@abstractmethod
def is_root(cls, path: Path) -> bool:
"""判断路径是否为根目录."""

@abstractmethod
def chdir(self, cwd: str = "home") -> AbstractContextManager[Path]:
"""临时切换到指定目录, 子进程将继承此 CWD。"""

@abstractmethod
async def achdir(self, cwd: str = "home") -> AbstractAsyncContextManager[Path]:
"""异步临时切换到指定目录, 子进程将继承此 CWD。"""
9 changes: 9 additions & 0 deletions astrbot/base/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
LOGO = r"""
___ _______.___________..______ .______ ______ .___________.
/ \ / | || _ \ | _ \ / __ \ | |
/ ^ \ | (----`---| |----`| |_) | | |_) | | | | | `---| |----`
/ /_\ \ \ \ | | | / | _ < | | | | | |
/ _____ \ .----) | | | | |\ \----.| |_) | | `--' | | |
/__/ \__\ |_______/ |__| | _| `._____||______/ \______/ |__|

"""
Loading