Commit Graph

60 Commits

Author SHA1 Message Date
starmen1265 87a1740cd3 feat(14-05): integrate cache into UnifiedSegmentationStrategy
- Add cache parameter to UnifiedSegmentationStrategy.__init__()
- Add cache logic to segment() method (check before LLM, save after)
- Pass cache parameter through SemanticSegmentationEngine.__init__()
- Implement missing chunking methods (_segment_single_chunk, _segment_multiple_chunks, etc.)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 22:40:24 +08:00
starmen1265 5c32cfdf69 test(14-01): 实现 LLM 调用的可恢复错误检测和重试逻辑
- 添加 _is_recoverable_error() 静态方法判断错误类型
- 可恢复错误: ConnectionError, Timeout, HTTPError (429/500/502/503/504)
- 不可恢复错误: 其他 HTTPError (4xx), ValidationError
- 重试逻辑: 仅对可恢复错误重试 1 次,立即重试(无延迟)
- 改进日志记录: 重试用 info 级别,降级用 warning 级别
- 降级时记录具体错误类型和消息

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 22:38:28 +08:00
starmen1265 baf7c0f521 feat(14-03): implement SemanticCache for content-based caching
- compute_content_hash(): 计算 SHA256 内容哈希
- SemanticCache.get(): 从缓存读取 SegmentationResult
- SemanticCache.set(): 保存 SegmentationResult 到缓存
- 支持版本控制(CACHE_VERSION = '1.0')
- 缓存存储在 .planning/cache/semantic/ 目录
- 错误容错:缓存失败不影响主流程
- 自动创建缓存目录

遵守用户决策:
- 缓存键: SHA256 内容哈希
- 缓存存储: 本地文件系统
- 缓存 TTL: 永久有效
- 缓存内容: 完整的 SegmentationResult

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 22:35:57 +08:00
starmen1265 ef4a660faa feat(13-07): integrate SemanticSegmentationEngine into SRTProcessor
- 添加 enable_semantic_segmentation 参数到 SRTProcessor.__init__
- 启用时使用 SemanticSegmentationEngine,禁用时使用 SemanticSegmenter
- AI 不可用时自动降级到规则分段
- 更新 _generate_markdown() 支持带标题的 VideoSegment 输出
- 调整步骤顺序:先加载元数据,再进行语义分段
- 更新 UnifiedSegmentationStrategy.segment() 返回 List[VideoSegment]
- 添加代理方法到 SemanticSegmentationEngine 以保持向后兼容
- 创建全面的集成测试(9 个测试用例)
- 更新现有语义引擎测试以适配新 API

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 00:32:14 +08:00
starmen1265 0d8ed1f22f feat(13-06): implement extensible strategy architecture for segmentation
- Define SegmentationStrategy Protocol interface (Plan 13-06)
- Implement UnifiedSegmentationStrategy with unified approach for all video types
- Update SemanticSegmentationEngine to use strategy pattern
- Add comprehensive tests for strategy extensibility (STRAT-01, STRAT-02, STRAT-03)

Key changes:
- SegmentationStrategy Protocol defines the strategy interface
- UnifiedSegmentationStrategy implements unified approach (per user decision)
- SemanticSegmentationEngine now uses strategy injection pattern
- Tests verify strategy protocol, unified strategy, custom strategy injection, and extensibility

The architecture supports future extension (e.g., knowledge-type specific strategies)
while Phase 13 uses the unified strategy approach.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 00:29:54 +08:00
starmen1265 759503f48a feat(13-05): 实现中文句边界检测指令
更新 SEGMENTATION_PROMPT,增强句边界检测:
- 列举所有中文句末标点(。?!……)
- 强调「自然停顿处」和「语义停顿」
- 说明「不仅依赖标点符号」

添加测试验证句边界检测效果:
- test_chinese_sentence_boundary_punctuations
- test_prompt_emphasizes_semantic_pause
- test_prompt_not_only_punctuation
- test_sentence_boundary_in_segmentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 00:25:40 +08:00
starmen1265 00319f523f feat(13-01): implement video type detection and Pydantic models
- 创建 SemanticSegmentationEngine 类
- 实现 VideoSegment 和 SegmentationResult Pydantic 模型
  - VideoSegment: title(可选), content(必填), start_index, end_index
  - SegmentationResult: video_type, segments[], actual_segment_count
  - 添加标题长度验证器(5-15字)
