diff --git a/.planning/phases/02-platform-skills/02-02-PLAN.md b/.planning/phases/02-platform-skills/02-02-PLAN.md
index c5da558..c0315f8 100644
--- a/.planning/phases/02-platform-skills/02-02-PLAN.md
+++ b/.planning/phases/02-platform-skills/02-02-PLAN.md
@@ -2,7 +2,7 @@
phase: 02-platform-skills
plan: 02
type: execute
-wave: 1
+wave: 2
depends_on: [02-01]
files_modified:
- kb_pipeline/platforms/__init__.py
@@ -24,6 +24,7 @@ must_haves:
- "内容保存为Markdown文件(YAML Frontmatter + 正文)"
- "403错误触发降级策略(API -> Playwright)"
- "网络错误自动重试3次"
+ - "失败时记录错误原因到workflow_state.json"
artifacts:
- path: "kb_pipeline/platforms/base.py"
provides: "平台适配器基类"
@@ -48,12 +49,16 @@ must_haves:
to: "kb-bilibili-metadata/bilibili_extractor.py"
via: "BilibiliExtractor class"
pattern: "from kb_bilibili_metadata"
+ - from: "kb_pipeline/platforms/bilibili.py"
+ to: "kb_pipeline/state.py"
+ via: "WorkflowStateManager.mark_step_failed"
+ pattern: "mark_step_failed"
---
创建 B站平台适配器,封装视频和专栏的元数据提取与内容获取逻辑,复用现有 BilibiliExtractor 实现。
-Purpose: 为 B站视频和专栏提供统一的元数据提取和内容下载接口,支持错误重试和降级策略。
+Purpose: 为 B站视频和专栏提供统一的元数据提取和内容下载接口,支持错误重试、降级策略和状态记录。
Output: PlatformAdapter 基类、BilibiliAdapter 实现类
@@ -96,6 +101,23 @@ class StepOutput(BaseModel):
success: bool
error_message: Optional[str]
completed_at: datetime
+
+class WorkflowState(BaseModel):
+ content_id: str
+ platform: str
+ source_url: str
+ steps: Dict[str, StepRecord]
+
+ def mark_step_failed(self, step_name: str, error_message: str) -> None:
+ """标记步骤失败,记录错误信息"""
+```
+
+From kb_pipeline/state.py:
+```python
+class WorkflowStateManager:
+ def load(self) -> Optional[WorkflowState]: ...
+ def save(self, state: WorkflowState) -> None: ...
+ def get_or_create(self, content_id, platform, source_url) -> WorkflowState: ...
```
From kb_pipeline/errors.py:
@@ -200,13 +222,14 @@ DEFAULT_HEADERS = {
- Task 2: Implement BilibiliAdapter for video metadata
+ Task 2: Implement BilibiliAdapter for video metadata with state recording
kb_pipeline/platforms/bilibili.py, tests/test_platforms/test_bilibili.py
- Test 1: fetch_metadata("BVxxx", "video") 返回正确的视频元数据
- Test 2: 403错误时触发降级策略(API -> Playwright)
- Test 3: 网络错误自动重试3次
- Test 4: get_output_filename 返回正确格式 "bilibili_BVxxx_metadata.json"
+ - Test 5: 失败时调用 WorkflowStateManager.mark_step_failed() 记录错误
创建 kb_pipeline/platforms/bilibili.py:
@@ -214,24 +237,32 @@ DEFAULT_HEADERS = {
from kb_pipeline.platforms.base import PlatformAdapter
from kb_pipeline.errors import NetworkError, AuthError
from kb_pipeline.retry import retry_on_network_error
+ from kb_pipeline.state import WorkflowStateManager
from kb_bilibili_metadata.bilibili_extractor import BilibiliExtractor
class BilibiliAdapter(PlatformAdapter):
PLATFORM = "bilibili"
- def __init__(self, headless: bool = True, timeout: int = 30):
+ def __init__(self, headless: bool = True, timeout: int = 30, state_manager: Optional[WorkflowStateManager] = None):
self.extractor = BilibiliExtractor(headless=headless, timeout=timeout)
+ self.state_manager = state_manager
def get_content_type(self, url: str) -> str:
# 从 URL 识别 video 或 article
@retry_on_network_error
async def fetch_metadata(self, content_id: str, content_type: str) -> Dict[str, Any]:
- if content_type == "video":
- return self.extractor.extract_video_metadata(content_id)
- elif content_type == "article":
- return self.extractor.extract_article_metadata(content_id)
- raise ValueError(f"Unsupported content type: {content_type}")
+ try:
+ if content_type == "video":
+ return self.extractor.extract_video_metadata(content_id)
+ elif content_type == "article":
+ return self.extractor.extract_article_metadata(content_id)
+ raise ValueError(f"Unsupported content type: {content_type}")
+ except (NetworkError, AuthError) as e:
+ # 记录失败原因到状态文件
+ if self.state_manager:
+ self.state_manager.mark_step_failed("metadata", str(e))
+ raise
async def fetch_content(self, content_id: str, content_type: str) -> str:
# 视频内容获取留给 Phase 3 (ASR)
@@ -246,11 +277,12 @@ DEFAULT_HEADERS = {
- 使用 mock 模拟 BilibiliExtractor 的返回值
- 测试视频元数据提取
- 测试错误处理和重试机制
+ - 测试失败时状态记录到 WorkflowStateManager
pytest tests/test_platforms/test_bilibili.py::test_video_metadata -x -v
- BilibiliAdapter 能正确提取B站视频元数据,支持错误重试
+ BilibiliAdapter 能正确提取B站视频元数据,支持错误重试和状态记录
@@ -328,6 +360,7 @@ DEFAULT_HEADERS = {
- [ ] BilibiliAdapter 正确提取B站专栏内容和元数据
- [ ] 内容保存为 Markdown 格式,包含 YAML Frontmatter
- [ ] 网络错误自动重试3次
+- [ ] 403/超时错误触发降级策略,记录失败原因到 workflow_state.json
- [ ] 所有测试通过(至少 8 个测试用例)