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.

Datos de origen

Repositorio
grahama1970/agent-stack-public
Última actividad en el origen
24 de septiembre de 2026 a las 15:51
Idioma detectado de SKILL.md
inglés
Estrellas
0
Forks
0

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Explorador de archivos
24 archivos

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
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
Ver en GitHub