- 实现 _infer_video_type() 方法
  - 从元数据推断视频类型(知识类/故事类/访谈类/新闻类/vlog)
  - 支持从 title, category, tags 推断
  - 默认类型为"知识类"
- 实现 _build_prompt() 方法
  - 包含视频类型信息
  - 包含完整的分段要求(数量控制、句边界保护、标题生成等)
  - 包含 JSON 输出格式规范
- 添加 extract_json_from_llm_response() 工具函数
- 添加 AIClientProtocol 协议定义
- 添加 deferred-items.md 记录超出范围的测试

所有计划 13-01 测试通过(10个测试)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 00:25:21 +08:00
starmen1265 8c2b3e079a feat(13-04): 实现主题标题生成功能
实现 VideoSegment.title 字段和验证,Prompt 中的标题生成指令。

功能:
- VideoSegment.title: Optional[str] 字段
- @field_validator 验证标题长度(不超过 15 字)
- SEGMENTATION_PROMPT 包含标题生成指令
- LLM 自主判断是否需要标题(主题/章节有标题,论点/观点无标题)
- 测试验证标题生成和省略

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 00:24:58 +08:00
starmen1265 a2ca45523b fix(srt): add punctuation requirement to ASR correction prompt
- Update CORRECTION_PROMPT to explicitly require adding punctuation
- Fix missing punctuation in thunderstorm and lightning sections

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 23:20:07 +08:00
starmen1265 0752f8b38f debug: add API response logging to investigate content vs reasoning_content
PR Test / lint (pull_request) Successful in 2s
2026-03-21 22:47:15 +08:00
starmen1265 4d2645876b fix(srt): add disable_reasoning parameter for ASR correction and include title in archive filename
PR Test / lint (pull_request) Successful in 1s
- SimpleAIClient: Add disable_reasoning parameter to control AI thinking mode
- ASRCorrector: Use disable_reasoning=True to get direct correction results
- ArchiveProcessor: Extract title from frontmatter and include in filename

File naming format: {YYYYMMDD}_{content_id}_{title}_analysis.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 22:19:14 +08:00
starmen1265 7ac4937c48 fix(deep-analyzer, srt): correct Zhipu API thinking parameter and fix metadata handling
Root cause:
1. thinking.type="disabled" caused ASR correction accuracy degradation
2. SRTProcessor didn't flatten nested metadata structure
3. Low-quality auto-generated summary section
4. duration field type handling issue

