Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
100 changes: 50 additions & 50 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,77 +11,77 @@ concurrency:
cancel-in-progress: true

jobs:
# ─── Gate 1: Lint (ruff) ───────────────────────────────────────────
lint:
name: "Gate 1: Lint (ruff)"
quality:
name: Quality Gates
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4

- name: Set up Python 3.12
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: "3.12"
python-version: ${{ matrix.python-version }}

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install ruff
python -m pip install -e ".[dev]"
npm ci

- name: Ruff check (linting)
run: ruff check src/ tests/
- name: Ruff check
run: python -m ruff check src tests

- name: Ruff format (formatting)
run: ruff format --check src/ tests/
- name: Ruff format
run: python -m ruff format --check src tests

# ─── Gate 2: Type check (mypy) ─────────────────────────────────────
typecheck:
name: "Gate 2: Type check (mypy)"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Mypy
run: python -m mypy src

- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Node syntax check
run: npm run check

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install mypy
- name: Pytest
run: python -m pytest -q

- name: Mypy strict
run: mypy src/

# ─── Gate 3: Tests (pytest + coverage) ─────────────────────────────
test:
name: "Gate 3: Tests (py${{ matrix.python-version }})"
package:
name: Build & Wheel Smoke
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]

needs: quality
steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
python-version: "3.12"

- name: Install dependencies
- name: Build and verify
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"

- name: Run tests with coverage
run: pytest --cov=roundtable --cov-report=term-missing --cov-report=xml -v

