SurfSense/surfsense_backend/app/utils
DESKTOP-RTLN3BA\$punk bdacea8b6e feat(crawler): captcha solving + per-attempt billing (Phase 3d)
Wire captchatools as the StealthyFetcher-tier page_action to detect, harvest
(egressing from the crawl's own proxy IP), inject, and submit reCAPTCHA v2/v3
and hCaptcha tokens. Opt-in and off by default (zero attempts, zero cost).

Licensing split:
- Apache-2 app/utils/captcha/ holds the generic, vendor-agnostic config
  (CaptchaConfig + captcha_enabled() = flag AND key present).
- Proprietary app/proprietary/web_crawler/captcha.py holds the bypass logic
  (detect/harvest/inject) plus a process-wide solver latch that halts solving
  on unrecoverable errors (no balance / bad key).

Crawler: CrawlOutcome gains captcha_attempts/captcha_solved, surfaced via a
per-call captcha_state dict threaded crawl_url -> _crawl_with_stealthy(_sync)
and stamped onto every stealth terminal outcome. The stealth tier captures the
proxy once and reuses it for both the fetch and the solver (IP-coherence).

Billing: WebCrawlCreditService gains captcha_billing_enabled,
captcha_solves_to_micros, charge_captcha, and a generic check_balance, sharing
a single _apply_debit path. The indexer accumulates attempts (even on failed
crawls), runs a combined crawl+captcha pre-flight, and posts a per-attempt
owner charge as usage_type="web_crawl_captcha". The captcha worst-case is only
reserved when solving is actually enabled, so a solving-off deployment is never
blocked for captcha that can never run. Both chat scrape tools fold attempts
into the current turn before the success/fail branch.

Fully config-driven prices; no migration. New unit tests cover the config,
factory (detection/latch/timeout/cap), credit service, indexer wiring, and the
chat fold.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 22:58:21 -07:00
..
captcha feat(crawler): captcha solving + per-attempt billing (Phase 3d) 2026-06-29 22:58:21 -07:00
proxy feat(03b): add BYO custom proxy provider + bounded crawler rotation-retry 2026-06-29 21:03:34 -07:00
async_retry.py feat: updated agent harness 2026-04-28 09:22:19 -07:00
blocknote_to_markdown.py Merge pull request #1543 from DhruvTilva/fix/codeblock-interior-line-indentation 2026-06-29 17:45:21 -07:00
chat_comments.py fix: use delimited format for mention highlighting 2026-01-16 20:10:09 +02:00
connector_naming.py refactor(backend): rename search_space -> workspace across app bulk (Phase 2 Wave D) 2026-06-26 18:30:47 +02:00
content_utils.py fix(chat): normalize provider-safe message history 2026-06-12 02:17:37 +05:30
document_converters.py refactor(backend): rename search_space -> workspace across app bulk (Phase 2 Wave D) 2026-06-26 18:30:47 +02:00
document_versioning.py chore: ran linting 2026-04-03 13:14:40 +05:30
file_extensions.py Route uploaded images to vision LLM with document-parser fallback 2026-04-09 14:33:33 +02:00
google_credentials.py chore: ran linting 2026-03-21 13:21:19 +05:30
indexing_locks.py feat: fixed and improved search and background task management. 2026-02-09 14:03:56 -08:00
notion_utils.py Implement KB sync after Notion page updates with block ID verification 2026-02-17 20:30:12 +02:00
oauth_security.py refactor(backend): rename search_space -> workspace across app bulk (Phase 2 Wave D) 2026-06-26 18:30:47 +02:00
pat.py chore: fix linting 2026-06-25 04:31:36 +05:30
perf.py feat(observability): add SurfSense metric helpers 2026-05-21 23:02:20 +05:30
periodic_scheduler.py refactor(backend): rename search_space -> workspace across app bulk (Phase 2 Wave D) 2026-06-26 18:30:47 +02:00
proxy_config.py feat(proxy): integrate Scrapling for enhanced web scraping capabilities 2026-06-09 00:15:10 -07:00
rbac.py refactor(backend): rename search_space -> workspace across app bulk (Phase 2 Wave D) 2026-06-26 18:30:47 +02:00
refresh_tokens.py chore: fix linting 2026-06-25 04:31:22 +05:30
signed_image_urls.py feat: added image gen support 2026-02-05 16:43:48 -08:00
user_message_multimodal.py chore: linting 2026-04-28 21:37:51 -07:00
validators.py feat(03a): implement Scrapling-only web crawler and remove Firecrawl integration 2026-06-29 20:37:56 -07:00
webcrawler_utils.py style(backend): run ruff format on 10 files 2026-01-28 22:20:02 +02:00