Changes:
- DeepAnalyzer: Remove thinking.type="disabled" to enable default thinking mode
- SRTProcessor: Add metadata flattening for nested structures
- SRTProcessor: Remove low-quality summary section generation
- SRTProcessor: Add duration type checking (string or int)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 21:41:29 +08:00
starmen1265 1f599f0c60 fix: correct Zhipu API thinking parameter and add non-interactive archive mode
PR Test / lint (pull_request) Successful in 2s
2026-03-20 00:44:41 +08:00
starmen1265 7903690882 fix(deep-analyzer): add disable_reasoning parameter to GLM API calls
PR Test / lint (pull_request) Successful in 1s
2026-03-20 00:28:33 +08:00
starmen1265 fbdfc2d68a fix(12-02): add SRTProcessor to processors/__init__.py exports
PR Test / lint (pull_request) Successful in 1s
2026-03-20 00:16:53 +08:00
starmen1265 a175a3242c fix(12-02): add deprecation warning to DeepAnalyzer
- Add logging warning in DeepAnalyzer.__init__
- Warn that Bilibili video should use SRTProcessor instead
- Keep functionality intact for Zhihu and other platforms

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 23:46:08 +08:00
starmen1265 b3b6498a71 feat(12-02): update CLI processor registration
- Import SRTProcessor from processors module
- Add SRTProcessor to processors list
- Update PipelineConfig.steps to include 'srt' step
- Pipeline will select SRTProcessor or AnalyzeProcessor based on platform

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 23:44:05 +08:00
starmen1265 8d41a1b324 feat(12-02): modify Pipeline for platform-specific processing flow
- Add Bilibili video detection: platform=bilibili and content_type=video
- Skip analyze step for Bilibili videos, use srt step instead
- Skip srt step for non-Bilibili-video content
- Add SRTInput import and step input creation logic
- Update _populate_skipped_step_results for srt step
- Add output_file, paragraphs, tags, corrected to result fields

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 23:43:39 +08:00
starmen1265 812f016b1b chore(12-01): update srt module exports
- Add SemanticSegmenter and ASRCorrector to __all__
- Maintain lazy loading for optional dependencies

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 23:39:20 +08:00
starmen1265 87b1919483 feat(12-01): implement SRTProcessor and Markdown generation
- Add SRTInput/SRTOutput schemas to pipeline
- Create SRTProcessor following BaseProcessor pattern
- Generate Markdown with YAML frontmatter
- Support metadata extraction and formatting
- Handle missing metadata gracefully

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 23:38:56 +08:00
starmen1265 5e00632f68 feat(12-01): implement ASRCorrector for speech recognition error correction
- Use LLM to correct obvious ASR errors (homophones, missing words)
- Batch processing for long text (5000 chars per batch)
- Fallback to original text when AI unavailable
- Simple sentence-based text splitting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 23:35:53 +08:00
starmen1265 a350693863 feat(12-01): implement SemanticSegmenter for subtitle segmentation
- Merge short segments into paragraphs
- Split on time gaps (>3 seconds by default)
- Enforce max paragraph length (500 chars by default)
- Simple rule-based approach (no LLM needed)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 23:34:18 +08:00
starmen1265 c259e0ac2f feat(12-01): implement SRT parser module
- Add Segment dataclass for subtitle segments
- Add parse_srt() function to parse SRT content string
- Add parse_srt_file() function to parse from file path
- Support standard SRT format with timestamps
- Handle special characters and multi-line subtitles

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 23:32:57 +08:00
starmen1265 7915808413 fix(cli): use json mode for model_dump serialization
PR Test / lint (pull_request) Successful in 2s
Ensure Pydantic model serializes to JSON-compatible format.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 22:59:36 +08:00
starmen1265 08cbe24d08 feat(11-02): integrate stealth fingerprint masking into ZhihuCrawler
- Add stealth_config parameter to ZhihuCrawler.__init__
- Add --disable-blink-features=AutomationControlled to launch args
- Call apply_stealth_sync after browser context creation
- Maintain backward compatibility (stealth enabled by default)
- Add 8 integration tests covering stealth behavior and compatibility

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 23:53:22 +08:00
starmen1265 e152b8ea05 feat(11-01): create stealth fingerprint masking module
- Add StealthConfig Pydantic model with all playwright-stealth options
- Add apply_stealth_sync/apply_stealth_async functions for browser context
- Add get_default_stealth_config convenience function
- Add 9 unit tests covering config defaults, stealth application, and disabled mode
- Update conftest.py with stealth_config and mock_browser_context fixtures

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 23:47:50 +08:00
starmen1265 b66bcc08b1 feat(10-02): integrate ProxyPool into ZhihuCrawler
- Add proxy_pool parameter to ZhihuCrawler constructor
- Add _current_proxy tracking for health check feedback
- Implement _parse_proxy_url static method for URL parsing
- Implement _on_request_success/failure for proxy health feedback
- Prioritize proxy_pool over config.proxy for multi-proxy support
- Maintain backward compatibility with single proxy config

Tests:
- test_crawler_accepts_proxy_pool
- test_crawler_without_proxy_pool (backward compatibility)
- test_parse_proxy_url (HTTP, auth, SOCKS5)
- test_proxy_pool_takes_priority_over_config

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 16:48:48 +08:00
starmen1265 c58a7d08b6 feat(10-01): implement proxy pool core functionality
- ProxyEntry: tracks proxy state, failures, and recovery
- ProxyPoolConfig: YAML configuration model
- ProxyPool: manages multiple proxies with round-robin rotation
- from_yaml(): load from ~/.kb_proxies.yaml
- from_env_fallback(): backward compatible env var loading
- get_next_proxy(): round-robin with lazy recovery check