- name: Upload coverage report
if: matrix.python-version == '3.12'
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage.xml
python -m pip install --upgrade pip build twine
python -m build
python -m twine check dist/*
python -m venv /tmp/roundtable-smoke
/tmp/roundtable-smoke/bin/python -m pip install --upgrade pip
/tmp/roundtable-smoke/bin/python -m pip install dist/*.whl
/tmp/roundtable-smoke/bin/python - <<'PY'
from importlib import resources
import roundtable

assert roundtable.__version__ == "2.1.0"
assert (resources.files("roundtable") / "web" / "viewer.js").is_file()
assert (resources.files("roundtable") / "web" / "i18n.js").is_file()
assert (resources.files("roundtable") / "templates" / "product-review.json").is_file()
assert (resources.files("roundtable") / "skills" / "mcp-roundtable" / "SKILL.md").is_file()
PY
/tmp/roundtable-smoke/bin/python -m roundtable.demo --no-web --rounds 1
27 changes: 0 additions & 27 deletions .github/workflows/lint.yml

This file was deleted.

21 changes: 11 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ permissions:
id-token: write

jobs:
# ─── Run Tests (gate before any publishing) ─────────────────────────
test:
name: Run tests
# ─── Preflight (gate before any publishing) ─────────────────────────
preflight:
name: Release preflight
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -22,18 +22,19 @@ jobs:
with:
python-version: "3.12"

- name: Install package with dev extras
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm

- name: Run pytest
run: python -m pytest tests/ --ignore=tests/test_web_viewer.py -q
- name: Run release preflight
run: scripts/release/preflight-check.sh

# ─── Build Python Package ───────────────────────────────────────────
build:
name: Build distribution
needs: test
needs: preflight
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down
30 changes: 0 additions & 30 deletions .github/workflows/test.yml

This file was deleted.

1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,3 @@ docs/internal/

# Node.js
node_modules/
package-lock.json
26 changes: 19 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
```bash
# 克隆仓库
git clone https://github.com/MoyuFamily/agent-roundtable.git
cd roundtable
cd agent-roundtable

# 创建虚拟环境
python -m venv .venv
Expand All @@ -62,28 +62,40 @@ pytest tests/test_core.py
pytest tests/test_core.py::TestCreateDiscussion -v

# 运行 lint
ruff check .
ruff format --check .
ruff check src tests
ruff format --check src tests

# 类型检查
mypy src/
mypy src
```

### Web Viewer 本地开发

Web viewer 需要 Node.js >= 18。
Web Viewer 需要 Node.js >= 18。`create_discussion()` 默认会以 `web=True` 尽力启动 Viewer;如果 Node 不存在或依赖安装失败,核心讨论仍应创建成功,并通过 `web_status`、`web_error`、`web_help` 返回诊断

```bash
# 安装 Node 依赖
npm install

# 检查 Web Viewer 语法
npm run check

# 运行带 web viewer 的 demo
python -m roundtable.demo --web

# 或显式关闭 web viewer
python -m roundtable.demo --no-web
```

可选 Python 依赖(web 功能):`nanoid`、`bcrypt`。通过 `pip install -e ".[web]"` 安装。
`package-lock.json` 是发布输入的一部分,请提交并维护。首跑自动安装只允许写入项目/包可控目录;不要在代码里无提示安装全局 npm 包。自动安装会设置 `PUPPETEER_SKIP_DOWNLOAD=true`,避免首跑下载 Chromium;PDF 导出缺浏览器时应返回明确错误。

可选 Python 依赖(web 功能):`nanoid`,通过 `pip install -e ".[web]"` 安装。Node 依赖(server.mjs):`bcryptjs`、`md-to-pdf`,已在 `package.json` 中声明;普通运行可用 `npm install --omit=dev`。

可选 Node 依赖(server.mjs):`bcryptjs`、`md-to-pdf`。已在 package.json 中声明,`npm install` 即可。
发布前请运行:

```bash
scripts/release/preflight-check.sh
```

### Web Viewer Schema 迁移

Expand Down
6 changes: 5 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ include CHANGELOG.md
include SECURITY.md
include pyproject.toml

recursive-include src/roundtable/web *.html *.css *.mjs *.cjs
recursive-include src/roundtable/web *.html *.css *.js *.json *.mjs *.cjs
recursive-include src/roundtable/templates *.json
recursive-include src/roundtable/skills *.md *.py *.json
include src/skills/SKILL.md
recursive-include docs *.md

prune docs/internal
prune docs/product
prune src/skills/references
prune .github
prune .hermes
prune .venv
Expand Down
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ pip install agent-roundtable
| 包名和导入名是什么? | 安装 `agent-roundtable`,代码里 `import roundtable` |
| 能不能独立使用? | 可以,核心库只依赖 Python 标准库和 SQLite |
| 能不能接 Agent 框架? | 可以,通过 adapter 接入 Hermes Agent 或任意 Agent 系统 |
| Web Viewer 会不会影响首跑? | 默认会尽力启动 Web Viewer;失败不阻断讨论,可看 `web_status` / `web_error` |
| 输出是什么? | 讨论状态、convergence score、共识/分歧、结构化 summary 与结论 |

## 🧭 什么时候用它?
Expand All @@ -62,13 +63,13 @@ pip install agent-roundtable

### 安装

PyPI 发布后,请使用正式包名安装
正式包名是 `agent-roundtable`

```bash
pip install agent-roundtable
```

发布前或需要验证当前分支时,可从源码安装:
需要验证当前分支或本地修改时,可从源码安装:

```bash
git clone https://github.com/MoyuFamily/agent-roundtable.git
Expand Down Expand Up @@ -117,6 +118,11 @@ result = core.create_discussion(
max_rounds=3,
)
disc_id = result["discussion_id"]
if result["web_status"] == "ready":
print(f"Web Viewer: {result['web_url']}")
elif result["web_status"] == "failed":
print(result["web_error"])
print(result["web_help"])

# 2. 参与者发言
core.speak(disc_id, "backend_architect", "PostgreSQL 的 JSON 和事务能力更适合复杂业务建模。")
Expand All @@ -135,6 +141,16 @@ print(summary["structured_summary"])
core.end_discussion(disc_id, conclusion="选择 PostgreSQL,优先支持复杂数据结构和长期扩展。")
```

### 默认 Web Viewer

`create_discussion()` 默认 `web=True`,会尽力启动本地 Web Viewer,这是 Roundtable 的核心体验之一。核心讨论创建优先成功;如果本机没有 Node.js、npm 依赖安装失败或端口不可用,返回值会包含:

- `web_status`: `"ready"`、`"failed"` 或 `"disabled"`
- `web_url`: Viewer 地址,失败时为 `None`
- `web_error` / `web_help`: 可读诊断和修复提示

Web Viewer 需要 Node.js 18+。Roundtable 会复用已在线服务、直接启动 `node server.mjs`,并在缺少本地 npm 依赖时尝试 `npm install --omit=dev`;不会自动安装 Node 本体,也不会无提示安装全局 PM2。自动安装会跳过 Puppeteer 的 Chromium 下载;Markdown 导出始终可用,PDF 导出缺浏览器时会返回清晰诊断。

### 错误安全模式(推荐用于生产环境)

```python
Expand Down Expand Up @@ -174,6 +190,7 @@ result = rt.init(
| 📊 **收敛追踪** | 自动计算每轮共识度(convergence score),量化讨论进展 |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good: The new web_status / web_error / web_help documentation is clear and matches the implementation. Helpful addition for operators debugging viewer startup.

| 🧾 **结构化总结** | 输出共识、分歧、决策建议和结论,适合沉淀会议记录与决策文档 |
| 🔌 **框架无关** | 独立运行,或通过 adapter 接入任何 Agent 框架 |
| 🖥️ **默认 Web Viewer** | 创建讨论时默认尽力启动实时 Viewer,失败不阻断核心讨论 |
| 🔔 **实时通知** | 讨论事件推送到飞书、Slack 或任意消息平台 |
| 🛡️ **错误安全** | Generic adapter 所有方法返回 dict,永不抛异常 |
| 🗂️ **SQLite 持久化** | 讨论记录持久存储,随时回溯 |
Expand Down Expand Up @@ -226,7 +243,6 @@ src/roundtable/

## 🛣️ 后续计划

- 发布 `agent-roundtable` 到 PyPI
- 补充 CLI 示例和端到端 Demo
- 增强结构化总结模板
- 补充更多 Agent 框架 adapter
Expand Down
Loading
Loading