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 个测试用例)