Implements PROXY-01 (multi-proxy config) and PROXY-02 (rotation)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 16:39:39 +08:00
starmen1265 9c8ac34138 fix(kb_workflow): resolve module/package naming conflict
PR Test / lint (pull_request) Successful in 1s
Rename kb_workflow.py to cli.py to avoid conflict with kb_workflow/ package.
Add __main__.py to support `python -m kb_workflow` execution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 10:35:33 +08:00
starmen1265 9d2433322a fix(crawler): set proxy_required=False by default
PR Test / lint (pull_request) Successful in 2s
旁路由 (192.168.1.200) provides automatic system-level proxy.
No explicit HTTP_PROXY/HTTPS_PROXY configuration needed.
2026-03-18 00:04:48 +08:00
starmen1265 c09c8588f0 fix(crawler): resolve circular import in zhihu_crawler
Circular import chain:
  zhihu_crawler -> pipeline.config -> pipeline.platforms -> zhihu_crawler

Fix: Lazy import get_settings() inside _get_cookie() method instead of
module-level import.
2026-03-18 00:03:02 +08:00
starmen1265 6a819b6c80 docs(skill): update kb_workflow SKILL.md to reflect current implementation
PR Test / lint (pull_request) Successful in 2s
- Fix CLI path: kb-workflow -> kb_workflow
- Add login command documentation for Zhihu
- Update directory structure to match actual paths
- Add environment variable checks section
- Document strict failure handling principle
- Update technical architecture diagram
2026-03-17 23:50:42 +08:00
starmen1265 76f06c330b feat(09-01): integrate ZhihuCrawler into ZhihuAdapter
- Replace ZhihuPlaywrightExtractor with ZhihuCrawler
- Add comment crawling with include_comments=True by default
- Implement cookie expiration detection and QR code login trigger
- Add idempotency check via IdempotencyChecker
- Add comment formatting with "## 热门评论" section
- Convert HTML content to Markdown using html2text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 23:14:22 +08:00
starmen1265 9e1452d2a9 feat(08-03): integrate proxy, delay, and retry into ZhihuCrawler
- Add CrawlerConfig with ProxyConfig, delay, and retry settings
- Integrate proxy configuration via _start_browser_with_proxy()
- Add random delay via _apply_random_delay()
- Add retry logic via _crawl_with_retry using tenacity
- Add ZhihuApiInterceptor tests for x-zse-96 handling
- All tests pass
2026-03-17 22:14:47 +08:00
starmen1265 626fb73a58 feat(08-03): create CrawlerConfig for proxy and rate limiting
- Add CrawlerConfig with ProxyConfig, delay, and retry settings
- Support HTTP_PROXY/HTTPS_PROXY environment variable parsing
- Add proxy_required validation with clear error message
- Add get_crawler_config singleton for configuration access

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 21:57:09 +08:00
starmen1265 f41e75a1b2 feat(08-02): implement crawl_comments method with hot sorting
- Add COMMENT_API_TEMPLATE for comment API URL
- Implement crawl_comments() returning CommentsResult
- Use order=hot for popular comments sorting
- Only fetch first-level comments (no nested replies)
- Add include_comments parameter to crawl_answer()
- Export CommentAuthor, CommentData, CommentsResult in __init__.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 21:56:47 +08:00
starmen1265 b1f57922da feat(08-02): add CommentData models for comment crawling
- Add CommentAuthor model for comment author info
- Add CommentData model with content, author, likes, child_count
- Add CommentsResult model for crawl operation result
- Update CrawlResult to include optional comments field

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 21:53:17 +08:00
starmen1265 aa96bc963c feat(08-01): implement ZhihuCrawler with API interception
- Add ZhihuCrawler class with crawl_answer() and crawl_article() methods
- Implement ZhihuApiInterceptor for capturing /api/v4/ responses
- Add _parse_author(), _parse_metadata(), _parse_answer_data(), _parse_article_data() helpers
- Support DOM parsing fallback for zhuanlan articles
- Export ZhihuCrawler and ZhihuApiInterceptor from __init__.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 21:10:10 +08:00
starmen1265 a102a75b28 feat(08-01): create crawler data models and test scaffolding
- Add Pydantic models: AnswerData, ArticleData, ContentMetadata, AuthorInfo, CrawlResult
- Create test fixtures in conftest.py with mock browser and sample API responses
- Set up crawler module with __init__.py exports

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 21:06:33 +08:00
starmen1265 d9861aa6c3 feat(07-03): implement login CLI subcommand
- Add login_command function with QR code login, cookie import, and status check
- Add login subcommand with --import-cookie and --status options
- Update CLI help text with login examples
- Fix mock paths in tests to match actual import locations

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 18:10:43 +08:00
starmen1265 919a4673e6 feat(07-03): implement cookie validation functionality
- Add CookieValidationResult Pydantic model with valid, username, user_id, reason fields
- Add validate_cookie async method to ZhihuLogin class
- Validate cookie via Zhihu /api/v4/me endpoint
- Handle 200, 401, and other status codes appropriately
- Handle network errors gracefully

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 18:00:37 +08:00
starmen1265 072d83da35 feat(07-01): implement ZhihuLogin QR code login class
TDD GREEN phase - implementation passes all 8 tests:

