# opencode_py **Repository Path**: sky92archangel/opencode_py ## Basic Information - **Project Name**: opencode_py - **Description**: 使用python进行opencode 重写 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-27 - **Last Updated**: 2026-04-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # OpenCode Python Backend OpenCode Python Backend 是一个基于 Python/FastAPI 实现的 OpenCode 服务器后端,为 TypeScript/Bun 服务器提供 API 兼容的替代方案。 ## 项目概述 OpenCode 是一个 AI 编程助手后端服务,提供了完整的会话管理、消息处理、技能系统、工具执行等功能。本项目是 OpenCode 的 Python 实现版本,使用 FastAPI 作为 Web 框架,提供了高性能的异步处理能力。 ### 主要特性 - **API 兼容**: 与原始 OpenCode 客户端 100% 兼容 - **多数据库支持**: 以 SQLite 为主数据库,同时支持 PostgreSQL 和 SQL Server 同步 - **实时事件**: 基于 SSE 的事件流,支持实时更新推送 - **会话管理**: 完整的会话/消息/片段数据模型 - **技能系统**: 内置技能扫描和加载功能 - **工具执行**: 支持 Bash、文件读写、Glob、Grep 等工具 - **工作区隔离**: 多租户工作区支持 ## 技术栈 | 类别 | 技术 | |------|------| | Web 框架 | FastAPI + Starlette + Uvicorn | | 数据库 | SQLAlchemy 2.0 (异步) + SQLite | | 同步目标 | PostgreSQL (asyncpg), SQL Server (pyodbc) | | 数据库迁移 | Alembic | | 数据验证 | Pydantic v2 | | 事件流 | SSE-Starlette | | 任务队列 | 异步原生实现 | ## 系统架构 ``` ┌─────────────────────────────────────────────────────────────┐ │ 客户端 │ └─────────────────────────────┬───────────────────────────────┘ │ HTTP/SSE/WebSocket ┌─────────────────────────────▼───────────────────────────────┐ │ FastAPI 服务器 │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ 路由层 │ │ 服务层 │ │ 事件总线 │ │ 工具 │ │ │ │ Routes │ │ Services │ │ Bus │ │ Tools │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ │ │ │ │ ┌────▼─────────────▼─────────────▼─────────────▼────┐ │ │ │ SQLAlchemy 2.0 (异步) │ │ │ └────────────────────────────────────────────────────┘ │ └─────────────────────────────┬───────────────────────────────┘ │ ┌─────────────────────┼─────────────────────┐ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ SQLite │ │ PostgreSQL │ │ SQL Server │ │ (主数据库) │─────▶│ (同步) │ │ (同步) │ └──────────────┘ └──────────────┘ └──────────────┘ ``` ### 核心模块说明 | 模块 | 路径 | 说明 | |------|------|------| | `app/main.py` | 主入口 | FastAPI 应用创建、生命周期管理 | | `app/config.py` | 配置 | 环境变量配置加载和管理 | | `app/routes/` | 路由层 | API 路由定义和处理 | | `app/services/` | 服务层 | 业务逻辑实现 | | `app/models/` | 数据模型 | SQLAlchemy ORM 模型 | | `app/schemas/` | 数据模式 | Pydantic 数据验证模式 | | `app/tools/` | 工具层 | AI Agent 工具实现 | | `app/db/` | 数据库层 | 数据库连接和同步管理 | | `app/middleware/` | 中间件 | 认证和工作区中间件 | ## 快速开始 ### 环境要求 - Python 3.11+ - pip 或 pipenv ### 安装步骤 ```bash # 克隆项目 git clone cd opencode_py # 创建虚拟环境 python -m venv venv # 激活虚拟环境 # Linux/Mac source venv/bin/activate # Windows venv\Scripts\activate # 安装依赖 pip install -e . # 安装开发依赖(可选) pip install -e ".[dev]" ``` ### 配置 1. 复制环境变量示例文件: ```bash cp .env.example .env ``` 2. 编辑 `.env` 文件配置参数: ```bash # 基本配置 HOST=0.0.0.0 PORT=8080 DEBUG=false # 认证配置 BASIC_AUTH_USERNAME=admin BASIC_AUTH_PASSWORD=change-me # 数据库配置 DATABASE_URL=sqlite+aiosqlite:///./opencode.db # 可选:PostgreSQL 同步 PG_URL=postgresql://user:pass@localhost:5432/opencode PG_ENABLED=false # 可选:SQL Server 同步 MSSQL_URL=mssql+pyodbc://user:pass@localhost:1433/opencode MSSQL_ENABLED=false ``` ### 运行 ```bash # 开发模式(支持热重载) uvicorn app.main:app --reload --host 0.0.0.0 --port 8080 # 生产模式 python -m app.main # 或使用安装的命令 opencode ``` ### 验证安装 访问以下地址验证服务是否正常运行: - API 文档: http://localhost:8080/docs - 健康检查: http://localhost:8080/health - 替代 API 文档: http://localhost:8080/redoc ## 配置详解 ### 环境变量配置 | 变量名 | 说明 | 默认值 | |--------|------|--------| | `HOST` | 服务器监听地址 | `0.0.0.0` | | `PORT` | 服务器端口 | `8080` | | `DEBUG` | 调试模式 | `false` | | `WORKERS` | 工作进程数 | `1` | | `SECRET_KEY` | 安全密钥 | 自动生成 | | `BASIC_AUTH_USERNAME` | 基础认证用户名 | `admin` | | `BASIC_AUTH_PASSWORD` | 基础认证密码 | `change-me` | | `DATABASE_URL` | SQLite 数据库 URL | `sqlite+aiosqlite:///./opencode.db` | | `PG_URL` | PostgreSQL 数据库 URL | - | | `PG_ENABLED` | 启用 PostgreSQL 同步 | `false` | | `MSSQL_URL` | SQL Server 数据库 URL | - | | `MSSQL_ENABLED` | 启用 SQL Server 同步 | `false` | | `SYNC_INTERVAL_SECONDS` | 同步间隔(秒) | `5` | | `SYNC_BATCH_SIZE` | 同步批次大小 | `100` | | `DATA_DIR` | 数据目录 | `./data` | | `CACHE_DIR` | 缓存目录 | `./cache` | | `SKILLS_CACHE_DIR` | 技能缓存目录 | `./cache/skills` | | `LOG_LEVEL` | 日志级别 | `INFO` | | `LOG_FORMAT` | 日志格式 | `json` | | `CORS_ORIGINS` | CORS 允许的源 | `http://localhost:3000,http://localhost:5173` | ### AI Provider 配置 | 变量名 | 说明 | 默认值 | |--------|------|--------| | `OPENAI_API_KEY` | OpenAI API 密钥 | - | | `OPENAI_MODEL` | OpenAI 模型 | `gpt-4` | | `OPENAI_BASE_URL` | OpenAI API 基础 URL | - | | `ANTHROPIC_API_KEY` | Anthropic API 密钥 | - | | `ANTHROPIC_MODEL` | Anthropic 模型 | `claude-3-5-sonnet-20241022` | | `GOOGLE_API_KEY` | Google API 密钥 | - | | `GOOGLE_MODEL` | Google 模型 | `gemini-pro` | | `AZURE_OPENAI_ENDPOINT` | Azure OpenAI 端点 | - | | `AZURE_OPENAI_API_KEY` | Azure OpenAI API 密钥 | - | | `AZURE_OPENAI_DEPLOYMENT` | Azure OpenAI 部署名 | - | | `AWS_REGION` | AWS 区域 | `us-east-1` | | `BEDROCK_MODEL` | Bedrock 模型 | `anthropic.claude-3-sonnet-20240229-v1:0` | | `AWS_ACCESS_KEY_ID` | AWS 访问密钥 | - | | `AWS_SECRET_ACCESS_KEY` | AWS 秘密密钥 | - | ## API 接口文档 ### 健康检查接口 #### 基础健康检查 ``` GET /health ``` 返回服务器基本状态信息。 **响应示例:** ```json { "status": "ok", "version": "2.0.0" } ``` #### 就绪检查 ``` GET /health/ready ``` 验证所有依赖服务是否就绪。 **响应示例:** ```json { "ready": true, "checks": { "database": true, "sync": true }, "version": "2.0.0" } ``` #### 存活检查 ``` GET /health/live ``` 服务器存活状态检查。 **响应示例:** ```json { "alive": true } ``` --- ### 会话接口 #### 创建会话 ``` POST /session/ ``` 创建新的编程会话。 **请求头:** - `X-Workspace-Id`: 工作区 ID(可选) - `X-Directory`: 工作目录(可选) **请求体:** ```json { "directory": "/path/to/project", "project_id": "project-123", "parent_id": "parent-session-id", "title": "会话标题" } ``` **响应示例:** ```json { "id": "01ARZ3NDEKTSV4RRFFQ69G5FAV", "slug": "01ARZ3NDEKTSV4RRFFQ69G5FAV", "project_id": "project-123", "workspace_id": "workspace-id", "parent_id": "parent-session-id", "directory": "/path/to/project", "title": "会话标题", "version": 1, "share_url": null, "time": { "created": "2024-01-01T00:00:00", "updated": "2024-01-01T00:00:00" } } ``` #### 列出会话 ``` GET /session/ ``` 获取会话列表,支持分页。 **查询参数:** - `limit`: 返回数量(默认 100,范围 1-1000) - `offset`: 偏移量(默认 0) **响应示例:** ```json { "sessions": [...], "total": 100, "limit": 100, "offset": 0 } ``` #### 获取会话 ``` GET /session/{session_id} ``` 获取指定会话详情。 #### 更新会话 ``` PATCH /session/{session_id} ``` 更新会话信息。 **请求体:** ```json { "title": "新标题" } ``` #### 删除会话 ``` DELETE /session/{session_id} ``` 删除指定会话及其所有消息。 **响应:** `204 No Content` #### Fork 会话 ``` POST /session/{session_id}/fork?message_id={message_id} ``` 在指定消息处创建会话分支。 #### 中止会话 ``` POST /session/{session_id}/abort ``` 中止正在处理的会话。 **响应:** `204 No Content` #### 分享会话 ``` POST /session/{session_id}/share ``` 创建会话分享链接。 **响应示例:** ```json { "url": "/share/abc123def456" } ``` #### 取消分享 ``` DELETE /session/{session_id}/share ``` 移除会话分享链接。 **响应:** `204 No Content` #### 获取会话差异 ``` GET /session/{session_id}/diff?message_id={message_id} ``` 获取消息的文件变更记录。 --- ### 消息接口 #### 创建消息 ``` POST /session/{session_id}/message/ ``` 在会话中创建新消息。 **请求体:** ```json { "role": "user", "parts": [ { "type": "text", "text": "用户输入内容" } ] } ``` #### 列出消息 ``` GET /session/{session_id}/message/ ``` 获取会话中的消息列表。 **查询参数:** - `limit`: 返回数量(默认 100) - `offset`: 偏移量(默认 0) #### 获取消息 ``` GET /session/{session_id}/message/{message_id} ``` 获取指定消息详情。 #### 更新消息 ``` PATCH /session/{session_id}/message/{message_id} ``` 更新消息内容。 #### 添加消息片段 ``` POST /session/{session_id}/message/{message_id}/part ``` 向消息添加新的片段。 **请求体:** ```json { "type": "text", "data": { "text": "片段内容" } } ``` #### 更新消息片段 ``` PATCH /session/{session_id}/message/{message_id}/part/{part_id} ``` 更新消息中的指定片段。 --- ### 事件接口 #### 订阅事件流 ``` GET /event/ ``` 订阅服务器事件(SSE),按工作区过滤。 **请求头:** - `X-Workspace-Id`: 工作区 ID(可选) - `X-Directory`: 工作目录(可选) **事件类型:** | 事件类型 | 说明 | |----------|------| | `server.connected` | 连接建立 | | `server.heartbeat` | 心跳(每 30 秒) | | `message.created` | 新消息创建 | | `message.updated` | 消息更新 | | `message.part.updated` | 消息片段更新 | | `session.status` | 会话状态变更 | | `session.error` | 会话错误 | | `permission.asked` | 权限请求 | **响应示例:** ``` data: {"type":"server.connected","properties":{}} data: {"type":"message.updated","properties":{"session_id":"...","message":{...}}} ``` #### 全局事件流 ``` GET /event/global ``` 订阅全局事件流(无工作区过滤)。 --- ### 技能接口 #### 列出技能 ``` GET /skill/ ``` 列出所有可用的技能。 **响应示例:** ```json { "skills": [ { "name": "skill-name", "description": "技能描述", "location": "/path/to/skill" } ] } ``` #### 获取技能详情 ``` GET /skill/{name} ``` 获取指定技能的详细信息。 **响应示例:** ```json { "name": "skill-name", "description": "技能描述", "location": "/path/to/skill", "content": "技能内容", "files": ["file1.md", "file2.md"] } ``` #### 读取技能文件 ``` GET /skill/{name}/file/{file_path:path} ``` 读取技能目录中的文件。 #### 列出技能目录 ``` GET /skill/dirs ``` 列出所有技能搜索目录。 **响应示例:** ```json { "dirs": ["/path/to/dir1", "/path/to/dir2"] } ``` #### 拉取远程技能 ``` POST /skill/pull?url={remote_url} ``` 从远程 URL 拉取技能。 **响应示例:** ```json { "pulled": 1, "dirs": ["/path/to/pulled/skill"] } ``` --- ### 配置接口 #### 获取配置 ``` GET /config/ ``` 获取当前工作区的配置。 **请求头:** - `X-Workspace-Id`: 工作区 ID(可选) - `X-Directory`: 工作目录(可选) **响应示例:** ```json { "version": "2", "provider": {}, "mcp": {} } ``` #### 更新配置 ``` PATCH /config/ ``` 更新配置。 **请求体:** ```json { "patches": [ { "path": "/provider/openai", "value": { "api_key": "xxx" } } ] } ``` --- ## 架构设计 ### 数据模型 ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Session │──────▶│ Message │──────▶│ Part │ │ (会话) │ 1:N │ (消息) │ 1:N │ (片段) │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ ▼ ▼ ┌─────────────┐ ┌─────────────┐ │ Workspace │ │ Project │ │ (工作区) │ │ (项目) │ └─────────────┘ └─────────────┘ ``` ### 事件总线 系统使用发布-订阅模式处理异步事件: ```python # 事件发布 await global_bus.publish({ "type": "session.status", "properties": { "session_id": session_id, "status": {"type": "busy"}, }, }) # 事件订阅 @global_bus.subscribe("session.status") async def on_session_status(event): ... ``` ### AI Agent 执行流程 ``` ┌──────────────────────────────────────────────────────────────┐ │ 用户消息 │ └────────────────────────────┬─────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────┐ │ 1. 构建消息历史 │ │ Build Message History │ └────────────────────────────┬─────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────┐ │ 2. 调用 AI Provider │ │ Call AI Provider │ └────────────────────────────┬─────────────────────────────────┘ │ ┌──────────────┴──────────────┐ │ │ ▼ ▼ ┌────────────────┐ ┌────────────────┐ │ 返回文本 │ │ 工具调用 │ │ Text Output │ │ Tool Call │ └────────────────┘ └───────┬────────┘ │ ▼ ┌────────────────────────┐ │ 3. 执行工具 │ │ Execute Tool │ └───────┬────────────────┘ │ ▼ ┌────────────────────────┐ │ 4. 返回结果 │ │ Return Result │ └───────┬────────────────┘ │ └──────────────────▶ 循环调用 AI ``` ### 工具系统 系统内置以下工具: | 工具名称 | 说明 | 参数 | |----------|------|------| | `bash` | 执行 Bash 命令 | `command`: 命令字符串 | | `read` | 读取文件内容 | `path`: 文件路径 | | `write` | 写入文件内容 | `path`: 文件路径, `content`: 内容 | | `glob` | 文件模式匹配 | `pattern`: glob 模式 | | `grep` | 文本搜索 | `pattern`: 正则表达式, `path`: 搜索路径 | --- ## 开发指南 ### 项目结构 ``` opencode_py/ ├── app/ │ ├── __init__.py # 包初始化 │ ├── main.py # 应用入口 │ ├── config.py # 配置管理 │ ├── config/ # 配置模块 │ ├── db/ # 数据库层 │ │ ├── database.py # 数据库连接 │ │ └── sync/ # 同步管理 │ ├── middleware/ # 中间件 │ │ ├── auth.py # 认证中间件 │ │ └── workspace.py # 工作区中间件 │ ├── models/ # 数据模型 │ │ ├── base.py # 基础模型 │ │ ├── session.py # 会话模型 │ │ ├── workspace.py # 工作区模型 │ │ └── project.py # 项目模型 │ ├── routes/ # 路由定义 │ │ ├── session.py # 会话路由 │ │ ├── message.py # 消息路由 │ │ ├── event.py # 事件路由 │ │ ├── skill.py # 技能路由 │ │ ├── config.py # 配置路由 │ │ └── health.py # 健康检查路由 │ ├── schemas/ # Pydantic 模式 │ ├── services/ # 业务逻辑 │ │ ├── agent.py # AI Agent │ │ ├── bus.py # 事件总线 │ │ ├── session.py # 会话服务 │ │ ├── provider.py # AI Provider │ │ ├── skill.py # 技能服务 │ │ └── mcp.py # MCP 服务 │ └── tools/ # 工具实现 │ ├── base.py # 工具基类 │ ├── bash.py # Bash 工具 │ ├── read.py # 读文件工具 │ ├── write.py # 写文件工具 │ ├── glob.py # Glob 工具 │ └── grep.py # Grep 工具 ├── docs/ # 文档 ├── scripts/ # 脚本 ├── tests/ # 测试 ├── .env.example # 环境变量示例 ├── pyproject.toml # 项目配置 └── README.md # 项目说明 ``` ### 运行测试 ```bash # 运行所有测试 pytest # 运行测试并生成覆盖率报告 pytest --cov=app tests/ # 运行特定测试文件 pytest tests/test_api.py # 运行测试并显示详细输出 pytest -v tests/ ``` ### 代码检查 ```bash # Ruff 代码检查 ruff check app/ # 自动修复可检查的问题 ruff check --fix app/ # Mypy 类型检查 mypy app/ # 完整检查 ruff check app/ && mypy app/ ``` ### 预提交钩子 安装预提交钩子: ```bash pre-commit install ``` 运行预提交检查: ```bash pre-commit run --all-files ``` --- ## 数据库迁移 使用 Alembic 进行数据库迁移管理: ```bash # 创建新迁移 alembic revision --autogenerate -m "add new table" # 运行迁移 alembic upgrade head # 回滚迁移 alembic downgrade -1 # 显示迁移状态 alembic current alembic history ``` --- ## 许可证 本项目基于 MIT 许可证开源。 --- ## 贡献指南 欢迎提交 Issue 和 Pull Request! ### 提交 Issue - 描述清楚问题或功能请求 - 提供复现步骤(如适用) - 注明环境信息(Python 版本、操作系统等) ### 提交代码 1. Fork 本仓库 2. 创建特性分支 (`git checkout -b feature/amazing-feature`) 3. 提交更改 (`git commit -m 'Add amazing feature'`) 4. 推送到分支 (`git push origin feature/amazing-feature`) 5. 创建 Pull Request ### 代码规范 - 遵循 PEP 8 规范 - 使用类型注解 - 编写单元测试 - 更新相关文档