feat: 新增工具插件、系统日志、workflow配置及前端优化

1. 新增工具插件(edit_file, python_executor, search_file, shell_executor, write_file)
2. 新增系统事件日志模块和API
3. 新增workflow配置文件和详情API
4. 前端增加SSE、错误边界、设置引导等组件
5. 优化认证加密、速率限制、配置加载等工具模块
6. 删除废弃的cluster和health API
7. 补充单元测试和集成测试

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-03 07:34:43 +00:00
parent f04fef916f
commit a53ffebe0e
57 changed files with 2804 additions and 271 deletions
+80
View File
@@ -0,0 +1,80 @@
"""``api/workflow.py`` 读侧拼装:运行期状态 merge 到静态 step。"""
from __future__ import annotations
from kilostar.api.workflow import _merge_runtime_status
def test_merge_marks_pending_when_no_log():
"""没有任何运行日志时,所有 step 默认 pending。"""
work_link = [
{"step": 1, "name": "s1", "node": "skill_individual", "action": "a"},
{"step": 2, "name": "s2", "node": "consciousness_node", "action": "b"},
]
merged = _merge_runtime_status(work_link, [])
assert [s["status"] for s in merged] == ["pending", "pending"]
# 静态字段保留
assert merged[0]["name"] == "s1"
assert merged[1]["node"] == "consciousness_node"
def test_merge_uses_latest_status_per_step():
"""同一 step 多条日志时取最后一条(working → completed)。"""
work_link = [
{"step": 1, "name": "s1", "node": "skill_individual", "action": "a"},
]
workflow_log = [
{"0": ["2026-01-01T00:00:00", "working", "开始"]},
{"0": ["2026-01-01T00:00:05", "completed", "成功"]},
]
merged = _merge_runtime_status(work_link, workflow_log)
assert merged[0]["status"] == "completed"
def test_merge_mixed_statuses():
"""多 step 各自取自己最新状态;无日志的保持 pending。"""
work_link = [
{"step": 1, "name": "s1", "node": "skill_individual", "action": "a"},
{"step": 2, "name": "s2", "node": "skill_individual", "action": "b"},
{"step": 3, "name": "s3", "node": "skill_individual", "action": "c"},
]
workflow_log = [
{"0": ["t", "completed", "ok"]},
{"1": ["t", "failed", "boom"]},
]
merged = _merge_runtime_status(work_link, workflow_log)
assert [s["status"] for s in merged] == ["completed", "failed", "pending"]
def test_merge_falls_back_to_position_index_without_step_field():
"""step 没有 step 字段时按位置索引匹配日志。"""
work_link = [
{"name": "s1", "node": "skill_individual", "action": "a"},
{"name": "s2", "node": "skill_individual", "action": "b"},
]
workflow_log = [
{"1": ["t", "completed", "ok"]},
]
merged = _merge_runtime_status(work_link, workflow_log)
assert merged[0]["status"] == "pending"
assert merged[1]["status"] == "completed"
def test_merge_ignores_malformed_log_entries():
"""脏日志(非 dict / payload 不是数组 / key 不是数字)不应炸。"""
work_link = [
{"step": 1, "name": "s1", "node": "skill_individual", "action": "a"},
]
workflow_log = [
"not-a-dict",
{"not-an-int": ["t", "completed", "x"]},
{"0": "not-a-list"},
{"0": ["t", "working"]},
]
merged = _merge_runtime_status(work_link, workflow_log)
assert merged[0]["status"] == "working"
def test_merge_handles_empty_work_link():
assert _merge_runtime_status([], []) == []
assert _merge_runtime_status(None, None) == []