- ZhihuLoginResult: Pydantic model for login results
- ZhihuLogin: Main class with QR code login flow
  - LOGIN_URL: https://www.zhihu.com/signin
  - CANVAS_SELECTORS: Multiple fallback selectors for QR canvas
  - _find_qrcode_canvas(): Find canvas with fallback selectors
  - _save_qrcode_image(): Save QR code to intermediate directory
  - check_login_cookie(): Detect z_c0 cookie for login state
  - get_cookies_str(): Extract cookie string from context
  - _wait_for_login(): Poll with configurable timeout (tenacity)
  - login_by_qrcode(): Main entry point for login flow

Key design decisions:
- Uses tenacity Retrying for configurable timeout
- QR code saved to intermediate_path with timestamp
- Multiple canvas selectors for robustness
- Proper browser lifecycle management

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 17:54:06 +08:00
starmen1265 00245c58cc feat(07-02): implement CookieManager class
- CookieManager saves cookies to ~/.kb_env file
- Updates existing ZHIHU_COOKIE line or appends new
- Preserves other configuration lines
- Sets file permissions to 600 for security
- Loads cookies from env file
- Clears get_settings cache after saving

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 17:50:39 +08:00
starmen1265 2360fcc99e feat(07-02): implement parse_json_cookies function
- Parse Chrome Cookie Editor JSON format
- Filter cookies by zhihu.com domain
- Handle malformed JSON with ValueError
- Handle file not found with ValueError
- Return cookie string in "name=value; name2=value2" format

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 17:48:51 +08:00
starmen1265 af3536aa92 test(07-02): add failing tests for Cookie JSON parsing
- Test parse_json_cookies for Chrome Cookie Editor format
- Test domain filtering for zhihu.com
- Test empty array handling
- Test malformed JSON error handling
- Test file not found error handling

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 17:48:23 +08:00
starmen1265 9fc52ffbdd refactor: integrate kb-deep-analyzer as kb_workflow.deep_analyzer package
- Move kb-deep-analyzer/deep_analyzer.py to kb_workflow/deep_analyzer/__init__.py
- Update analyze.py to import from kb_workflow.deep_analyzer directly
- Remove sys.path manipulation for external package
- DeepAnalyzer, SimpleAIClient, generate_frontmatter now available as:
  from kb_workflow.deep_analyzer import DeepAnalyzer, SimpleAIClient, generate_frontmatter

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 15:28:58 +08:00
starmen1265 14b3a3c4c1 fix(analyze): correct kb-deep-analyzer path calculation
- Add one more .parent to reach correct directory level
- Fixed path: /home/.../kb-skills/kb-deep-analyzer (was /home/.../kb-skills/kb_workflow/kb-deep-analyzer)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 15:14:22 +08:00
starmen1265 244dea9371 feat(kb_workflow): add archive_file to process_command return value
PR Test / lint (pull_request) Successful in 2s
- Extract archive_file from pipeline results and include in response
- Allows callers to get the final archive path instead of only content_dir
- Fixes report display issue where content directory showed working dir instead of archive location

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:53:55 +08:00
starmen1265 ee0fc74378 fix(download): return author name instead of mid in _extract_author
PR Test / lint (pull_request) Successful in 1s
- Fix download processor to return actual author name (e.g. "HOLA小测佬")
  instead of B站用户ID (mid, e.g. "406636263")
- Add 5 test cases for author extraction logic
- Resolves report display issue where UP主名称 showed numeric ID

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:50:02 +08:00
starmen1265 72d75e3454 feat(06-03): export Pipeline class from pipeline package
- Add Pipeline import from kb_workflow.pipeline.pipeline
- Add Pipeline to __all__ exports list
- Enables: from kb_workflow.pipeline import Pipeline

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 00:34:26 +08:00