Skip to main content

debug-fetcher

Automated URL fetch failure handling with strategy exhaustion, memory learning, and human-in-the-loop recovery. Use when fetches fail and you need intelligent retry, pattern learning, and human collaboration.

소스 정보

저장소
grahama1970/agent-stack-public
최근 소스 활동
2026년 9월 24일 15:51
감지된 SKILL.md 언어
영어
스타
0
포크
0

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
24 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
debug-fetcher
description
Automated URL fetch failure handling with strategy exhaustion, memory learning, and human-in-the-loop recovery. Use when fetches fail and you need intelligent retry, pattern learning, and human collaboration.
allowed-tools
Bash, Read, Write, Task
triggers
["debug fetch","debug fetcher","why did fetch fail","fetch failure","analyze fetch failure","retry fetch","resilient fetch","extraction failure","empty extracted text","result.text contains HTML","content extraction bug"]
metadata
{"short-description":"Failure-to-recovery automation for URL fetching"}
provides
["debug-fetcher"]
composes
["task-monitor","agentic-evals"]
disciplines
["research-retrieval","developer-tooling"]
# Debug-Fetcher Skill Automated fetch failure handling that: 1. **Queries /memory first** - applies learned strategies before trying defaults 2. **Exhausts all strategies** - direct, playwright, wayback, brave, jina, proxy, UA rotation 3. **Stores successes** - saves working strategies to /memory for future runs 4. **Collaborates with humans** - uses /interview when all automated strategies fail ## Quick Start ```bash # Fetch single URL with failure handling ./run.sh fetch https://example.com # Fetch batch with failure handling ./run.sh fetch-batch urls.txt # Check what was learned about a domain ./run.sh recall example.com # Export all learned strategies ./run.sh export-learnings ``` ## How It Works ``` URL Request │ ▼ ┌──────────────────────────┐ │ 1. Query /memory │ │ "What works for this │ │ domain?" │ └──────────────────────────┘ │ ▼ ┌──────────────────────────┐ │ 2. Try learned strategy │ │ (if exists) │ └──────────────────────────┘ │ ▼ (fail or no learned strategy) ┌──────────────────────────┐ │ 3. Exhaust strategies: │ │ - direct fetch │ │ - playwright │ │ - wayback machine │ │ - brave alternates │ │ - jina reader │ │ - proxy rotation │ │ - user-agent rotation │ └──────────────────────────┘ │ ▼ (all fail) ┌──────────────────────────┐ │ 4. Launch /interview │ │ Ask human for help: │ │ - Credentials? │ │ - Mirror URL? │ │ - Manual download? │ │ - Skip this URL? │ └──────────────────────────┘ │ ▼ ┌──────────────────────────┐ │ 5. Store to /memory │ │ - Successful strategy │ │ - Domain patterns │ │ - Human-provided info │ └──────────────────────────┘ ``` ## Memory Schema Each learned strategy stores: | Field | Description | |-------|-------------| | `domain` | Target domain (e.g., "nytimes.com") | | `path_pattern` | URL path pattern (e.g., "/article/*") | | `successful_strategy` | What worked (e.g., "playwright") | | `headers` | Custom headers that helped | | `timing_ms` | How long the fetch took | | `success_rate` | Historical success rate | | `failure_count` | How many times this domain failed | | `last_used` | Timestamp of last use | | `discovered_at` | When strategy was first learned | ## Commands | Command | Description | |---------|-------------| | `fetch <url>` | Fetch single URL with failure handling | | `fetch-batch <manifest>` | Fetch list of URLs with failure handling | | `recall <domain>` | Show learned strategies for domain | | `export-learnings` | Export all strategies to JSON | ### fetch-batch Options | Option | Default | Description | |--------|---------|-------------| | `--concurrency` | 4 | Max concurrent fetches | | `--no-memory` | false | Disable memory integration | | `--output` | - | Output JSON file | | `--json-stream` | false | Output NDJSON per URL (streaming progress) | | `--task-monitor/--no-task-monitor` | true | Enable/disable task-monitor integration | ## Task-Monitor Integration debug-fetcher integrates with the centralized task-monitor for live progress tracking: ```bash # Run batch fetch with task-monitor (enabled by default) ./run.sh fetch-batch urls.txt # View progress in task-monitor TUI cd ~/.pi/skills/task-monitor uv run python monitor.py tui --filter debug-fetcher # Or check state file directly cat /path/to/debug-fetcher/debug_fetcher_task_state.json | jq ``` State file schema: ```json { "completed": 50, "total": 100, "progress_pct": 50.0, "strategies": { "direct": {"attempts": 30, "successes": 25, "rate": 0.833}, "playwright": {"attempts": 20, "successes": 18, "rate": 0.9} }, "stats": { "success_count": 45, "failure_count": 5, "success_rate": 0.9, "learned_count": 12 }, "failures": [...], "status": "running" } ``` ## NDJSON Streaming Output For long-running batch jobs, use `--json-stream` to output one JSON object per line: ```bash ./run.sh fetch-batch urls.txt --json-stream | tee results.jsonl # Each line: # {"url": "https://...", "success": true, "winning_strategy": "playwright", "attempts": 2, "timing_ms": 1234} ``` This enables: - Real-time progress monitoring via `tail -f results.jsonl | jq` - Integration with streaming parsers - Resume from partial runs ## Environment Variables | Variable | Description | |----------|-------------| | `DEBUG_FETCHER_MEMORY_SCOPE` | Memory scope for storing strategies (default: "fetcher_strategies") | | `DEBUG_FETCHER_MAX_RETRIES` | Max retries per strategy (default: 2) | | `DEBUG_FETCHER_INTERVIEW_THRESHOLD` | Min failures before triggering interview (default: 3) | ## Integration with Fetcher Debug-fetcher wraps the standard fetcher skill and adds failure handling capabilities. All fetcher environment variables (BRAVE_API_KEY, FETCHER_EMIT_MARKDOWN, etc.) are respected. ## Examples ### Learning from Failures After fetching a batch of URLs, debug-fetcher stores successful strategies: ```bash # Fetch a batch ./run.sh fetch-batch urls.txt --output results.jsonl # View what was learned ./run.sh recall attack.mitre.org # Output: # Domain: attack.mitre.org # Strategy: playwright # Success rate: 95% # Last used: 2025-01-30 # Next time, playwright will be tried first for attack.mitre.org ./run.sh fetch https://attack.mitre.org/techniques/T1059 ``` ### Human-in-the-Loop Interview When all strategies fail, an interview is generated: ```bash # Fetch batch with failures ./run.sh fetch-batch difficult_urls.txt # Interview generated at: /tmp/interview_abc123.json # Run: ./agents/skills/interview/run.sh /tmp/interview_abc123.json # Example interview questions: # - "Failed 5 URLs from nytimes.com. Do you have credentials?" # - "archive.org not working. Try a mirror URL?" ``` ### YouTube URL Handling YouTube URLs are automatically detected and handled via the `/ingest-youtube` skill: ```bash # YouTube URLs use transcript extraction ./run.sh fetch https://www.youtube.com/watch?v=abc123 # Uses: /ingest-youtube skill for transcript extraction # Falls back to other strategies if transcript unavailable ``` ### Batch Analysis After a batch run, analyze patterns: ```python from debug_fetcher.batch_analyzer import analyze_batch, get_failure_summary # Get summary summary = get_failure_summary(results) # { # "total": 1000, # "success": 850, # "failed": 150, # "success_rate": "85.0%", # "top_failing_domains": [ # {"domain": "nytimes.com", "count": 45}, # {"domain": "wsj.com", "count": 30} # ], # "patterns": [ # "All 45 URLs from nytimes.com returned HTTP 403", # "High failure rate: 50% of failures are paywalled sites" # ] # } ``` ## Fetch Failure vs Extraction Failure **Critical distinction**: "Empty content" can mean two different things: | Symptom | Fetch Failure | Extraction Failure | |---------|---------------|-------------------| | HTTP status | Non-200 | 200 | | `downloads/` content | Empty or error page | Full HTML present | | `extracted_text/` | Empty | Empty (BUG) or HTML (BUG) | | Root cause | Network/auth/JS rendering | `evaluate_result_content()` bug | | Fix | Add to SPA_FALLBACK_DOMAINS, proxy, etc. | Fix extraction code | ### Diagnosing the Difference ```bash # Step 1: Check HTTP status jq '.items[0].status' consumer_summary.json # 200 = fetch succeeded, issue is extraction # 403/401/etc = fetch failed, try other strategies # Step 2: Check raw download head -c 500 downloads/*.html # If contains real content → extraction bug # If contains JS shell only → needs Playwright # If contains error page → fetch failed # Step 3: Check extracted text head -c 500 extracted_text/*.txt # If contains "<!DOCTYPE html>" → extraction returned HTML (BUG) # If contains clean text → working correctly # If empty → extraction failed # Step 4: Verify method used jq '.items[0].method' consumer_summary.json # "aiohttp" = direct fetch # "playwright" = JS rendering used ``` ### Real-World Example (Fixed 2026-02-04) **Bug**: `result.text` contained raw HTML instead of extracted text. **Evidence**: ``` downloads/abc.html → <!DOCTYPE html>...(full HTML) extracted_text/abc.txt → <!DOCTYPE html>...(same HTML - BUG!) ``` **Fix**: `evaluate_result_content()` now replaces `result.text` with `assessment.text` (trafilatura output). **Lesson**: Always compare `downloads/` vs `extracted_text/` - they should be different formats. ## Recovery Actions When human provides help via interview: | Action Type | Description | Example | |-------------|-------------|---------| | `credentials` | Login credentials provided | username/password for site | | `mirror` | Alternative URL to try | archive.org mirror | | `manual_file` | Human downloaded file manually | Path to local PDF | | `skip` | URL not needed | "Not critical" | | `retry` | Try again later | Server was down | | `custom_strategy` | Specific approach suggested | "Use proxy" | ## Files ``` .pi/skills/debug-fetcher/ ├── SKILL.md # This file ├── run.sh # Entry point ├── pyproject.toml # Dependencies └── debug_fetcher/ # Python package ├── __init__.py ├── cli.py # CLI commands ├── memory_schema.py # FetchStrategy dataclass ├── memory_bridge.py # Recall/learn from /memory ├── strategy_engine.py # Strategy exhaustion loop ├── batch_analyzer.py # Analyze batch failures ├── interview_generator.py # Generate /interview JSON ├── interview_processor.py # Process interview responses ├── recovery_executor.py # Execute recovery actions └── pdf_bridge.py # Cross-skill integration with debug-pdf ``` ## Companion Skill: debug-pdf `debug-fetcher` and `debug-pdf` work together in the pipeline: ``` URL → debug-fetcher → /fetcher → /extractor → debug-pdf ↓ ↓ fetch fail extraction fail ↓ ↓ retry/recover analyze PDF issues ↓ ↓ /memory /memory ``` **Shared failure patterns:** | Pattern | debug-fetcher | debug-pdf | |---------|---------------|-----------| | `auth_required` | HTTP 401/403 | N/A | | `access_restricted` | HTTP 403 | N/A | | `paywall_detected` | Soft paywall | N/A | | `password_protected` | N/A | Encrypted PDF | | `scanned_no_ocr` | N/A | No text layer | | `archive_org_wrap` | Wayback wrapper | Wayback wrapper | **Cross-skill notifications:** - When debug-fetcher successfully fetches a PDF but detects issues (password protected, scanned), it notifies debug-pdf via agent-inbox - When debug-fetcher fails to fetch a PDF URL, it notifies debug-pdf for tracking ## Related Skills - `/memory` - Stores learned fetch strategies - `/interview` - Human collaboration for unrecoverable URLs - `/ingest-youtube` - YouTube transcript extraction - `/fetcher` - Core URL fetching functionality - `/extractor` - Content extraction from fetched documents - `/debug-pdf` - Companion skill for PDF extraction failures
GitHub에서 보기