Files

152 lines
6.6 KiB
Markdown
Raw Permalink Normal View History

2026-08-23 22:44:18 +08:00
# PineAgents 品牌抽离方案(Branding Abstraction
> 目标:把散落在 271 个 Python + 147 个前端文件里的品牌字符串,**收敛到单一配置层**。做到「改品牌只改一处」,并最大限度降低与上游 QwenPaw rebase 时的冲突。
> 现状:`constant.py` 里品牌已部分集中(`PROJECT_NAME`、`WORKING_DIR`、env 前缀),但仍有大量硬编码散落在 cli / routers / providers / 前端。
---
## 1. 设计原则
1. **单一事实源(Single Source of Truth**:所有持久化标识、前缀、展示名集中在一个 `Branding` 配置对象。
2. **三前缀回退**:环境变量支持 `PINEAGENTS_`(主)→ `QWENPAW_``COPAW_`(遗留)逐级回退,保证旧部署/旧环境变量不被破坏。
3. **持久化标识与展示名分离**:数据目录、keyring、消息 tag 等持久化标识可独立于展示名配置(避免改展示名影响旧数据)。
4. **不破坏上游合并路径**:新增独立模块,尽量少改 `constant.py` 既有语义;上游改动通过「读 Branding 而非字面量」自然落地。
---
## 2. 目标结构
### 2.1 新增模块 `src/pineagents/branding.py`
```python
# -*- coding: utf-8 -*-
"""PineAgents 品牌与命名配置 —— 单一事实源。
改造/二次开发时:改这里,不要改散落在各文件的字面量。
"""
from __future__ import annotations
from dataclasses import dataclass, field
from pathlib import Path
@dataclass(frozen=True)
class Branding:
# ---- 展示名(可安全全量改名)----
project_name: str = "PineAgents" # 产品名(原 QwenPaw
cli_name: str = "pineagents" # CLI 命令(原 qwenpaw/copaw
package_name: str = "pineagents" # Python 包名
env_prefix: str = "PINEAGENTS_" # 环境变量主前缀
version: str = "2.1.0b1"
# ---- 持久化标识(改名需迁移,见第 3 节)----
working_dir_name: str = ".qwenpaw" # 数据目录(保守:沿用)
keyring_account: str = "qwenpaw" # 钥匙串主密钥账号(沿用)
message_tag_key: str = "qwenpaw_tag" # 消息元数据 tag(沿用)
message_client_id_key: str = "qwenpaw_client_message_id"
builtin_qa_agent_id: str = "QwenPaw_QA_Agent_0.2"
# ---- 兼容前缀(逐级回退)----
legacy_prefixes: tuple[str, ...] = ("QWENPAW_", "COPAW_")
# ---- 依赖主前缀派生出的 env key 前缀列表(供测试/检查用)----
env_keys: tuple[str, ...] = (
"WORKING_DIR", "SECRET_DIR", "KEYRING_ACCOUNT", "LOG_LEVEL",
)
BRAND = Branding()
```
### 2.2 改造 `constant.py` 的 `_get_env`(三前缀回退)
把现有的 `QWENPAW_``COPAW_` 两级回退,扩展为 `PINEAGENTS_``QWENPAW_``COPAW_` 三级:
```python
def _get_env(key, default=""):
if key in os.environ:
return os.environ[key]
if key.startswith(BRAND.env_prefix):
for legacy in BRAND.legacy_prefixes:
legacy_key = legacy + key[len(BRAND.env_prefix):]
if legacy_key in os.environ:
return os.environ[legacy_key]
return default
```
### 2.3 收敛关键常量(`constant.py` 改为读 `BRAND`
```python
PROJECT_NAME = BRAND.project_name
QWENPAW_MESSAGE_TAG_KEY = BRAND.message_tag_key # 保留别名避免大改
QWENPAW_CLIENT_MESSAGE_ID_KEY = BRAND.message_client_id_key
BUILTIN_QA_AGENT_ID = BRAND.builtin_qa_agent_id
```
> 说明:`QWENPAW_MESSAGE_TAG_KEY` 等**别名保留原名**,只是值改由 `BRAND` 提供。这样内部引用无需改动,持久化值也不变(沿用 `qwenpaw_tag`),仅品牌展示名切换为 PineAgents。
---
## 3. 持久化标识处理矩阵
| 标识 | 决策 | 理由 |
|------|------|------|
| 数据目录 `~/.qwenpaw` | **沿用**(不改) | 避免旧数据不可见;如需改,配 `working_dir_name` 并加迁移 |
| 钥匙串账号 | **沿用** | 改则主密钥失配、无法解密旧密钥 |
| 消息 tag | **沿用** | 旧消息上的 tag 需继续可读 |
| 内置 Agent ID | **沿用** | 旧会话归属需对上 |
| env 前缀 | **新增 `PINEAGENTS_` 为主** | 新部署用新前缀;旧变量靠回退仍生效 |
**结论**PineAgents 默认「展示名全改、持久化标识沿用」,实现零迁移平滑改造。
---
## 4. 前端抽离(`console/`
前端同样收敛到一个品牌常量文件,例如 `console/src/constants/branding.ts`
```ts
export const BRAND = {
name: "PineAgents",
cli: "pineagents",
docBase: "https://<你的文档域名>/",
// ...
} as const;
```
- 所有组件(`layouts/``locales/``pages/**`)改读 `BRAND.name`,替换字面量 `"QwenPaw"` / `"qwenpaw"`
- `console/index.html``<title>` 与 favicon、`console/package.json` 的 name 直接改为 PineAgents。
---
## 5. 打包与部署入口
- `pyproject.toml``name="pineagents"``[project.scripts] pineagents = "pineagents.cli.main:cli"`(保留 `qwenpaw`/`copaw` 作为兼容别名可选),coverage source、package-data 同步。
- `docker-compose.yml` / `deploy/` / `scripts/`:镜像名、容器卷名、启动命令改 `pineagents`
- 包目录改名 `src/pineagents``src/pineagents`(或保留目录名、仅内部标识改名,视同步策略二选一,见第 6 节)。
---
## 6. 同步策略:目录改名 or 不改?
两条路,按上游同步频率取舍:
| 方案 | 做法 | 优点 | 缺点 |
|------|------|------|------|
| **A. 目录改名** `src/pineagents/` | 一劳永逸品牌干净 | 产物、import 全干净 | 每次 rebase 上游 271 个文件路径全变,冲突巨大 |
| **B. 目录沿用** `src/pineagents/` | 包名/import 保留 qwenpaw,仅展示层改 PineAgents | rebase 冲突最小 | import 里仍带 qwenpaw 字样 |
**建议**PineAgents 走「Fork + 上游同步」,选 **方案 B**(目录沿用 `src/pineagents/`、import 保留),只把**展示层 + 配置 + 打包入口**切到 PineAgents。这样 rebase 上游时只处理少量展示层文件。若将来决定彻底冻结上游,再一次性迁移到 `src/pineagents/`
---
## 7. 分步落地
1. 新增 `src/pineagents/branding.py``Branding` 配置对象)。
2. `constant.py``PROJECT_NAME` 等改读 `BRAND``_get_env` 改三前缀回退。
3. 前端新增 `console/src/constants/branding.ts`,替换关键展示名。
4. `pyproject.toml` / `docker-compose.yml` / `deploy/`:打包与部署入口切 `pineagents`
5. 替换 `console/public` 品牌素材(logo/favicon/启动图)。
6. 关闭/替换遥测上报。
7. 运行 `tests/` 与 e2e 回归,确认持久化标识未破坏。