fix: 修复多个bug并合并社区贡献

Bug 修复:
- Fix #232: court_discuss.py 添加 from __future__ import annotations 兼容 Python 3.9
- Fix #233: Dockerfile 添加 channels 模块 COPY 解决 Docker 运行时 ModuleNotFoundError
- Fix #234: sync_agent_config.py 将 dispatchChannel 默认值从 'feishu' 改为空字符串
- Fix #241: sync_agent_config.py 收集 defaults.models 中的所有可用模型到看板选择器

社区贡献 (cherry-pick):
- PR #239 (@ElninoZhong): 添加 workflow state vs execution ownership 文档
- PR #237 (@ElninoZhong): 修复 feishu 默认值问题
- PR #212 (@YIOYIOIOI): Windows install.ps1 优先 python 命令 + UTF-8 编码修复

依赖更新 (Dependabot):
- actions/checkout v4 → v6
- docker/setup-buildx-action v3 → v4
- docker/build-push-action v5 → v7
- actions/labeler v5 → v6
- actions/stale v9 → v10
This commit is contained in:
cft0808
2026-03-30 21:48:55 +08:00
parent dc66e0666d
commit 0f1c24bd44
9 changed files with 71 additions and 15 deletions

View File

@@ -12,7 +12,7 @@ jobs:
label:
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v5
- uses: actions/labeler@v6
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
sync-labels: false
@@ -20,7 +20,7 @@ jobs:
size-label:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Label PR size
uses: codelytv/pr-size-labeler@v1
with:

View File

@@ -10,7 +10,7 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Shell lint
run: |
@@ -28,7 +28,7 @@ jobs:
matrix:
python-version: ['3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
@@ -52,13 +52,13 @@ jobs:
docker-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
- name: Build Docker image
uses: docker/build-push-action@v5
uses: docker/build-push-action@v7
with:
context: .
push: false

View File

@@ -13,7 +13,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
- uses: actions/stale@v10
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -11,8 +11,8 @@ COPY edict/frontend/ ./
# Build 输出到 /build/distvite.config 中 outDir 是相对路径,这里重写)
RUN npx vite build --outDir /build/dist
# Stage 2: 运行时
FROM --platform=${TARGETPLATFORM:-linux/amd64} python:3.11-slim
# Stage 2: 运行时 (多架构支持 amd64 + arm64)
FROM python:3.11-slim
WORKDIR /app
@@ -20,6 +20,9 @@ WORKDIR /app
COPY dashboard/ ./dashboard/
COPY scripts/ ./scripts/
# 复制通知渠道模块 (Fix #233: server.py 依赖 channels 包)
COPY edict/backend/app/channels/ ./edict/backend/app/channels/
# 复制 React 构建产物
COPY --from=frontend-build /build/dist ./dashboard/dist/

View File

@@ -11,6 +11,7 @@
- 命运骰子:随机事件
- 每个官员保持自己的角色性格和说话风格
"""
from __future__ import annotations
import json
import logging

View File

@@ -1597,3 +1597,43 @@ curl http://127.0.0.1:7891/api/task-activity/JJC-20260302-001
**核心价值**:用制度确保质量,用透明确保信心,用自动化确保效率。
相比 CrewAI/AutoGen 的"自由+人工管理",三省六部提供了一套**企业级的AI协作框架**。
## Workflow state vs execution ownership
In Edict workflows, **workflow state** and **execution ownership** are related but not always identical.
### Workflow state
Workflow state describes the current institutional stage of a task, for example:
- `Taizi`
- `Zhongshu`
- `Menxia`
- `Assigned`
- `Doing`
- `Review`
- `Done`
This is the stage shown in the board/UI and reflects where the task is in the intended process.
### Execution ownership
Execution ownership means which actual runtime agent/session currently owns the next action or is writing the next progress/log update.
In simple flows, workflow state and execution ownership may appear to match.
In more complex or multi-stage flows, they can temporarily diverge. For example:
- the workflow state may already show `Assigned`
- while the active runtime execution context is still tied to an earlier stage's dispatch chain
### Why this distinction matters
This distinction is useful when:
- debugging handoff behavior
- understanding why a later-stage label appears before a fully isolated execution handoff occurs
- reasoning about future improvements such as stage-isolated orchestration
In short:
- **workflow state** = where the task is in the institutional process
- **execution ownership** = which runtime path currently holds the next action
> This documentation does not change runtime semantics. It only clarifies an important concept for advanced real-world usage.

View File

@@ -34,9 +34,9 @@ function Check-Deps {
}
Log "OpenClaw CLI: OK"
$py = Get-Command python3 -ErrorAction SilentlyContinue
$py = Get-Command python -ErrorAction SilentlyContinue
if (-not $py) {
$py = Get-Command python -ErrorAction SilentlyContinue
$py = Get-Command python3 -ErrorAction SilentlyContinue
}
if (-not $py) {
Error "未找到 python3 或 python"

View File

@@ -91,6 +91,16 @@ def _collect_openclaw_models(cfg):
if dm and dm not in known_ids:
extra.append({'id': dm, 'label': dm, 'provider': 'OpenClaw'})
known_ids.add(dm)
# 收集 defaults.models 中的所有模型OpenClaw 默认启用的模型列表)
defaults_models = agents_cfg.get('defaults', {}).get('models', {})
if isinstance(defaults_models, dict):
for model_id in defaults_models.keys():
if model_id and model_id not in known_ids:
provider = 'OpenClaw'
if '/' in model_id:
provider = model_id.split('/')[0]
extra.append({'id': model_id, 'label': model_id, 'provider': provider})
known_ids.add(model_id)
# 收集每个 agent 的 model
for ag in agents_cfg.get('list', []):
m = normalize_model(ag.get('model', ''), '')
@@ -182,7 +192,7 @@ def main():
'generatedAt': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'defaultModel': default_model,
'knownModels': merged_models,
'dispatchChannel': existing_cfg.get('dispatchChannel') or os.getenv('DEFAULT_DISPATCH_CHANNEL', 'feishu'),
'dispatchChannel': existing_cfg.get('dispatchChannel') or os.getenv('DEFAULT_DISPATCH_CHANNEL', ''),
'agents': result,
}
DATA.mkdir(exist_ok=True)

View File

@@ -37,8 +37,10 @@ OFFICIALS = [
]
def rj(p, d):
try: return json.loads(pathlib.Path(p).read_text())
except Exception: return d
try:
return json.loads(pathlib.Path(p).read_text(encoding='utf-8'))
except Exception:
return d
# Pre-load openclaw config once (avoid re-reading per agent)