-
Notifications
You must be signed in to change notification settings - Fork 1.2k
修复看板日志不可见:自动选择正确任务数据源(多工作区) #117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -38,6 +38,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DIST = BASE / 'dist' # React 构建产物 (npm run build) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DATA = BASE.parent / "data" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SCRIPTS = BASE.parent / 'scripts' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _ACTIVE_TASK_DATA_DIR = None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 静态资源 MIME 类型 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _MIME_TYPES = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -82,21 +83,84 @@ def now_iso(): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return datetime.datetime.now(datetime.timezone.utc).isoformat().replace('+00:00', 'Z') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def load_tasks(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return atomic_json_read(DATA / 'tasks_source.json', []) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def _iter_task_data_dirs(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """返回可用的任务数据目录候选(优先 workspace,其次本地 data)。""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dirs = [DATA] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| oclaw_home = pathlib.Path.home() / '.openclaw' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for p in sorted(oclaw_home.glob('workspace-*/data')): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+89
to
+90
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| oclaw_home = pathlib.Path.home() / '.openclaw' | |
| for p in sorted(oclaw_home.glob('workspace-*/data')): | |
| for p in sorted(OCLAW_HOME.glob('workspace-*/data')): |
Copilot
AI
Mar 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
新增的数据目录自动探测会读取真实用户目录 ~/.openclaw/workspace-*/data,这会让现有的 tests/test_server.py 通过 patch srv.DATA 的方式无法完全隔离测试环境(可能被本机 workspace 的 tasks_source.json“抢走”数据源),导致测试与本地环境耦合。建议补充/调整测试覆盖:在测试里创建 tasks_source.json 并验证 get_task_data_dir() 的选择逻辑可控(或提供可注入/可禁用 workspace 探测的开关)。
Copilot
AI
Mar 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get_task_data_dir() 一旦把 _ACTIVE_TASK_DATA_DIR 缓存成某个目录,就只检查 is_dir() 并直接返回;如果服务启动时没有任何候选包含 tasks_source.json(或后续才在 workspace 生成),缓存会永久锁定到默认 DATA,导致多工作区场景下仍可能读错数据源。建议缓存前至少要求目录内存在 tasks_source.json,或在缓存命中时也验证该文件仍存在/必要时重新探测。
| if _ACTIVE_TASK_DATA_DIR and _ACTIVE_TASK_DATA_DIR.is_dir(): | |
| return _ACTIVE_TASK_DATA_DIR | |
| best_dir = DATA | |
| best_score = (-1, -1, -1, -1) | |
| for d in _iter_task_data_dirs(): | |
| tf = d / 'tasks_source.json' | |
| if not tf.exists(): | |
| continue | |
| score = _task_source_score(tf) | |
| if score > best_score: | |
| best_score = score | |
| best_dir = d | |
| # 缓存命中时,既要求目录存在,也要求其中仍有 tasks_source.json | |
| if _ACTIVE_TASK_DATA_DIR and _ACTIVE_TASK_DATA_DIR.is_dir(): | |
| if (_ACTIVE_TASK_DATA_DIR / 'tasks_source.json').exists(): | |
| return _ACTIVE_TASK_DATA_DIR | |
| # 若缓存目录已不再包含任务源文件,则丢弃缓存并重新探测 | |
| _ACTIVE_TASK_DATA_DIR = None | |
| best_dir = DATA | |
| best_score = None | |
| for d in _iter_task_data_dirs(): | |
| tf = d / 'tasks_source.json' | |
| if not tf.exists(): | |
| continue | |
| score = _task_source_score(tf) | |
| if best_score is None or score > best_score: | |
| best_score = score | |
| best_dir = d | |
| # 仅在找到至少一个包含 tasks_source.json 的目录时才缓存; | |
| # 否则返回默认 DATA,但不缓存,以便后续新建 workspace 时能重新探测。 | |
| if best_score is None: | |
| log.info(f'任务数据源: 默认 DATA(未找到 tasks_source.json)') | |
| return best_dir |
Copilot
AI
Mar 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_refresh_live_data_async() 在 workspace 目录下找不到脚本时会回退到仓库 scripts/refresh_live_data.py;但该脚本内部写死使用自身所在目录的 DATA = BASE / 'data'(见 scripts/refresh_live_data.py),会把 live_status.json 写回仓库 data,而不是当前选中的 task_data_dir。这会造成 save_tasks 之后看板仍读取不到最新 live_status。建议让刷新脚本支持传入 dataDir(参数或环境变量),或在回退时显式传递/切换到能写入 task_data_dir 的实现。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_iter_task_data_dirs()的 docstring 说“优先 workspace,其次本地 data”,但当前实现dirs = [DATA]后再 append workspace;在打分相同(或不存在 tasks_source 时回退)的情况下会更倾向选择本地 DATA,和说明不一致。建议要么调整候选顺序/加显式 tie-breaker,要么修正文档描述以匹配实际策略。