Source reference
Architecture · Workflows · Configuration
This index is generated from the released source. File links preserve the containing implementation and its local context.
HTTP routes
Configuration names
Values stay in the recipient’s private runtime file. Setup groups the load-bearing credentials by feature.
APP_BASE_URL, AWS_REGION, BASE_URL, BEDROCK_CLAUDE_HAIKU, BEDROCK_CLAUDE_SONNET, BEDROCK_REGION, BRIGHT_DATA_API_KEY, CHATWOOT_ACCOUNT_ID, CHATWOOT_API_TOKEN, CHATWOOT_INBOX_ID, CHATWOOT_URL, DATABASE_URL, DEEPGRAM_API_KEY, DEEPGRAM_MODEL, DEV, DOCUSEAL_API_KEY, DOCUSEAL_TEMPLATE_AGREEMENT, ELEVENLABS_API_KEY, GROQ_API_KEY, GROQ_WHISPER_MODEL, HABITISSIMO_EMAIL, HABITISSIMO_PASSWORD, HERMES_HOME, HERMES_VENDOR_PATH, HF_TOKEN, HF_WHISPER_MODEL, HOGAMI_API_KEY, HUGGINGFACE_HUB_TOKEN, LEO_AWS_ACCOUNT, LEO_CS_MAX_TOKENS, LEO_DISABLE_JWT_CACHE, LEO_ENV, LEO_FALLBACK_MODEL, LEO_JWT_CACHE_SIZE, LEO_JWT_CACHE_TTL, LEO_MAX_ITERATIONS, LEO_PRIMARY_MODEL, LEO_PROJECT_EMAIL_DOMAIN, LEXAPI_KEY, LITELLM_API_KEY, LITELLM_BASE_URL, LITELLM_PORT, MARKETPLACE_TOKEN, MEM0_API_KEY, META_API_VERSION, NEXT_PUBLIC_SUPABASE_ANON_KEY, NEXT_PUBLIC_SUPABASE_URL, OPENROUTER_API_KEY, OPS_MONITOR_TOKEN, OUTREACH_FOLLOWUP_1_HOURS, OUTREACH_FOLLOWUP_2_HOURS, OUTREACH_FOUNDER_PHONE, OUTREACH_MAX_DAILY, OUTREACH_STAGGER_SECONDS, OUTREACH_TARGET_PER_JOB, PETER_WHATSAPP, POLISH_API_STYLE, PROFILE_STRUCTURE_MODEL, RESEND_API_KEY, RESEND_WEBHOOK_SECRET, RESEND_WEBHOOK_TOLERANCE_SECONDS, SALES_TRACKER_TOKEN, STRIPE_PUBLISHABLE_KEY, STRIPE_SECRET_KEY, STRIPE_SECRET_KEY_TEST, STRIPE_WEBHOOK_SECRET, STRIPE_WEBHOOK_SECRET_TEST, SUPABASE_ANON_KEY, SUPABASE_SERVICE_KEY, SUPABASE_SERVICE_ROLE_KEY, SUPABASE_URL, TRANSCRIPT_POLISH_ENABLED, TRANSCRIPT_POLISH_MODEL, TWILIO_ACCOUNT_SID, TWILIO_API_KEY_SECRET, TWILIO_API_KEY_SID, TWILIO_AUTH_TOKEN, TWILIO_TWIML_APP_SID, VITE_API_URL, VITE_MAPBOX_ACCESS_TOKEN, VITE_POSTHOG_KEY, VITE_SUPABASE_ANON_KEY, VITE_SUPABASE_URL, VOICE_CONCURRENCY, VOICE_LOG_CONTENT, WHATSAPP_PHONE_NUMBER_ID, WHATSAPP_TEMPLATE_HOMEOWNER, WHATSAPP_TEMPLATE_PROFESSIONAL, WHATSAPP_TEMPLATE_RECEIVED, WHATSAPP_TOKEN, WHATSAPP_VERIFY_TOKEN, WHISPER_BEAM_SIZE, WHISPER_COMPUTE_TYPE, WHISPER_CPU_THREADS, WHISPER_DEVICE, WHISPER_MODEL
Functions
apps/scope/product/backend/agent/ephemeral_context.py
| Function |
Arguments |
Purpose |
| build_enrichment_note |
enrichment_needed |
Build the ENRICHMENT NEXT injection line for the system prompt. |
| _scope_intake_context |
audience, profile_context |
|
| _language_instructions |
page_locale, user_language_hint |
|
| build_turn_context |
mode, audience, lead_context, page_locale, user_language_hint, profile_context, channel, confirmed, lead_phone, capabilities, enrichment_needed |
Build the ephemeral_system_prompt for one agent turn. |
| Function |
Arguments |
Purpose |
| search_boe |
query, limit |
Search the BOE consolidated legislation API (free, no auth). |
| get_boe_norm_text |
norm_id |
Fetch the full text of a specific BOE norm by identifier. |
| _get_lexapi_key |
|
Load LexAPI key from env. |
| search_eu_law |
query, document_type, domain, max_results |
Search EU law via LexAPI (free tier: 50 calls/day). |
apps/scope/product/backend/agent/leo.py
| Function |
Arguments |
Purpose |
| _load_soul |
|
Read ~/.hermes/SOUL.md once and cache it. Hermes uses this as slot #1 in _build_system_prompt when skip_context_files=False, but we set skip_context_files=True to avoid injecting dev context files (AGENTS.md, .cursorrules) into customer chats. So we load SOUL.md ourselves and pass it via system_message (slot #4, cached on first turn). |
| _get_enabled_toolsets |
|
Read marketplace_config.json and merge enabled toolsets with leo-quote. |
| _get_conversation_lock |
conversation_id |
|
| evict_stale_agents |
|
Remove agents idle longer than AGENT_TTL_SECS. Returns count evicted. |
| _get_or_create_agent |
conversation_id, channel, model |
Return existing agent for this conversation, or create a new one. |
| _tool_progress |
tool_name, preview, args |
Fires before any Hermes tool call. Skipped for Leo tools that self-report. |
| _to_openai_messages |
history |
Convert frontend/WhatsApp message format directly to OpenAI format. |
| _extract_text |
openai_content |
Pull plain text from an OpenAI message content field. |
| _last_msg_has_images |
raw_msgs |
Check if the last message has images (raw format or OpenAI multipart format). |
| _pick_model |
mode |
Sales mode gets Sonnet 4.6 (founder tool, worth the cost). All other modes use the default PRIMARY_MODEL (Sonnet 4.6). |
| _resolve_capabilities |
channel, caps, page_locale, user_language_hint |
Resolve a ChannelCapabilities from either an explicit object or a channel string. |
| _legacy_msgs_to_leo_messages |
raw_msgs |
Convert legacy frontend format {role, text, images} to LeoMessage list. |
| _extract_all_tool_calls |
messages |
Extract every tool name the agent called from the full Hermes message history. |
| _extract_improvement_signals |
messages |
Scan Hermes message history for memory tool calls containing IMPROVEMENT_SIGNAL. Returns a list of signal descriptions. |
| _phone_key |
phone |
Normalise a phone to bare digits (no +, spaces, dashes). |
| whatsapp_reply |
messages, mode, raw_history, lead_context, audience, page_locale, user_language_hint, profile_context, lead_phone, conversation_id, capabilities, enrichment_needed |
WhatsApp channel wrapper: runs Hermes with WhatsApp formatting + capabilities. |
| _leo_messages_to_openai |
leo_msgs |
Convert enriched LeoMessages to OpenAI format for Hermes. After enrichment, messages should be text-only (media already converted). |
| run_leo_chat |
messages, mode, raw_history, lead_context, audience, page_locale, user_language_hint, profile_context, channel, lead_phone, source_tag, confirmed, user_id, conversation_id, capabilities, leo_messages, contractor_id, enrichment_needed |
Run one agent turn using a pooled Hermes AIAgent. |
| _run_agent |
|
Synchronous AIAgent call, runs in thread executor. |
| _run_agent_retry |
|
|
apps/scope/product/backend/agent/peter_notify.py
| Function |
Arguments |
Purpose |
| _wa_text_payload |
body, max_len |
Build a WhatsApp text payload, enabling link previews when URLs are present. |
| _get_supabase |
|
Get Supabase URL and key from the database module (single source of truth). |
| _wa_token |
|
|
| _wa_phone_id |
|
|
| notify_peter |
name, whatsapp, location, chat_summary |
Send Peter a WhatsApp message about a new signup. Fire-and-forget. |
| notify_peter_lead_submitted |
phone, name, location, job_text |
Notify Peter the instant a homeowner confirms their phone on the landing page. |
| notify_peter_discovery_complete |
job_id, trade, city, sent, deferred, candidates_found |
Notify Peter when contractor discovery finishes for a job. |
| notify_brief_confirmed |
brief, phone |
Send Peter a WhatsApp with the full brief when a homeowner confirms a job. |
| save_signup |
name, whatsapp, location, source, chat_summary, chat_history |
|
| whatsapp_handoff |
name, whatsapp, detected_lang, audience |
|
| proposal_short_id |
proposal_uuid |
First 8 hex chars of UUID (no dashes) for founder WhatsApp replies. |
| store_skill_proposal |
skill_name, action, reason, content, conversation_id, skill_payload |
Store a skill change proposal and return the row (including id). |
| get_similar_proposals |
skill_name, action |
Find existing draft/pending proposals for the same skill and action. |
| resolve_skill_proposal |
proposal_id, status |
Update a proposal's status to approved/rejected/draft. |
| notify_founder_skill_proposal |
proposal_id, skill_name, action, reason, pattern_count, content_preview |
Send Peter a WhatsApp message about a skill change proposal. |
| send_whatsapp_text |
to_digits, body |
Send a plain text WhatsApp message. Delegates to unified send_wa_message. |
| fetch_pending_skill_proposals |
limit |
|
| fetch_skill_proposal_by_id |
proposal_id |
|
| resolve_proposal_for_founder |
short_opt |
Pick the pending proposal matching ref prefix, or latest pending if short_opt is empty. |
| execute_skill_manage_from_row |
row |
Apply an approved proposal by calling Hermes skill_manage (sync). |
| parse_founder_skill_reply |
text |
Parse founder WhatsApp reply. Returns (verb, optional_ref) where verb is approve / reject / draft. Ref is 8-char hex prefix when provided. |
| try_handle_founder_skill_reply |
sender_digits, text |
If sender is founder and text is a skill decision, apply it. Returns (handled, message_to_echo) — message_to_echo is sent back to founder on WhatsApp. |
| notify_founder_improvement_signal |
signal_text, conversation_id |
WhatsApp Peter when the agent flagged IMPROVEMENT_SIGNAL (non-customer-facing). |
| request_human_escalation |
reason, conversation_summary, user_name, user_phone, channel |
Escalate a conversation to Peter. Sends him a WhatsApp alert with context and returns a wa.me link to share with the user. |
| send_email_resend |
to, subject, body_html, body_text, from_label, from_address |
Send an email via Resend API. Returns {"ok": True, "id": ...} or {"ok": False, "error": ...}. |
| patch_lead_structured |
|
|
| Function |
Arguments |
Purpose |
| register_leo_tools |
registry, create_custom_toolset |
Register the leo-quote tool handlers + toolset. |
| Function |
Arguments |
Purpose |
| _handle_lookup_price |
args |
Look up renovation/construction prices from Habitissimo + CronoShare databases. |
| _handle_estimate_cost |
args |
Multi-layer cost estimator: curated recipes → construction cost DB → market data. |
| _handle_lookup_product |
args |
Search 199K Spanish construction products by name, brand, or model. |
| register |
registry |
|
apps/scope/product/backend/config.py
apps/scope/product/backend/constants.py
| Function |
Arguments |
Purpose |
| peter_whatsapp |
|
Return PETER_WHATSAPP env var or the UK default. |
apps/scope/product/backend/documents/agreements.py
| Function |
Arguments |
Purpose |
| template_name |
self |
|
| render_html |
self |
Render the agreement HTML. Memoised for the instance lifetime. |
| render_pdf |
self |
Render the agreement PDF. Not memoised — callers rarely render the same PDF twice, and a 200-800 KB byte cache on every doc instance is noise. |
| content_hash |
self |
sha256 hex digest of render_html() bytes. Memoised. |
| filename |
self |
Canonical download filename: leo-agreement-<12-char-token>.<ext>. |
| send_agreement_for_signature |
payload |
End-to-end: render agreement PDF, submit to docuSeal. |
apps/scope/product/backend/documents/consent.py
apps/scope/product/backend/documents/contexts.py
apps/scope/product/backend/documents/dates.py
| Function |
Arguments |
Purpose |
| format_date_es |
d |
Spanish long-form date. date(2026, 4, 18) → "18 de abril de 2026". |
| format_date |
d |
Generic locale-aware long date formatting. Babel wrapper. |
apps/scope/product/backend/documents/docuseal/client.py
apps/scope/product/backend/documents/docuseal/webhook.py
apps/scope/product/backend/documents/invoices.py
apps/scope/product/backend/documents/payloads.py
| Function |
Arguments |
Purpose |
| from_cents |
cls, cents |
Alternate constructor: Money.from_cents(1234). |
| from_euros |
cls, euros |
Alternate constructor: Money.from_euros("12.34"). |
| euros |
self |
EUR value as Decimal at 2 dp. Wraps :func:domain.money.from_cents. |
| str |
self |
Human-readable ES-convention string, e.g. "1.234,56 €". |
| add |
self, other |
|
| sub |
self, other |
|
| mul |
self, other |
|
| rmul |
self, other |
|
apps/scope/product/backend/documents/render.py
apps/scope/product/backend/documents/storage.py
| Function |
Arguments |
Purpose |
| init |
self |
|
| _supabase |
self |
|
| _client |
self |
|
| _key |
self, doc |
|
| put |
self, doc |
Upload document bytes to S3 + insert documents row. |
| get_by_id |
self, id |
|
| find |
self |
Most recent StoredDocument for the (kind, quote_token) pair. |
| get_url |
self, stored |
Presigned GET URL. Accepts :class:StoredDocument or raw S3 key. |
| delete |
self, stored |
|
| get_storage |
|
Process-wide factory. Bucket name derived from LEO_ENV. |
apps/scope/product/backend/documents/variations.py
apps/scope/product/backend/main.py
apps/scope/product/backend/pricing/config.py
apps/scope/product/backend/pricing/cype_index.py
apps/scope/product/backend/pricing/estimate.py
apps/scope/product/backend/pricing/historical.py
apps/scope/product/backend/pricing/ine_categories.py
apps/scope/product/backend/pricing/ine_drift.py
apps/scope/product/backend/pricing/markup.py
apps/scope/product/backend/pricing/materials.py
| Function |
Arguments |
Purpose |
| lookup_live_price |
sku |
STUB — raises NotImplementedError until scraping lands vendor-aware helpers. |
apps/scope/product/backend/pricing/modifiers.py
apps/scope/product/backend/pricing/overhead.py
apps/scope/product/backend/pricing/price_lookup.py
| Function |
Arguments |
Purpose |
| _get_index |
|
Lazily open the prices DB as a :class:fulltext.DomainIndex. |
| close_connection |
|
Drop the cached DomainIndex. Safe to call when no index is open. |
| _format_city_row |
row |
Format a city_prices row as LLM text. |
| _format_fts_result |
result, city_norm |
|
| _dedupe_city_rows |
city_rows, limit |
Drop rows that share a price fingerprint (Habitissimo's recycled content). |
| _extract_structured |
city_rows, fts_results, city |
Pull structured fields out of the same rows the text formatter uses. |
| lookup_market |
query |
Search Habitissimo + CronoShare for market-price data. |
apps/scope/product/backend/pricing/product_lookup.py
apps/scope/product/backend/pricing/quote.py
| Function |
Arguments |
Purpose |
| _normalise_iva |
iva_rate, iva_percent |
Return (fraction, integer_percent) after validation. |
| _line_amount_eur |
item |
Extract the numeric amount field from a line_items[] entry. |
| compute_line |
description, amount_eur |
Build a :class:Line from raw values. |
| compute_quote |
draft |
Compute quote financials deterministically from a :class:QuoteDraft. |
| breakdown_from_quote_row |
row |
Decode a stored quotes row into a typed :class:QuoteBreakdown. |
apps/scope/product/backend/pricing/recipes.py
| Function |
Arguments |
Purpose |
| _clear_cache |
|
Drop the in-memory recipe cache. Called from :func:pricing.configure. |
| load_recipes |
|
Return the in-memory recipe list, loading once. |
| _normalise |
text |
|
| recipe_score |
recipe, query_normalized |
Per-recipe relevance score against a normalised query. |
| find_recipe |
query, threshold |
Best-match recipe for a free-text query. |
apps/scope/product/backend/pricing/types.py
| Function |
Arguments |
Purpose |
| to_dict |
self |
|
| to_quote_row |
self |
Shape ready for Supabase quotes row INSERT/PATCH. |
| format_total_eur |
self |
Spanish-locale total with the euro sign — core.money.format_eur. |
| from_dict |
cls, data |
Factory that copes with optional / extra fields in the JSON. |
| to_dict |
self |
|
| to_dict |
self |
JSON-safe dict for the hermes tool envelope. |
| as_llm_text |
self |
Formatted string — the LLM-context shape today's search_prices returns. |
| as_llm_text |
self |
|
apps/scope/product/backend/project_access.py
| Function |
Arguments |
Purpose |
| is_project_homeowner |
caller, quote |
Match a verified auth subject, or a nonempty verified legacy email. |
| project_party |
caller, quote |
Resolve the sender from verified identity and this quote's participants. |
apps/scope/product/backend/records/conversations.py
| Function |
Arguments |
Purpose |
| add_message |
user_id, role, text |
Append a message row to whatsapp_messages or web_messages. |
| get_messages |
user_id |
Fetch messages for a user, newest-first, paginated. |
| get_recent_window |
user_id |
Messages from the last hours, capped at cap rows. |
| summarize_recent |
user_id |
Recency-weighted summary of a user's conversation. |
| _summarize_older |
older |
Group into 15-min buckets and summarize each via :func:llm.chat. |
| _row_to_message |
row |
Adapt legacy + target schemas into the unified :class:Message. |
| _parse_ts |
raw |
|
| _ensure_aware |
ts |
Supabase timestamps are UTC; guard against naive by coercing. |
apps/scope/product/backend/records/dossier.py
| Function |
Arguments |
Purpose |
| _upsert |
row |
|
| _patch |
contractor_id, updates |
|
| _select |
column, value |
|
| get_or_create_contractor |
contractor_id |
Idempotent. If a row with this id exists, patch missing fields. Otherwise upsert a new row. |
| get_contractor_by_phone |
phone |
Index-hit lookup by unique phone column. Returns None if not found. |
| get_contractor_by_token |
canvas_token |
Index-hit lookup by canvas_token. |
| set_contractor_phone |
contractor_id, phone |
Set or update the phone column on a contractor row. |
| add_contractor_source |
contractor_id, source_data |
Append a scraped profile to dossier.sources[], deduplicating by (platform, source_url). |
| update_trust_signals |
contractor_id, signals |
Write verification results to dossier.trust_signals. |
| add_conversation_note |
contractor_id, note |
Append {text, timestamp} to dossier.conversation_notes. |
| update_identity_overrides |
contractor_id, overrides |
Store conversation corrections (business_name, trade, NIF given verbally). |
| recompute_canvas |
dossier |
Pure function: dossier in, canvas dict out. |
| _best_source |
|
|
| _field |
key, override_key |
|
| save_and_recompute |
contractor_id |
Read dossier, compute canvas, write canvas back, return canvas. |
| _row_to_contractor |
row |
|
| _parse_ts |
raw |
|
apps/scope/product/backend/records/leads.py
apps/scope/product/backend/records/proposals.py
apps/scope/product/backend/routes/admin.py
| Function |
Arguments |
Purpose |
| create_api_key |
body |
Generate a new API key and store it. Returns the key (only shown once). |
| list_api_keys |
|
List all active API keys (keys are masked). |
| deactivate_api_key |
key_id |
Deactivate an API key by ID (soft delete). |
| get_customer_360 |
phone |
Aggregate all available data for a customer identified by phone number. |
apps/scope/product/backend/routes/canvas.py
apps/scope/product/backend/routes/chat.py
| Function |
Arguments |
Purpose |
| chat |
request |
Body: { "messages": [{"role":"user","text":"...","images":[{"data":"b64","media_type":"image/jpeg"}]}, ...], "mode": "early_access" / "general" / "scope_intake" / "sales" (optional), "audience": "homeowner" / "agent" / "professional" (optional, default homeowner), "lead_context": "..." (optional; location/flow hints), "profile_context": "..." (optional; |
| _build_leo_messages |
raw_msgs |
Convert raw frontend messages to LeoMessages with media attachments. |
| _lang_fallback |
msgs |
|
apps/scope/product/backend/routes/chatwoot.py
| Function |
Arguments |
Purpose |
| _cw |
method, path |
Make a Chatwoot API call. Returns parsed JSON or None on error. |
| get_or_create_contact |
phone, name |
Find or create a Chatwoot contact by phone number. Returns the Chatwoot contact ID. Normalises the phone to E.164 format (+34...) for consistency. |
| get_or_create_conversation |
contact_id |
Find the most recent open conversation for this contact in our inbox, or create a new one. Returns the Chatwoot conversation ID. |
| push_message_to_chatwoot |
phone, name, text, message_type |
Push a message to the Chatwoot conversation for this phone number. |
| chatwoot_outbound_webhook |
request |
Chatwoot fires this when any message is created on the WhatsApp inbox. We only care about 'outgoing' messages (agent replies) that aren't private notes. Those get forwarded to the customer via Meta WhatsApp Cloud API. |
| _forward_to_whatsapp |
phone_digits, content, conv_id |
Forward a Chatwoot agent reply to WhatsApp via Meta Cloud API. |
apps/scope/product/backend/routes/dispute.py
| Function |
Arguments |
Purpose |
| _get_quote |
token |
|
| _get_contractor |
contractor_id |
|
| open_dispute |
req, ctx |
Open a dispute on a milestone. Creates a Chatwoot conversation with full context. |
| _store_dispute |
quote_token, milestone_index, conversation_id, reason, homeowner_phone, is_sandbox |
Store dispute record in Supabase for tracking. |
| reply_to_dispute |
req, ctx |
Send a message in a dispute conversation. |
| get_disputes |
quote_token |
Get all disputes for a quote. |
apps/scope/product/backend/routes/documents.py
apps/scope/product/backend/routes/events.py
| Function |
Arguments |
Purpose |
| track_event |
req |
Ingest an activity event from the frontend. |
| Function |
Arguments |
Purpose |
| extract_doc |
file |
Extract text from PDF/DOCX as Markdown (tables preserved). |
apps/scope/product/backend/routes/job_inbox.py
| Function |
Arguments |
Purpose |
| _generate_inbox_token |
|
|
| create_job |
brief, homeowner_phone, homeowner_user_id, brief_photos |
Create a new job and return the row including inbox_token. |
| get_job_by_token |
token |
|
| get_job_by_id |
job_id |
|
| update_job |
job_id, updates |
|
| get_active_job_for_phone |
homeowner_phone |
Return the most recent active job for a homeowner phone number. |
| add_response |
job_id, data |
|
| update_response |
response_id, updates |
|
| get_responses_for_job |
job_id |
|
| find_response_by_phone |
job_id, phone |
Find an existing response for a contractor phone on a job. |
| find_job_for_contractor_phone |
phone |
Find the most recent active job that has an outreach to this contractor. |
| rank_responses |
job_id |
AI-rank all responses for a job against the brief. Returns updated responses. |
| api_create_job |
req |
|
| api_get_inbox |
token |
|
| api_add_response |
job_id, req |
|
| api_update_response |
job_id, response_id, updates |
|
| api_rank_responses |
job_id |
|
| api_update_job |
job_id, updates |
|
| _get_ops_token |
|
|
| api_approve_outreach |
token |
Homeowner approves a contractor's outreach — marks the job as 'contractor_selected' and updates the job status so the contractor knows they were chosen. Called from the homeowner inbox when they tap "Approve" on a response. |
| api_ops_dashboard |
token |
Founder-only ops view: all jobs, all outreach, all responses. |
apps/scope/product/backend/routes/landing_leads.py
| Function |
Arguments |
Purpose |
| _supabase_insert |
table, data |
Insert a row via Supabase REST API. |
| _normalize_phone_e164 |
phone, require_spanish |
Parse and normalise a phone number to E.164. |
| _supabase_get_landing_lead |
lead_id |
|
| _insert_cs_lead_onboarding |
|
|
| _supabase_update |
table, row_id, data |
Update a row via Supabase REST API. |
| _transcribe_audio |
audio_bytes, content_type |
Transcribe audio via packages/voice. |
| _polish_and_update |
lead_id, raw_text |
Background: polish transcript with LLM and update the DB row. |
| submit_lead |
background_tasks, job_text, audio, transcript_polished |
|
| add_phone |
request, lead_id, phone, audience, display_name, locale, location, job_description, chat_summary_extra, user_id |
|
| upload_photos |
lead_id, photos |
Upload one or more photos for a lead. Saves locally, stores URLs in Supabase. |
| update_lead |
lead_id, location, chat_history, job_description |
Update a lead with location, chat history, or refined job description. |
| check_whatsapp |
request |
Check whether a phone number is registered on WhatsApp. |
apps/scope/product/backend/routes/marketplace.py
apps/scope/product/backend/routes/messages.py
| Function |
Arguments |
Purpose |
| send_message |
req, ctx, caller |
Insert a message to job_messages. Supabase Realtime handles delivery. |
| get_messages |
quote_token, limit, caller |
Return this authenticated project party’s message history. |
| Function |
Arguments |
Purpose |
| _markdown_to_whatsapp |
text |
Convert common markdown to WhatsApp-native formatting. |
| _split_wa_reply |
text, max_chars |
Split a long reply into natural WhatsApp-sized messages. |
| _get_phone_lock |
phone |
|
| retry_orphaned_messages |
|
Called on server startup. Finds user messages that never got a reply (server died mid-processing) and replays them. Returns count of retried conversations. |
| _debounce_reply |
phone, contact_name, msg |
Buffer an inbound message. After DEBOUNCE_WINDOW_SECS of quiet from this phone, fire one _auto_reply_wa with all accumulated messages merged. Typing indicator fires immediately on the first message so the user sees feedback during the debounce wait. |
| _delayed_typing |
|
|
| _fire |
|
|
| _get_token |
|
|
| _get_phone_id |
|
|
| _download_meta_media |
media_id |
Download a media file from Meta Cloud API, save it to MEDIA_DIR, and return {"url": public_url, "mime": mime_type, "filename": fname}. Returns None on any failure. |
| _store_message |
phone_number, role, text, message_type, media_urls, media_types, wa_message_id, reply_to_wa_id, reply_to_text |
Insert a message into whatsapp_messages via Supabase REST. Delegates to the unified send_wa.store_message() function. |
| _onboarding_body_text |
audience, display_name, locale, location_suffix |
Short confirmation copy for the first WhatsApp message after phone capture. Goal: get the user to reply (opens 24-hour free messaging window). Rich follow-up details are sent by Hermes when the user replies. |
| send_onboarding_wa_message |
phone, audience, display_name, locale, location_suffix |
First WhatsApp after user submits phone on the landing flow. Delegates to unified send_wa_message() for template/text routing. Stores outbound in whatsapp_messages and upserts whatsapp_user_profiles. |
| _lookup_lead |
phone |
Look up a user in cs_leads by their WhatsApp number. |
| _extract_contractor_voice_response |
phone, transcript, voice_url |
If this phone belongs to a contractor with an active job outreach, extract reaction/needs/availability from the transcript via LLM and update the response. |
| _transcribe_local_file |
fpath |
Transcribe an audio file — delegates to the unified enrich module. |
| _send_typing_indicator |
wa_msg_id |
Show 'typing...' in the user's WhatsApp chat for up to 25 seconds. |
| _auto_reply_wa |
phone, contact_name, user_text, msg_type, media_urls, media_types, wa_msg_id |
Fetch full conversation history, call the CS agent, and send the reply back via WhatsApp. Runs as a background task so the webhook responds quickly to Meta. |
| meta_whatsapp_verify |
request |
Meta sends a GET with hub.mode, hub.verify_token, hub.challenge. We echo back hub.challenge if the token matches. |
| meta_whatsapp_webhook |
request |
Receive inbound WhatsApp messages from Meta Cloud API. Store in Supabase. No AI processing — pure proxy. |
| list_conversations |
|
List distinct phone numbers with their most recent message + display name. |
| get_messages |
phone, limit, after |
Get messages for a specific phone number, ordered by time. Pass after (ISO timestamp) for polling new messages. |
| send_message |
request |
Send a WhatsApp message from the Leo Copilot app. |
| send_template |
request |
Send a WhatsApp template message to initiate a conversation. |
| serve_media |
filename |
Serve a media file that was downloaded from Meta. |
| upload_voice |
to, audio |
Upload a voice note from the Leo Copilot app, save to disk, convert to OGG Opus (WhatsApp requirement), send via Meta Cloud API, and store in Supabase. |
| upload_media |
to, media, caption |
Upload any media from the Leo Copilot app, save to disk, send via Meta Cloud API, and store in Supabase. |
apps/scope/product/backend/routes/milestone.py
| Function |
Arguments |
Purpose |
| _get_quote |
quote_token |
|
| _get_contractor |
contractor_id |
|
| _patch_quote |
quote_token, data |
|
| _insert_notification |
user_id, quote_token, notif_type, milestone_index |
Insert a notification row (in-app bell). Table uses scope_token column. |
| _send_whatsapp |
phone, message, suppress |
Send WhatsApp message via the unified send_wa stack. |
| send_notification |
user_id, quote_token, notif_type, milestone_index, phone, whatsapp_message, suppress_wa |
Insert in-app notification and optionally send WhatsApp. |
| _app_base_url |
|
|
| _tracking_url |
quote_token, homeowner_email |
Build tracking page URL with optional email pre-fill for faster homeowner login. |
| submit_proof |
req, ctx |
Contractor submits proof photos + note for a milestone. |
| release_milestone |
req, ctx |
Homeowner approves a milestone and releases funds from escrow. |
| create_variation |
req, ctx |
Contractor proposes a change order / variation. |
| approve_variation |
req, ctx |
Homeowner approves a variation — creates new Stripe Checkout for the extra amount. |
| decline_variation |
req, ctx |
Homeowner declines a variation. |
| cancel_job |
req, ctx |
Cancel a job and issue full refund via Stripe. |
| create_review |
req |
Homeowner submits review after job completion. |
| get_notifications |
user_id, limit |
Returns notifications for a user, newest first. |
| mark_notifications_read |
req |
Mark notification IDs as read. |
| get_milestone_updates |
quote_token |
Return all milestone proof submissions for a scope. |
| get_variation_orders |
quote_token |
Return all variation orders for a scope. |
apps/scope/product/backend/routes/milestones.py
| Function |
Arguments |
Purpose |
| submit_proof |
token, idx, body, caller, ctx |
Contractor submits proof photos + note for a milestone. |
| release_milestone |
token, idx, caller, ctx |
Homeowner approves a milestone and releases funds from escrow. |
apps/scope/product/backend/routes/notifications.py
| Function |
Arguments |
Purpose |
| _insert_notification |
user_id, quote_token, notif_type, milestone_index |
Insert a notification row (in-app bell). Table uses scope_token column. |
| send_whatsapp |
phone, message, suppress |
Send a WhatsApp message via the unified send_wa stack. |
| send_notification |
user_id, quote_token, notif_type, milestone_index, phone, whatsapp_message, suppress_wa |
Insert in-app notification and optionally deliver via WhatsApp. |
| get_notifications |
caller, limit |
Return notifications for the authenticated user, newest first. |
| mark_notifications_read |
req, caller |
Mark notification IDs as read. Caller must be authenticated. |
apps/scope/product/backend/routes/pages.py
apps/scope/product/backend/routes/payment.py
| Function |
Arguments |
Purpose |
| api_create_checkout |
req, ctx |
Create a Stripe Checkout Session for a scope payment. |
apps/scope/product/backend/routes/profile_import.py
| Function |
Arguments |
Purpose |
| _get_playwright_browser |
|
Lazy-init a persistent Playwright Chromium browser for SPA scraping. |
| _render_spa |
url, wait_seconds, accept_cookies |
Render a SPA page with Playwright headless. Returns (page_text, list_of_img_dicts). Each img dict has keys: src, alt, cls. |
| detect_platform |
url |
|
| _discover_platform_links |
profile |
Scan page_chunks + raw_about + website field for links to known directory platforms. |
| _merge_profile_data |
target, source |
Merge fields from source into target without losing existing data. |
| cross_pollinate |
profile |
Discover links to other platforms in the profile data and scrape+merge them. |
| _searxng_search |
query, max_results |
Run a SearXNG JSON search and return result dicts (title, url, content). |
| enrich_credentials_from_web |
profile |
Search the web for company registration, licenses, and certifications via SearXNG. |
| _extract_legal_identity |
website_url |
Fetch legal / privacy pages from a Spanish business website and extract NIF, razón social, etc. |
| _company_name_is_specific |
name |
Check if a company name is specific enough to do a meaningful web credential search. |
| _is_noise_image |
src |
True if src looks like UI chrome rather than profile/portfolio content. |
| _image_fingerprint |
url |
Extract a stable fingerprint for dedup — strips resize params and CDN prefixes. |
| _deduplicate_portfolio |
profile |
Remove noise images and fingerprint-based duplicates in-place. |
| _is_noise_image_website_portfolio |
src |
Like _is_noise_image but keeps many CMS upload URLs that contain substrings like logo in filenames. |
| _best_url_from_srcset |
srcset |
Pick the largest candidate URL from an HTML srcset (url 400w …). |
| _img_in_excluded_portfolio_region |
img |
True if this img node sits in aside/footer/nav or (optionally) a related-posts widget. |
| _add_img_urls_from_node |
img, base_domain, seen, out |
|
| add |
u |
|
| _collect_image_urls_from_page |
page, base_domain |
Collect img URLs including lazy-load and srcset (best resolution). |
| collect_with |
related_widgets |
|
| collect_noise_url_only |
|
No DOM scoping — only _is_noise_image_website_portfolio filters URLs. |
| _playwright_collect_project_detail_images |
page, url_allow |
Images for a single project detail URL using heading/section cutoffs + fallbacks. |
| _meta_content |
page |
|
| _extract_jsonld_business_fields |
page |
Pull name / phone / description / logo from JSON-LD Organization/LocalBusiness blocks. |
| _should_skip_internal_path |
path |
|
| _internal_path_priority |
path |
Higher = crawl first (portfolio / about / services). |
| _canonical_internal_url |
parsed |
Same page identity: scheme + host + path + query, no fragment. |
| _discover_internal_urls |
seed_url, page, base_parsed |
Collect same-host links, filter junk, sort by relevance. |
| _hostname |
url |
|
| _is_noise_external_link |
href |
|
| extract_business_website_from_habitissimo |
page, body_text |
Find the pro's own website from the Habitissimo profile DOM + text. |
| _parse_habitissimo_reviews_from_text |
rev_text |
Parse reviews from the rendered text of a Habitissimo profile page. |
| _discover_opinion_urls |
base, first_page |
Follow pagination / opinion links on the first opinions page. |
| scrape_habitissimo_reviews |
base_url, first_opiniones_page |
Aggregate reviews from first page + linked opinion/pagination pages. |
| add_batch |
revs |
|
| _parse_habitissimo_project_page |
page_url |
|
| scrape_habitissimo_projects |
base_url, proj_page |
Collect project cards + per-project detail pages when links exist. |
| merge_website_into_profile |
profile, website_url, max_pages |
Crawl a business website and merge images + text into an existing profile. Used after Habitissimo/Houzz when a public website URL is known. |
| _habi_render_page |
ctx, url, wait_seconds, keep_open |
Render one Habitissimo page in an existing browser context. |
| _habi_load_env_credentials |
|
|
| _habi_refresh_session_if_needed |
ctx |
Ensure module-level _habi_session has a valid JWT. |
| _habi_inject_cookies |
ctx, token, awsalb |
|
| _habi_extract_phone_from_modal |
html |
Parse real phone number from /do_ajax/business_modal_contact response HTML. |
| _habi_reveal_phone |
page_or_slug, base_url_or_none |
Reveal the real phone number via Habitissimo's AJAX endpoint. |
| _habi_reveal_phone_httpx |
slug, token, awsalb, session_rh |
Fire the Habitissimo AJAX contact endpoint via httpx to get the real phone. |
| scrape_habitissimo |
url, merge_external_site |
|
| _parse_habi_main_page |
profile, text, imgs_raw |
Extract name, trade, location, rating, review count, description, Q&A from main page. |
| _parse_habi_fotos |
profile, imgs_raw |
Extract gallery images from the /fotos page. |
| _parse_habi_proyectos |
profile, text, imgs_raw |
Extract project titles and images from the /proyectos page. |
| _habi_enrich_projects |
ctx, profile, base_url |
Use the already-open Playwright context to fetch each Habi project detail page for its images. |
| _habi_allow |
u |
|
| _parse_habi_opiniones |
profile, text |
Parse reviews from the rendered /opiniones page text. |
| _extract_houzz_about_from_body |
body_text |
Extract the 'Sobre nosotros' / 'About Us' blurb from Houzz profile body text. |
| _houzz_fetch_about_playwright |
profile_url |
Render the Houzz profile in a browser, open the About tab if needed, read full about text. |
| _best_description_from_homepage |
page |
Pick the longest useful homepage description (meta, og:, JSON-LD). |
| _houzz_enrich_projects |
profile, max_projects |
Use Playwright to discover project links from the profile page and scrape their images. |
| _houzz_allow |
u |
|
| _houzz_fetch_page |
url |
Fetch a Houzz page via curl_cffi (TLS impersonation) — scrapling's Fetcher gets 404'd. |
| scrape_houzz |
url |
|
| scrape_cronoshare |
url |
Scrape a CronoShare professional profile (cronoshare.com/croner-*). |
| _parse_cronoshare_reviews |
profile, text, page |
Parse client reviews from a CronoShare profile page. |
| _hogami_slug_from_url |
url |
|
| scrape_hogami |
url |
|
| _extract_emails_from_page |
page |
Pull email addresses from mailto: links and visible text. |
| scrape_website |
url |
Crawl the entry URL plus prioritized same-site pages; store per-page chunks for LLM structuring. |
| _add_images |
urls |
|
| _get_bedrock |
|
|
| _text_from_converse |
response |
|
| _openrouter_chat |
system, user, max_tokens, temperature |
Fallback LLM call via the llm package when Bedrock fails. |
| _converse_with_fallback |
system, user |
Try Bedrock Converse, fall back to OpenRouter on any failure. |
| structure_profile_with_llm |
profile |
Structure the raw crawl with LLM. Tries Bedrock first, falls back to OpenRouter. |
| summarize_reviews_with_llm |
profile |
Fill review_summary from profile.reviews via Bedrock (objective overview). |
| _run_social_proof_background_by_id |
contractor_id, phone |
Run social proof when we have a contractor ID + phone but no ProfileResult in memory. |
| _run_social_proof_background |
result, contractor_id |
Run the slow social proof search after canvas delivery. |
| _stream_scrape |
url, contractor_id |
Generator that yields SSE events during scraping. |
| _strip_cc |
p |
|
| profile_import |
req |
Scrape a tradesperson profile. Returns SSE stream with progress + result. |
| profile_import_sync |
req |
Synchronous version — scrapes and returns profile JSON directly. |
apps/scope/product/backend/routes/projects.py
| Function |
Arguments |
Purpose |
| get_quote |
quote_token |
Fetch a quote row by token. Raises 404 if not found. |
| get_contractor |
contractor_id |
Fetch a contractor row by id. Raises 404 if not found. |
| patch_quote |
quote_token, data |
|
| app_base_url |
|
|
| tracking_url |
quote_token, homeowner_email |
Build the homeowner-facing project tracking URL with optional email pre-fill. |
| get_project |
token, caller |
Return project data. Public read — auth resolves role-specific visibility. |
| cancel_project |
token, req, caller, ctx |
Cancel a project and issue a full Stripe refund. |
apps/scope/product/backend/routes/resend_inbound.py
| Function |
Arguments |
Purpose |
| _b64decode_secret |
secret |
|
| _parse_svix_signatures |
signature_header |
Extract all v1 signatures from the svix-signature header. Format: "v1,BASE64SIG" or "v1,BASE64SIG v1,BASE64SIG2" |
| _verify_resend_webhook |
|
|
| _extract_email_address |
from_field |
|
| _clean_reply_text |
body |
Strip common email reply cruft (quoted text, signatures) to get the actual reply. |
| _format_wa_notification |
from_addr, subject, body |
Format an inbound email as a WhatsApp notification to the founder. |
| _send_wa_notification |
phone, text |
Send a WhatsApp text message via unified send_wa_message. |
| _store_inbound_email |
from_addr, to_addrs, subject, body, raw_payload |
Store the inbound email in Supabase for audit trail. |
| resend_inbound_webhook |
request |
Resend inbound MX webhook. |
| _auto_reply_email |
from_addr, from_field, subject, body |
Process inbound email through Leo agent and send a reply email back. |
apps/scope/product/backend/routes/reviews.py
| Function |
Arguments |
Purpose |
| create_review |
token, req, caller |
Homeowner submits a review after job completion. |
apps/scope/product/backend/routes/search_instagram.py
| Function |
Arguments |
Purpose |
| _save_instagram_csv |
trade, city, profiles |
Save Instagram profiles to CSV in the same reports/ dir the sales tracker reads. |
| search_instagram_profiles |
trade, city, save_csv |
Search Instagram for tradespeople profiles matching trade + city. Extract phone numbers from bios and linked websites. |
| search_instagram_batch |
trades, cities |
Batch search Instagram for multiple trade + city combinations. Runs them concurrently (up to 3 in parallel). |
| _one |
trade, city |
|
apps/scope/product/backend/routes/stripe_connect.py
apps/scope/product/backend/routes/transcribe.py
| Function |
Arguments |
Purpose |
| transcribe_audio |
audio, polish, provider, language |
|
| polish_text |
text |
Polish raw Whisper text with Bedrock LLM. No re-transcription. |
apps/scope/product/backend/routes/transcribe_stream.py
apps/scope/product/backend/routes/variations.py
| Function |
Arguments |
Purpose |
| create_variation |
token, body, caller, ctx |
Contractor proposes a change order / variation. |
| approve_variation |
token, variation_id, caller, ctx |
Homeowner approves a variation — creates a new Stripe Checkout for the extra amount. |
| decline_variation |
token, variation_id, caller, ctx |
Homeowner declines a variation. |
apps/scope/product/backend/scrapers/directories.py
| Function |
Arguments |
Purpose |
| phone_normalized |
self |
9-digit dedup key from :func:domain.phone.normalize, or "". |
| is_valid_phone |
self |
True if phone parses as a valid Spanish mobile. |
| _dispatch |
platform, trade, city, limit |
Lazy-import and invoke a single platform's search. |
| _dedup |
leads |
Deduplicate by normalised phone. Leads with unparseable phones are dropped (audit §1.3 I1: invalid phones can't dedup reliably). |
| search |
trade, city |
Search for contractors across one or more platforms. |
apps/scope/product/backend/scrapers/facebook/expand.py
| Function |
Arguments |
Purpose |
| expand_comments |
page, max_clicks |
Click every matching "more comments" button up to max_clicks rounds. |
apps/scope/product/backend/scrapers/facebook/groups.py
| Function |
Arguments |
Purpose |
| capture_graphql |
page |
Capture FB GraphQL responses matching op_name over timeout_ms milliseconds. |
apps/scope/product/backend/scrapers/habitissimo/blast.py
| Function |
Arguments |
Purpose |
| submit_rfq |
trade, city |
Submit one RFQ to Habitissimo's /v1/serviceRequest endpoint. |
| build_submissions |
trades, cities, templates |
Cartesian product of trades × cities × templates. |
apps/scope/product/backend/scrapers/habitissimo/phones.py
| Function |
Arguments |
Purpose |
| extract_phone_from_modal_html |
html |
Parse a phone number out of Habitissimo's reveal-modal HTML. |
| _clean |
raw |
Strip whitespace / dashes / parens from a raw phone string. |
| _is_proxy |
phone |
True if phone starts with :data:HABITISSIMO_PROXY_PREFIX after stripping a leading +34 if present. |
| reveal_phone |
slug |
Reveal the phone for a Habitissimo company by slug. |
apps/scope/product/backend/scrapers/habitissimo/search.py
| Function |
Arguments |
Purpose |
| list_companies |
trade, city |
List companies on Habitissimo's directory for trade × city. |
| search |
trade, city |
Search Habitissimo directory and optionally reveal phones. |
apps/scope/product/backend/scrapers/habitissimo/session.py
| Function |
Arguments |
Purpose |
| refresh_session |
|
Log in via Playwright and write HABITISSIMO_SESSION_FILE. |
| get_session |
|
Return the cached session, refreshing if expired. |
apps/scope/product/backend/scrapers/houzz/search.py
| Function |
Arguments |
Purpose |
| build_query |
trade, city |
Construct a Houzz directory search URL. |
| search |
trade, city |
Houzz contractor directory search. |
apps/scope/product/backend/scrapers/instagram/profile.py
apps/scope/product/backend/scrapers/instagram/scraper.py
| Function |
Arguments |
Purpose |
| search |
trade, city |
IG contractor search (Google SERP → profile parse → leads). |
apps/scope/product/backend/scrapers/instagram/search.py
| Function |
Arguments |
Purpose |
| google_search |
query |
Execute a Google SERP query and return list of IG-profile hits. |
apps/scope/product/backend/scrapers/instagram_scraper.py
| Function |
Arguments |
Purpose |
| instagram_handle_from_bio |
bio |
Best-effort Instagram @handle from a Google snippet / Wallapop line / bio string. Used to backfill profile_url for PHONE-only scraper rows. |
| _load_bd_key |
|
|
| _google_instagram_search |
query, start, bd_key, num |
One paginated Google search for tradespeople with Instagram presence. |
| _fetch_instagram_profile |
username, bd_key |
Fetch an Instagram profile page and extract bio + phone. Returns dict. |
| _extract_bio_from_html |
html |
Extract bio text from Instagram page HTML. Tries meta description first. |
| _extract_display_name |
html |
|
| _extract_website |
html |
|
| _extract_phone |
text |
Extract first Spanish mobile phone number from text. |
| _normalise_phone |
raw |
Normalise to +34XXXXXXXXX format. |
| _try_fetch_website_phone |
url, bd_key |
Fetch a linked website (linktree, etc.) and look for a phone number. |
| scrape_instagram_profiles |
trade, city, parallelize |
Search Instagram for tradespeople profiles by trade + city. Returns: { "total_profiles": int, "profiles_with_phone": int, "profiles": [...], "proxies_used": int, "queries_run": int, } |
| _run_search |
q, start |
|
| _bounded_search |
q, start |
|
| _parse_synthetic_phone_row |
entry |
|
| _bounded_fetch |
uname |
|
apps/scope/product/backend/scrapers/whatsapp_checker.py
| Function |
Arguments |
Purpose |
| _get_ws_url |
|
Return the WebSocket debugger URL for any available browser tab. |
| _cdp_send |
ws, method, params, msg_id |
Send a single CDP command over an open websockets connection and return result. |
| check_number |
phone_digits |
Return True if phone_digits has a WhatsApp account. |
| check_bulk |
phones, concurrency, skip_check |
Check WhatsApp presence for a list of phone numbers. |
apps/scope/product/backend/state_machine.py
| Function |
Arguments |
Purpose |
| _guard_no_work_started |
milestones |
True iff every milestone is still pending / unset. |
| can_transition |
entity, from_status, to_status, actor_role, milestones |
Check whether a state transition is allowed. |
| assert_transition |
entity, from_status, to_status, actor_role, milestones, status_code |
:func:can_transition + raise HTTPException on failure. |
apps/scope/product/backend/workflows/brief_enrichment.py
apps/scope/product/backend/workflows/brief_intake.py
apps/scope/product/backend/workflows/contractor_discovery.py
| Function |
Arguments |
Purpose |
| to_dict |
self |
|
| run_contractor_discovery |
job_id, max_send, stagger_seconds |
Full contractor discovery pipeline for a job. |
| on_contractor_reply |
phone, job_id |
Called by the WhatsApp webhook when a contacted contractor first replies. |
| _expand_trade_slugs |
trade, max_slugs |
Map a trade/job description to multiple Houzz directory slugs. |
| _search_houzz_expanded |
trade, city |
Search Houzz for the target city first. Only expand to nearby cities if the primary city returns fewer than _SPARSE_THRESHOLD results — because in small towns tradespeople often list under the nearest larger city. |
| _search_houzz |
trade, city |
Scrape Houzz directory for contractors. Returns list of candidate dicts. |
| _search_facebook |
trade, city, days_back |
Search Facebook groups for contractor recommendations via Bright Data. |
| _search_forums |
trade, city, days_back |
Search Spanish forums (Forocoches, Mediavida, Reddit ES) via Bright Data. |
| _scrape_fb_post_comments |
urls, city, already_found |
Fetch full FB post pages and extract phones + business names from comments. |
| _fetch_one |
url |
|
| _extract_name_near_phone |
text, phone_digits |
Try to find a commenter name near a phone number in FB post text. |
| _extract_phones_from_text |
text |
Extract phone numbers from a text snippet. |
| _extract_business_names |
text, phones_already_found |
Find business name mentions in FB comments that don't have a phone number. |
| _merge_and_deduplicate |
houzz, facebook |
Merge Houzz and Facebook candidates, deduplicate by phone, filter valid. |
| _send_single_outreach |
candidate, job_id, brief, humanized_summary, lang |
Create HC record and send one outreach message. |
| _humanize_brief |
brief, lang |
Get a humanized job summary for template slot {{2}}. |
| _send_first_reply |
phone_digits, contractor_id, provenance |
Send a personalized follow-up when a contractor first replies. |
| _background_profile_import |
contractor_id, profile_url |
Kick off Profile Import workflow in background after a contractor replies. |
| _write_workflow_signal |
job_id, sent, hc_ids |
Write completion signal for Hermes to pick up on next turn. |
| _write |
|
|
apps/scope/product/backend/workflows/copy.py
| Function |
Arguments |
Purpose |
| _get_bedrock |
|
|
| _converse_sync |
system, user, max_tokens |
Synchronous Bedrock Converse call. Used inside asyncio.to_thread(). |
| humanize_job_summary |
brief, language |
Turn a homeowner brief into a natural one-liner for WhatsApp template slot {{2}}. |
| craft_first_reply |
brief, contractor_profile, language |
Write a personal follow-up message when a contractor first replies to outreach. |
| _build_profile_summary |
profile |
Build a brief human-readable summary of contractor profile data. |
| _build_brief_summary |
brief |
Build a one-sentence summary of the job brief. |
apps/scope/product/backend/workflows/profile_import.py
| Function |
Arguments |
Purpose |
| to_dict |
self |
|
| run_profile_import |
contractor_id, source_url |
Full Profile Import pipeline for a known contractor. |
| run_profile_import_for_phone |
phone, source_url, name, trade, city |
Look up or create a contractor record by phone, then run Profile Import. |
| _write_workflow_signal |
contractor_id, source_url, trust_score, canvas_token, status |
Append a workflow_signal to the contractor dossier. |
apps/scope/product/web/src/App.tsx
apps/scope/product/web/src/components/ConsentDrawer.tsx
| Function |
Arguments |
Purpose |
| ConsentDrawer |
{ |
|
| open, |
|
|
| onClose, |
|
|
| quoteToken, |
|
|
| scope, |
|
|
| amountTotalCents, |
|
|
| homeowner_email, |
|
|
| onPaymentReady, |
|
|
| } |
|
|
| handleConfirm |
|
|
apps/scope/product/web/src/components/DocumentViewer.tsx
| Function |
Arguments |
Purpose |
| DocumentViewer |
{ src, title, downloadUrl, className = '', fullHeight = false } |
|
apps/scope/product/web/src/components/EditableQuoteCanvas.tsx
| Function |
Arguments |
Purpose |
| draftToChangeOrder |
d |
|
| parseDuration |
label |
|
| buildDuration |
n, unit |
|
| ContingencyDraftRow |
{ |
|
| draft, |
|
|
| lang, |
|
|
| onRemove, |
|
|
| } |
Inline contingency draft card between milestones. |
|
| EditableQuoteCanvas |
{ scope, onChange, lang = 'en' } |
|
| updateMilestone |
i, field, value |
|
| addMilestone |
|
|
| removeMilestone |
i |
|
| removeContingency |
afterIdx, title |
|
| setDuration |
newN, newUnit |
|
apps/scope/product/web/src/components/ErrorBoundary.tsx
apps/scope/product/web/src/components/FullScreenStep.tsx
| Function |
Arguments |
Purpose |
| FullScreenStep |
{ icon, title, subtitle, children, footer } |
|
apps/scope/product/web/src/components/LanguagePickerScreen.tsx
apps/scope/product/web/src/components/LanguageToggle.tsx
apps/scope/product/web/src/components/LeoLogo.tsx
| Function |
Arguments |
Purpose |
| LeoLogo |
{ variant = 'charcoal', mark = 'wordmark', height = 20, className } |
|
apps/scope/product/web/src/components/LocationPickerModal.tsx
apps/scope/product/web/src/components/PageLoading.tsx
apps/scope/product/web/src/components/RequireAuth.tsx
| Function |
Arguments |
Purpose |
| RequireAuth |
{ children, role } |
|
apps/scope/product/web/src/components/canvas/ClaimProfileDrawer.tsx
apps/scope/product/web/src/components/canvas/ProfileActionDrawer.tsx
apps/scope/product/web/src/components/canvas/ScopeActionBar.tsx
apps/scope/product/web/src/components/chat/ActionBar.tsx
| Function |
Arguments |
Purpose |
| ActionBar |
{ |
|
| status, |
|
|
| previewOpen, |
|
|
| onTogglePreview, |
|
|
| confirmLabel, |
|
|
| onConfirm, |
|
|
| confirmDisabled, |
|
|
| confirmed = false, |
|
|
| drawerState, |
|
|
| onDrawerAction, |
|
|
| } |
|
|
| handleActionClick |
|
|
apps/scope/product/web/src/components/chat/AttachmentSheet.tsx
apps/scope/product/web/src/components/chat/ChatMessage.tsx
apps/scope/product/web/src/components/chat/ChatMessages.tsx
| Function |
Arguments |
Purpose |
| ChatMessages |
{ messages, isThinking, bottomPadding = 180, afterFirstMessageSlot } |
|
| handler |
|
|
apps/scope/product/web/src/components/chat/ChatShell.tsx
| Function |
Arguments |
Purpose |
| SubmitConfirmModal |
{ |
|
| mode, |
|
|
| onDismiss, |
|
|
| } |
Post-submit confirmation modal — adapts to job post vs. profile save |
|
| FullscreenOverlay |
{ |
|
| drawerState, |
|
|
| content, |
|
|
| onAction, |
|
|
| onDismiss, |
|
|
| } |
|
|
| BannerOverlay |
{ |
|
| drawerState, |
|
|
| content, |
|
|
| onAction, |
|
|
| onDismiss, |
|
|
| } |
|
|
| ChatShell |
{ |
|
| title, |
|
|
| headerLeft, |
|
|
| headerRight, |
|
|
| messages, |
|
|
| isThinking, |
|
|
| status, |
|
|
| previewState, |
|
|
| previewContent, |
|
|
| placeholderContent, |
|
|
| customDrawerContent, |
|
|
| onSendText, |
|
|
| onSendVoice, |
|
|
| onConfirm, |
|
|
| confirmLabel, |
|
|
| previewLabelClosed = 'Preview', |
|
|
| previewLabelOpen = 'Close preview', |
|
|
| confirmed = false, |
|
|
| drawerState, |
|
|
| onDrawerAction, |
|
|
| onComposingChange, |
|
|
| emptyPreviewLabel, |
|
|
| previewThinkingLabels, |
|
|
| afterFirstMessageSlot, |
|
|
| contained = false, |
|
|
| initialPreviewOpen = false, |
|
|
| confirmMode = 'job', |
|
|
| closePreviewCount = 0, |
|
|
| } |
|
|
| handleOverlayAction |
|
|
| handleOverlayDismiss |
|
|
apps/scope/product/web/src/components/chat/CustomDrawerBody.tsx
apps/scope/product/web/src/components/chat/PreviewPanel.tsx
| Function |
Arguments |
Purpose |
| VellumOverlay |
{ pulse } |
Brand Vellum overlay — identical DOM to brand-book.html. Visual styles from /brand-effects.css (shared, not processed by Vite). |
| PreviewPanel |
{ |
|
| previewState, |
|
|
| children, |
|
|
| placeholderContent, |
|
|
| className, |
|
|
| mobile = false, |
|
|
| inline = false, |
|
|
| open = true, |
|
|
| overlayLabel, |
|
|
| emptyLabel = 'Check back here as your brief builds up', |
|
|
| thinkingLabels = DEFAULT_BUILDING_LABELS, |
|
|
| } |
|
|
apps/scope/product/web/src/components/chat/ThinkingIndicator.tsx
| Function |
Arguments |
Purpose |
| ThinkingIndicator |
|
Typing dots while the agent is processing (shown when isThinking and no streaming text). |
apps/scope/product/web/src/components/dashboard/JobCard.tsx
| Function |
Arguments |
Purpose |
| JobCard |
{ scope, contractorId: _contractorId, onSubmitProof, onCreateVariation } |
|
apps/scope/product/web/src/components/dashboard/SubmitProofSheet.tsx
apps/scope/product/web/src/components/dashboard/VariationCreateSheet.tsx
apps/scope/product/web/src/components/project/CancelJobSheet.tsx
| Function |
Arguments |
Purpose |
| CancelJobSheet |
{ |
|
| open, onClose, totalCents, contractorName, quoteToken, onCancelled, navigateToChat, |
|
|
| } |
|
|
| handleCancel |
|
|
apps/scope/product/web/src/components/project/DocumentSheet.tsx
| Function |
Arguments |
Purpose |
| DocumentSheet |
{ open, onClose, src, title } |
|
apps/scope/product/web/src/components/project/InlineLogin.tsx
apps/scope/product/web/src/components/project/MilestoneDetailSheet.tsx
| Function |
Arguments |
Purpose |
| MilestoneDetailSheet |
{ |
|
| open, onClose, milestone, milestoneIndex, update, contractorName, quoteToken, |
|
|
| onReleased, navigateToChat, onOpenLightbox, canRelease = true, |
|
|
| } |
|
|
| handleRelease |
|
|
| statusLabel |
|
|
apps/scope/product/web/src/components/project/PageSkeleton.tsx
| Function |
Arguments |
Purpose |
| PageSkeleton |
|
PageSkeleton — Animated loading skeleton for ProjectDetail. Shows a charcoal header placeholder + content rows with pulse animations. |
apps/scope/product/web/src/components/project/ReviewSheet.tsx
apps/scope/product/web/src/components/project/VariationDetailSheet.tsx
apps/scope/product/web/src/components/quote/FinalizeModal.tsx
apps/scope/product/web/src/context/AuthContext.tsx
apps/scope/product/web/src/context/SandboxContext.tsx
apps/scope/product/web/src/hooks/useCanvasQuery.ts
apps/scope/product/web/src/hooks/useChat.ts
apps/scope/product/web/src/hooks/useVoiceRecorder.ts
apps/scope/product/web/src/i18n.ts
| Function |
Arguments |
Purpose |
| setAppLanguage |
lang |
Convenience: change language and persist to localStorage. |
apps/scope/product/web/src/lib/api.ts
| Function |
Arguments |
Purpose |
| log |
msg, data |
|
| logError |
msg, err |
|
| setAuthTokenGetter |
fn |
Called once by AuthProvider when it mounts. |
| _sandboxHeaders |
|
Returns X-Sandbox header when sandbox mode is active. Uses the shared isSandbox() helper from utils to avoid key drift. |
| jsonRequest |
url, init |
Performs an apiFetch and parses JSON, returning a typed result. On HTTP error, returns { ok: false, error: message }. On network error, throws — callers should catch if needed. |
| apiFetch |
url, init |
|
| sendChatMessage |
params |
|
| transcribeAudio |
blob, opts |
|
| uploadPhotos |
leadId, photos |
|
| importProfile |
url, contractorId |
SSE stream from POST /api/profile-import — yields parsed event objects. |
| signalComposing |
userId, composing, inputType |
Fire-and-forget signal: user is composing (typing/recording) or stopped. Lightweight — no response needed. Backend uses this to hold off premature replies. |
| extractDocument |
file |
|
| fetchInbox |
token |
|
| approveOutreach |
token |
|
| fetchCanvas |
token |
|
| finalizeScope |
contractorId, scopeData, authUserId |
|
| claimProfile |
canvasToken, accessToken |
|
| createStripeAccount |
contractorId, opts |
|
| getStripeAccountLink |
contractorId |
|
| getStripeAccountStatus |
contractorId |
|
| fetchContractorScopes |
contractorId |
|
| updateScope |
token, scopeData, contractorId |
|
| fetchOps |
token |
|
apps/scope/product/web/src/lib/handoff.ts
| Function |
Arguments |
Purpose |
| consumeHandoff |
|
Read and delete the handoff payload. Returns an empty object if there's nothing (direct navigation, refresh, or already consumed). |
apps/scope/product/web/src/lib/supabase.ts
apps/scope/product/web/src/lib/tracking.ts
| Function |
Arguments |
Purpose |
| initTracking |
|
Initialise PostHog. Call this once after cookie consent is granted. Safe to call multiple times — only initialises on first call. |
| identify |
userId, traits |
Associate subsequent events with a user. Call after login / session restore. |
| track |
event, properties |
Fire a named event with optional properties. |
| _sendToBackend |
event, properties |
|
apps/scope/product/web/src/lib/utils.ts
| Function |
Arguments |
Purpose |
| uid |
|
|
| clsx |
args |
|
| eur |
cents |
Format cents as EUR with 0 decimals (e.g. 15000 → "€150"). |
| eurFromEuros |
euros |
Format a euro amount (not cents) as EUR with 0 decimals (e.g. 150 → "€150"). |
| computeQuoteTotals |
scope |
Canonical quote financial computation. All amounts are in euros (not cents). |
| isSandbox |
|
Returns true when sandbox mode is active (reads the shared localStorage key). |
| getLeoAuth |
|
Read the leo_auth session object, returning {} on missing/invalid JSON. |
| mergeLeoAuth |
patch |
Shallow-merge a patch into the leo_auth session object. |
| fileToBase64 |
file |
Read a File (image) as a base64 data string (no data: prefix). |
apps/scope/product/web/src/pages/AuthCallback.tsx
apps/scope/product/web/src/pages/Canvas.tsx
apps/scope/product/web/src/pages/ComponentLibrary.tsx
apps/scope/product/web/src/pages/Dashboard.tsx
apps/scope/product/web/src/pages/DesignSystem.tsx
apps/scope/product/web/src/pages/FirstQuote.tsx
| Function |
Arguments |
Purpose |
| generateChangeSummary |
before, after, lang |
|
| EditModeWrapper |
{ |
|
| scope, |
|
|
| lang, |
|
|
| isEditMode, |
|
|
| isThinking, |
|
|
| onEnterEdit, |
|
|
| onSaveEdits, |
|
|
| onCancelEdit, |
|
|
| onChange, |
|
|
| } |
|
|
| ChatMode |
{ |
|
| contractorId, |
|
|
| contractorName, |
|
|
| lang, |
|
|
| location, |
|
|
| editToken, |
|
|
| initialScope, |
|
|
| isFirstQuote, |
|
|
| onLangChange, |
|
|
| onScopeReady, |
|
|
| onStartFresh, |
|
|
| onGoToDashboard, |
|
|
| } |
|
|
| FirstQuote |
|
|
| handleScopeReady |
scope |
|
| handleAfterChatLocationConfirm |
label |
|
| handleConnectBank |
quoteToken |
|
apps/scope/product/web/src/pages/ImportPro.tsx
| Function |
Arguments |
Purpose |
| adaptRawToCanvas |
raw |
Adapt raw ProfileResult (from SSE preview) into the ProfileUpdate shape that ProfileCanvas expects. The backend sends result.model_dump() for preview events — flat fields like name, reviews[], projects[] at the top level. ProfileCanvas needs business_name, nested sources[] with per-platform reviews/projects, etc. |
| advanceSteps |
steps, activeId |
|
| ImportPro |
|
|
| handleNavigateToCanvas |
|
|
| handlePhoneSubmit |
e |
|
apps/scope/product/web/src/pages/JobChat.tsx
apps/scope/product/web/src/pages/JobInbox.tsx
apps/scope/product/web/src/pages/Login.tsx
apps/scope/product/web/src/pages/MyQuotes.tsx
apps/scope/product/web/src/pages/OnboardHomeowner.tsx
apps/scope/product/web/src/pages/OnboardPro.tsx
apps/scope/product/web/src/pages/OpsMonitor.tsx
apps/scope/product/web/src/pages/ProjectDetail.tsx
apps/scope/product/web/src/pages/QuoteSent.tsx
apps/scope/product/web/src/pages/SandboxDashboard.tsx
apps/scope/product/web/src/pages/Settings.tsx
apps/scope/product/web/src/pages/StripeKyc.tsx
apps/scope/product/web/src/pages/StripeRefresh.tsx
apps/scope/product/web/src/pages/StripeReturn.tsx
apps/scope/product/web/src/reel/CaptionStrip.tsx
apps/scope/product/web/src/reel/ReelSwitcher.tsx
apps/scope/product/web/src/reel/engine.ts
| Function |
Arguments |
Purpose |
| chatUserBeats |
|
Beats that carry a user line (the ones that trigger a /v1/chat round-trip). |
| resetChatCursor |
|
|
| delay |
ms |
|
| clone |
v |
|
| reelData |
|
Current mutable data for the active flow, lazily seeded from initialData. |
| setReelData |
mutate |
Mutate the current data in place. |
| resetReelData |
|
Reset to a fresh clone of initialData (used at the top of each loop). |
| prefersReducedMotion |
|
|
| jsonResponse |
body |
|
| reelHandle |
url, init |
Returns a canned Response when reel mode can serve this request, else null (the caller then proceeds — and with VITE_API_URL=reel.invalid in the vendored build, any unhandled call fails loudly instead of hitting a dead host). |
apps/scope/product/web/src/reel/flag.ts
| Function |
Arguments |
Purpose |
| isReelFlowId |
v |
|
| reelFlowId |
|
Resolve the active reel flow, or null when reel mode is off. Order: ?reel=<id> query param (sticks it to localStorage) -> localStorage. ?reel=off / ?reel=0 clears it. Invalid ids are ignored (treated as off). |
| isReel |
|
True when the app is running as a portfolio reel (any flow). |
apps/scope/product/web/src/reel/registry.ts
| Function |
Arguments |
Purpose |
| activeScript |
|
The script for the active reel flow, or undefined when reel mode is off. |
apps/scope/product/web/src/reel/scripts/approve-release.ts
| Function |
Arguments |
Purpose |
| asset |
f |
Resolve a reel public asset in both dev (/app/) and the vendored build (/scope/app/). |
apps/scope/product/web/src/reel/useReelChatDriver.ts
apps/scope/product/web/src/reel/useReelStepDriver.ts
apps/scope/product/web/src/store.tsx
packages/brand/src/brand/build.py
| Function |
Arguments |
Purpose |
| _camel |
key |
ink_dark → inkDark. |
| _kebab |
key |
ink_dark → ink-dark. |
| _to_js_lit |
value |
Escape a string for JS/TS single-quoted literal output. |
| _themes_for_json |
|
Serialise THEMES with camelCase keys for JS/TS consumers. |
| _emit_tokens_json |
|
Serialise the full token set as JSON (camelCase keys, sorted families). |
| _emit_tokens_ts |
|
Emit tokens.ts — typed TS re-export matching old brand.ts surface. |
| _emit_theme_overrides_tailwind |
|
Emit [data-theme="..."] { ... } blocks for Tailwind v4 consumers. |
| _emit_theme_overrides_vars |
|
Emit [data-theme="..."] { ... } blocks for plain-HTML vars.css. |
| _emit_tokens_css |
|
Emit Tailwind v4 @theme { ... } block + [data-theme] overrides. |
| _emit_vars_css |
|
Emit :root { ... } block + utility classes (replaces brand-vars.css). |
| _render_all |
|
|
| _write |
name, body |
|
| _app_artifact_body |
app, name, rendered |
Return the generated-artifact body that app app should sync. |
| _canonical_bytes |
key, app |
Read canonical bytes for a sync key (effects.css, generated/vars.css, assets/leo-charcoal.svg, ...). |
| _sync_public_copy |
app, target_rel, body |
|
| _check_public_copies |
|
Return a list of public copies that drift from the canonical. |
| main |
argv |
|
packages/brand/src/brand/fluid-gradient.js
| Function |
Arguments |
Purpose |
| compile |
gl, type, src |
|
| link |
gl, vs, fs |
|
| makePass |
gl, fragSrc, name |
|
| makePreviewProgram |
gl |
|
| _fbo |
w, h, internalFormat, format, type, filter |
|
| swap |
|
|
| destroy |
gl |
|
| resize |
w, h, internalFormat, format, type, filter |
|
| _initGL |
|
|
| _buildPrograms |
|
|
| _initGradientFBO |
|
|
| _renderGradient |
t |
|
| _quadSim |
|
|
| _quadPreview |
|
|
| _bindSim |
|
|
| _bindPreview |
|
|
| _setTarget |
fbo |
|
| _blit |
pass, setUniforms |
|
| resize |
|
|
| _createBuffers |
sw, sh |
|
| _recreateBuffers |
sw, sh |
|
| _syntheticAudio |
t |
Fake “audio” for the Eleven-style preview: slow swell + tide envelopes and low-frequency carriers (no fast beating). tanh soft-clips mixes for round peaks. |
| soft |
x |
|
| _staticPreviewAudio |
t |
Constant band levels + linear cum only — preview shader stays balanced without frame-varying “audio” (removes micro-jitter on landing heroes). |
| _smoothPreviewAudio |
au |
Two-stage low-pass on avg / avgIn: fast stage follows target, slow stage trails for a longer decay tail (less frame-to-frame jitter from uniforms). |
| _advanceVisualTime |
dt |
Two-pole exponential toward sim time — no spring overshoot / snap-back (plastic drift). Convex combos only; cannot ring past the target like a damped oscillator. |
| _tick |
|
|
| _step |
|
|
| initGradients |
|
|
packages/brand/src/brand/illustrations/generate.py
| Function |
Arguments |
Purpose |
| _load_theme_style |
theme |
Resolve the IllustrationStyle for theme via dynamic import. |
| generate |
|
Generate an illustration of scene in the Leo house register. |
| generate_with_references |
|
Generate a raster illustration that preserves identity across refs. |
packages/brand/src/brand/illustrations/post/chroma_key.py
| Function |
Arguments |
Purpose |
| process |
image |
Make pixels within tolerance of color transparent. |
packages/brand/src/brand/illustrations/post/luminosity_alpha.py
| Function |
Arguments |
Purpose |
| process |
image |
Knock white out, force black. Returns RGBA PNG bytes. |
| _remap |
v |
|
packages/brand/src/brand/illustrations/providers/litellm_raster.py
packages/brand/src/brand/illustrations/providers/litellm_raster_refs.py
| Function |
Arguments |
Purpose |
| render |
|
Render a raster illustration conditioned on reference images. |
packages/brand/src/brand/illustrations/providers/vtracer_vector.py
| Function |
Arguments |
Purpose |
| _flatten_on_white |
rgba_png |
Composite a transparent RGBA PNG onto pure white → opaque RGB PNG. |
| render |
|
Render a vector SVG for scene under style, raster-then-trace. |
packages/brand/src/brand/motion/init.py
| Function |
Arguments |
Purpose |
| get |
name |
Look up a motion style by name. Raises KeyError on miss. |
| names |
|
Return the sorted list of registered motion names. |
packages/brand/src/brand/motion/quiet.py
| Function |
Arguments |
Purpose |
| to_css |
self |
Emit CSS variables under :root. |
| to_ts |
self |
Emit a TypeScript export object — framer-motion-consumable. |
packages/brand/src/brand/themes/init.py
| Function |
Arguments |
Purpose |
| get |
name |
Return the theme module for name. Raises KeyError on miss. |
| names |
|
Return the sorted list of registered theme names. |
packages/brand/src/brand/translucency/init.py
| Function |
Arguments |
Purpose |
| get |
name |
Look up a translucency style by name. Raises KeyError on miss. |
| names |
|
Return the sorted list of registered style names. |
packages/brand/src/brand/translucency/vellum.py
| Function |
Arguments |
Purpose |
| to_css |
self, selector |
Emit the full CSS block for selector. |
packages/brand/src/brand/typography/init.py
| Function |
Arguments |
Purpose |
| get |
name |
Look up a typography style by name. Raises KeyError on miss. |
| names |
|
Return the sorted list of registered typography names. |
packages/brand/src/brand/typography/default.py
| Function |
Arguments |
Purpose |
| to_css |
self |
Emit CSS custom properties for the font families. |
packages/brand/src/illustrations.ts
packages/brand/src/translucency.ts
packages/core/src/core/auth/api_keys.py
| Function |
Arguments |
Purpose |
| verify_api_key |
raw_key |
Look up an API key; return the row (or None on miss / error). |
| require_api_key_or_jwt |
authorization, x_api_key |
FastAPI dep: accept a JWT or an API key. |
packages/core/src/core/auth/deps.py
| Function |
Arguments |
Purpose |
| _contractor_id_for_auth_user |
auth_user_id |
Look up the claimed contractor row for a Supabase auth user. |
| _resolve_current_user |
access_token |
Verify JWT, then resolve role + contractor_id. |
| require_auth |
authorization |
Require any valid Supabase JWT (contractor or homeowner). |
| optional_auth |
authorization |
Return the caller identity if a JWT is present, else None. |
| require_contractor |
authorization |
Require a JWT belonging to a claimed contractor. |
| require_homeowner |
authorization |
Require a JWT belonging to a homeowner (non-contractor) account. |
packages/core/src/core/auth/jwt.py
packages/core/src/core/auth/tokens.py
| Function |
Arguments |
Purpose |
| _is_dev_env |
|
|
| tracker_token_valid |
token |
Predicate form of :func:require_tracker_token for routes that only conditionally require a valid X-Tracker-Token. |
| _check_token |
header_value, env_var, header_name, code_prefix |
|
| require_ops_token |
x_ops_token |
Require X-Ops-Token matching OPS_TOKEN env var. |
| require_tracker_token |
x_tracker_token |
Require X-Tracker-Token matching SALES_TRACKER_TOKEN env var. |
packages/core/src/core/auth/webhooks.py
packages/core/src/core/aws.py
packages/core/src/core/bootstrap.py
| Function |
Arguments |
Purpose |
| repo_root |
|
Return the repo root by walking parents for pyproject.toml + .git. |
| scope_backend_dir |
|
Return the path to the scope-backend tree. |
| backend_dir |
|
Deprecated alias for :func:scope_backend_dir. |
| init |
|
Idempotent: add the backend dir to sys.path + load .env.local. |
| load_env_files |
paths |
Load one or more dotenv files; return the list of paths that loaded. |
packages/core/src/core/db.py
| Function |
Arguments |
Purpose |
| _supabase_url_base |
|
|
| sb_url |
|
Supabase REST base URL, i.e. {SUPABASE_URL}/rest/v1. |
| sb_auth_url |
|
Supabase Auth API base URL, i.e. {SUPABASE_URL}/auth/v1. |
| sb_key |
|
Service-role key if set, else anon key. |
| sb_headers |
|
Standard headers for Supabase REST calls. |
| init |
self, client |
|
| client |
self |
The underlying :class:httpx.AsyncClient. |
| select |
self, table |
Run GET /rest/v1/{table} with PostgREST-style query params. |
| insert |
self, table, row |
Run POST /rest/v1/{table} with a single row payload. |
| upsert |
self, table, row |
Run POST /rest/v1/{table} with Prefer: resolution=merge-duplicates. |
| update |
self, table, patch |
Run PATCH /rest/v1/{table} with PostgREST filters on the URL. |
| delete |
self, table |
Run DELETE /rest/v1/{table} with PostgREST filters. |
| request |
self, method, path |
Escape-hatch raw request. Returns the :class:httpx.Response. |
| _build_client |
|
Build a new pooled :class:httpx.AsyncClient. |
| get_supabase |
|
Return the process-wide :class:Supabase singleton. |
| close_supabase_pool |
|
Close the pooled client (call on FastAPI shutdown). |
| check_supabase_health |
|
Probe Supabase reachability. |
packages/core/src/core/errors.py
| Function |
Arguments |
Purpose |
| init |
self, message |
|
| to_detail |
self |
Return the JSON-serialisable detail body for FastAPI. |
| to_http |
self |
Return an :class:HTTPException with this error's status + body. |
| api_error |
status, message |
Return an :class:HTTPException matching the unified error envelope. |
packages/core/src/core/http.py
| Function |
Arguments |
Purpose |
| http_client |
timeout |
General-purpose async client with Leo's defaults. |
| sb_request |
timeout |
Short-lived Supabase-scoped async client (base_url + auth headers). |
| http_client_sync |
timeout |
Sync counterpart to :func:http_client. |
packages/core/src/core/money.py
| Function |
Arguments |
Purpose |
| _as_decimal |
value |
Coerce value to Decimal via str(value) to dodge float noise. |
| _quantize |
value |
Round value to 2 dp, ROUND_HALF_UP (Spanish legal convention). |
| to_cents |
eur |
Convert EUR amount to integer cents (HALF_UP at 2 dp). |
| from_cents |
cents |
Convert integer cents to Decimal EUR (2 dp). |
| add_iva |
amount, rate |
Return amount * (1 + rate) rounded 2 dp HALF_UP. |
| strip_iva |
gross, rate |
Inverse of add_iva: extract net from gross. |
| iva_amount |
amount, rate |
Return only the VAT component: amount * rate rounded 2 dp. |
| add_iva_percent |
amount, percent |
Like :func:add_iva but percent is an integer percentage. |
| strip_iva_percent |
gross, percent |
Like :func:strip_iva but percent is an integer percentage. |
| iva_amount_percent |
amount, percent |
Like :func:iva_amount but percent is an integer percentage. |
| format_eur |
amount |
Format amount as EUR string. |
packages/core/src/core/phone.py
packages/core/src/core/resilience.py
packages/core/src/core/text.py
| Function |
Arguments |
Purpose |
| strip_accents |
text |
Remove diacritical marks. |
| normalize_spanish |
text |
Canonical form for Spanish search / equality comparison. |
| slugify |
text |
Produce a URL-safe slug. |
packages/fulltext/src/fulltext/_stemmer.py
packages/fulltext/src/fulltext/forum/init.py
| Function |
Arguments |
Purpose |
| set_provider |
provider |
Inject a concrete async forum-search provider. |
| forum_search |
query |
Async forum-corpus search. |
packages/fulltext/src/fulltext/index.py
| Function |
Arguments |
Purpose |
| init |
self, name, db_path |
:param name: Logical collection name ("prices", "cype"). :param db_path: Optional explicit path; if omitted, uses <package_root>/data/indexes/{name}.db relative to the consumer — pass one explicitly in production callers. |
| _setup_tables |
self |
|
| add |
self, doc_id, slug, title, body, meta |
Insert or replace a document. All text fields are stemmed at index time — the documents table stores the post-tokenisation form, which the FTS triggers then index. This keeps index-time and query-time tokenisation in lock-step (D4). |
| add_city_price |
self, doc_id, city, prices, source, title, slug |
Insert or replace a (doc_id, city) pricing row. |
| commit |
self |
Flush pending writes. |
| count |
self |
Return number of indexed documents. |
| search |
self, query, limit, city |
Full-text search with BM25 ranking. |
| search_city |
self, city, query, limit |
Flat city-price lookup, optionally narrowed by an FTS query. |
| rebuild |
self |
Rebuild the FTS5 index from scratch (expensive). |
| drop |
self |
Drop and recreate all tables. |
| close |
self |
Close the underlying SQLite connection. |
| del |
self |
|
packages/fulltext/src/fulltext/legal/init.py
| Function |
Arguments |
Purpose |
| set_provider |
provider |
Inject a concrete async legal-search provider. |
| legal_search |
query |
Async legal-corpus search. |
packages/fulltext/src/fulltext/protocols.py
| Function |
Arguments |
Purpose |
| search |
self, query, limit, city |
Return up to limit BM25-ranked results. |
| count |
self |
Return total indexed document count. |
| search |
self, query |
Return up to limit results; MAY raise :class:~fulltext.errors.SearchError subclasses. |
packages/fulltext/src/fulltext/rerank.py
| Function |
Arguments |
Purpose |
| city_boost |
city |
Return a reranker that subtracts amount from the rank of any result whose meta["city_prices"] mentions city. |
| _run |
results |
|
| chain_reranks |
|
Compose rerankers left-to-right. |
| _run |
results |
|
packages/fulltext/src/fulltext/synonyms.py
| Function |
Arguments |
Purpose |
| _make_or_group |
stems |
Build an FTS5 OR group: single token or (a OR b OR c). |
| expand_query |
raw_query |
Expand a raw user query into an FTS5 MATCH expression. |
packages/fulltext/src/fulltext/tokenizer.py
| Function |
Arguments |
Purpose |
| tokenize |
text |
Normalise + stem + filter a free-text string. |
packages/fulltext/src/fulltext/web/init.py
| Function |
Arguments |
Purpose |
| set_provider |
provider |
Inject a concrete async provider. None reverts to the stub (empty-result) behaviour. Intended for app bootstrap + tests. |
| web_search |
query |
Async open-web search. Returns [] unless a provider has been installed via :func:set_provider. |
packages/llm/src/llm/chat.py
| Function |
Arguments |
Purpose |
| _normalise |
messages_or_prompt |
Accept str → wrap in single user :class:Message. |
| _resolve_model_or_tier |
model, tier |
|
| chat |
messages_or_prompt |
Unified async chat entry point. Dispatches on provider. |
| _invoke |
model_id |
|
| chat_sync |
messages_or_prompt |
Sync version of :func:chat. No fallback chain — sync callers (i18n_engine, sales_tracker, profile_import) run single-shot. |
| _emit_usage |
resp |
Dispatch the response to observability; swallow observer bugs. |
packages/llm/src/llm/config.py
| Function |
Arguments |
Purpose |
| proxy_base_url |
|
Return the proxy base URL. |
| proxy_api_key |
|
Return the proxy API key. See :func:proxy_base_url for rationale. |
packages/llm/src/llm/embed.py
packages/llm/src/llm/errors.py
| Function |
Arguments |
Purpose |
| init |
self, message |
|
| repr |
self |
|
packages/llm/src/llm/images.py
packages/llm/src/llm/models/pricing.py
| Function |
Arguments |
Purpose |
| estimate_cost |
usage |
Return USD cost of usage on model. |
packages/llm/src/llm/models/registry.py
| Function |
Arguments |
Purpose |
| _build_registry |
|
Index every model by id + every alias. Enforce invariants. |
| resolve_model |
id_or_alias |
Look up a model by id, alias, or bedrock/... prefix. |
| by_tier |
tier |
Return every model matching tier, ordered by registration. |
| for_provider |
provider |
Return every model for a given provider, in registration order. |
packages/llm/src/llm/models/tiers.py
| Function |
Arguments |
Purpose |
| pick |
tier |
Return the canonical Model.id for tier's default. |
packages/llm/src/llm/prompts/loader.py
| Function |
Arguments |
Purpose |
| render |
self, variables |
Render the template through Jinja with StrictUndefined. |
| _parse_frontmatter |
raw |
Extract YAML frontmatter from a .md file. Missing → {}. |
| load_prompt |
path |
Parse a .md + YAML frontmatter file into a :class:Prompt. |
packages/llm/src/llm/prompts/registry.py
| Function |
Arguments |
Purpose |
| init |
self, root |
|
| _load |
self |
Walk the templates root, parse every .md. Idempotent. |
| register |
self, prompt |
Inject a :class:Prompt into the registry. Idempotent on key. |
| get |
self, prompt_id |
Look up a prompt. version None ⇒ highest; language None ⇒ language-agnostic entry, else falls through to language-specific entry. |
| list |
self |
Every known prompt id, in registration order (deduplicated). |
| render_prompt |
prompt_id |
One-shot: look up prompt_id and :meth:~Prompt.render it. |
| list_prompts |
|
Convenience wrapper around :meth:PROMPTS.list. |
| get_prompt |
prompt_id |
Return the raw :class:Prompt without rendering. |
packages/llm/src/llm/providers/base.py
| Function |
Arguments |
Purpose |
| cost_usd |
self |
Compute USD cost via :data:llm.PRICING. Returns 0.0 on unknown model. |
packages/llm/src/llm/providers/bedrock.py
| Function |
Arguments |
Purpose |
| _bedrock_client |
region |
Return a bedrock-runtime client for region with Leo billing discipline. |
| _msg_to_converse |
m |
Leo :class:Message → Bedrock Converse API message shape. |
| _parse_converse_response |
data |
|
| _map_botocore_error |
exc |
Translate a botocore ClientError → :mod:llm.errors hierarchy. |
| complete_sync |
messages |
Sync Bedrock Converse call. Runs on the caller's thread — callers from async code MUST wrap in asyncio.to_thread (see :func:llm.providers.bedrock.complete). |
| complete |
messages |
Async wrapper over :func:complete_sync via asyncio.to_thread. |
packages/llm/src/llm/providers/fallback.py
| Function |
Arguments |
Purpose |
| resolve_chain |
name_or_list |
Resolve a named chain or raw list into an ordered model id list. |
| run_with_fallback |
primary, fallback |
Run invoke(model_id) against primary, falling through fallback on retryable errors. |
packages/llm/src/llm/providers/gemini.py
| Function |
Arguments |
Purpose |
| complete |
messages |
Async Gemini completion. Currently proxied; spec'd for native. |
| complete_sync |
messages |
Sync Gemini completion. Currently proxied; spec'd for native. |
packages/llm/src/llm/providers/litellm_proxy.py
packages/llm/src/llm/stream.py
| Function |
Arguments |
Purpose |
| stream |
messages_or_prompt |
Stream completion chunks. Terminal chunk carries usage. |
packages/llm/src/llm/structured.py
| Function |
Arguments |
Purpose |
| _choose_mode |
model_id |
Pick json_schema if the model supports strict schema; else json_object. |
| _parse |
raw_text |
|
| complete_structured |
messages_or_prompt |
Async structured-output call. Returns a validated schema instance. |
| complete_structured_sync |
messages_or_prompt |
Sync structured-output call. Returns a validated schema instance. |
packages/llm/src/llm/tokens.py
packages/llm/src/llm/usage.py
packages/llm/src/llm/vision.py
| Function |
Arguments |
Purpose |
| _to_data_url |
image |
Normalise image input to a data: URL. |
| _build_vision_message |
prompt, image |
Assemble a single user :class:Message with text + image_url blocks. |
| _ensure_vision |
model_id |
Raise :exc:ModelNotFound if model_id doesn't support vision. |
| complete_vision |
prompt, image |
Async vision call. Default model is :data:~llm.models.tiers.DEFAULT_VISION. |
| complete_vision_sync |
prompt, image |
Sync vision call. No fallback — sync callers run single-shot. |
packages/messaging/src/messaging/channel.py
| Function |
Arguments |
Purpose |
| copy |
self |
Return a new :class:ChannelCapabilities with updates applied. |
packages/messaging/src/messaging/comms.py
| Function |
Arguments |
Purpose |
| notify |
|
Send a notification via the appropriate channel(s). |
| _resolve_channels |
channel, phone, email |
Decide which real channels to dispatch to given the channel sentinel. |
| _send_whatsapp |
phone, message, purpose, template_name, template_params |
Delegate to the unified WhatsApp sender. |
| _send_email |
to, subject, text, html |
Delegate to :func:messaging.email.send_email. |
| notify |
self |
|
packages/messaging/src/messaging/email/resend.py
| Function |
Arguments |
Purpose |
| _resolve_api_key |
|
Pull the Resend API key from env. |
| send_email |
to, subject, body_html, body_text |
Send an email via Resend. |
| send_email_resend |
to, subject, body_html, body_text, from_label, from_address |
Legacy alias for :func:send_email. |
packages/messaging/src/messaging/frameworks/adapters.py
| Function |
Arguments |
Purpose |
| register_host_adapter |
name, fn |
Register fn under name (called by the host at startup). |
| get_adapter |
name |
Look up a host adapter. When required is True, raises if missing. |
| has_adapter |
name |
True if name has been registered (useful in tests/dry-runs). |
| clear_adapters |
|
Wipe the registry (only intended for test teardown). |
packages/messaging/src/messaging/frameworks/hermes.py
| Function |
Arguments |
Purpose |
| is_available |
|
Return True if Hermes's modules can be imported from the current PYTHONPATH. Hosts call this at startup to decide whether to wire Hermes-dependent tools. |
| get_ai_agent_class |
|
Return the Hermes AIAgent class (lazy import so we don't force vendor/hermes-agent to be on path at package-import time). |
| get_session_db_class |
|
Return the Hermes SessionDB class. |
| get_tool_registry |
|
Return the singleton Hermes tools.registry.registry. |
| get_create_custom_toolset |
|
Return the Hermes toolsets.create_custom_toolset factory. |
packages/messaging/src/messaging/frameworks/protocol.py
| Function |
Arguments |
Purpose |
| is_available |
self |
Return True if the provider's dependencies are present on PYTHONPATH / installed. Hosts check this before wiring tools — an absent provider should degrade gracefully rather than crash on first agent call. |
| Function |
Arguments |
Purpose |
| enrich_message |
msg |
Convert all media attachments on msg into in-line text. |
| _is_document_mime |
mime |
Catch document MIME variants not in the frozen set. |
| _resolve_path |
attachment |
Get a local file path, writing base64 to a temp file if needed (web chat uploads). |
| _enrich_image |
attachment |
|
| _enrich_audio |
attachment |
Transcribe audio via :func:voice.transcribe. Messaging never owns a codec. |
| transcribe_file |
fpath |
Transcribe an audio file on disk using the best available STT provider. |
| _enrich_document |
attachment |
|
packages/messaging/src/messaging/verification/api.py
| Function |
Arguments |
Purpose |
| _searxng_search |
query, max_results, days_back |
SearXNG JSON search. Serialized — used only for the fast NIF/REA/review checks. |
| _load_bd_key |
|
Load Bright Data API key from env or .env.local. |
| _google_via_brightdata |
query, max_results, days_back |
Run one Google search through Bright Data Web Unlocker. |
| _handle_bd_credit_exhausted |
|
Send a WhatsApp alert when Bright Data credit runs out. Only fires once per session. |
| _send_brightdata_credit_alert |
|
Send WhatsApp message to Peter warning that Bright Data credit is out. |
| _social_search_parallel |
queries, max_results, days_back |
Run multiple social proof queries in parallel via Bright Data Web Unlocker. |
| _run |
idx, q |
|
| check_brightdata_credit |
notify |
Verify Bright Data Web Unlocker is working and has credit. |
| validate_nif |
nif |
Validate a Spanish NIF/CIF/NIE using the official checksum algorithm. |
| check_vies |
nif |
Check a Spanish VAT number against the EU VIES REST API. |
| check_rea |
identifier, id_type |
Check if a company is registered in Spain's REA (construction accreditation). |
| search_review_signals |
name, city, phone, website |
Search SearXNG for review/rating data about a tradesperson. |
| expand_fb_queries |
query, max_queries |
Generate query variations: English, Spanish, and related trade synonyms. |
| search_fb_posts |
queries, max_results, days_back |
Search Facebook groups for contractor mentions via Bright Data Web Unlocker (parallel). |
| search_forum_posts |
queries, max_results, days_back |
Search Spanish forums (Forocoches, Mediavida, Reddit ES) via Bright Data (parallel). |
| search_social_proof |
name, city, phone |
Search for Facebook group and forum mentions/recommendations of a contractor. |
| _has_identifying_signal |
snippet, title |
Return True if the text contains the phone or the city. |
| run_verification_checks |
profile |
Run the fast verification checks: NIF/VIES/REA + review signals. |
| run_social_proof_checks |
profile |
Run the slow social proof searches: Facebook groups + forums (~15 SearXNG calls). |
| enrich_contractor_from_phone |
phone, name, trade, city |
Standalone verification for a contractor we know by phone but may not have a profile URL for. |
| _extract_legal_identity |
website_url |
Fetch legal / privacy pages and extract NIF, razón social, etc. |
| _company_name_is_specific |
name |
Return True if the name is unambiguous enough for a web credential search. |
| enrich_credentials_from_web |
profile |
Search the web for registrations/licenses/certifications via SearXNG. |
packages/messaging/src/messaging/whatsapp/outreach_budget.py
| Function |
Arguments |
Purpose |
| _headers |
key |
|
| _today_utc |
|
|
| _tomorrow_utc |
|
|
| daily_sent_count |
waba_id |
Count cold messages sent today from waba_id. |
| request_quota |
waba_id, n, daily_limit |
Return (approved, queued) where approved + queued == n. |
| log_send |
waba_id, phone_digits, job_id, hc_id, purpose |
Append one row to cold_outreach_log. Fire-and-forget. |
| enqueue_deferred |
entries, waba_id, job_id, humanized_summary, lang |
Push overflow entries into cold_outreach_queue for tomorrow. |
| flush_queue |
waba_id |
Return + mark-sent all queue rows eligible today. |
packages/messaging/src/messaging/whatsapp/send.py
| Function |
Arguments |
Purpose |
| _wa_token |
|
|
| _wa_phone_id |
|
|
| _record_cold_send |
purpose, phone_digits, job_id |
Fire-and-forget: log a cold send to cold_outreach_log. |
| send_wa_message |
phone, text, purpose, name, template_params, do_store, skip_window_check |
Send a WhatsApp message — the canonical entry point. |
| send_wa_message_sync |
phone, text, purpose, name, template_params, do_store, skip_window_check |
Sync wrapper for hermes tool handlers running in a thread executor. |
packages/messaging/src/messaging/whatsapp/session.py
| Function |
Arguments |
Purpose |
| _sb_auth_headers |
|
Minimal read-auth headers for a Supabase REST GET. |
| check_24h_window |
phone |
Return True if we have an inbound WA message from phone within 24h. |
packages/messaging/src/messaging/whatsapp/storage.py
| Function |
Arguments |
Purpose |
| store_message |
phone_number, role, text, message_type, media_urls, media_types, wa_message_id, reply_to_wa_id, reply_to_text |
Insert one row into whatsapp_messages via Supabase REST. |
packages/messaging/src/messaging/whatsapp/templates.py
| Function |
Arguments |
Purpose |
| _freeze_templates |
raw |
Return a two-level read-only view of raw (purpose → lang → template name). |
| detect_language |
phone_digits |
Guess en_US vs es from the phone country code. |
| get_template_name |
purpose, language |
Look up a template name for a purpose + language combo. |
packages/payments/src/payments/checkout.py
| Function |
Arguments |
Purpose |
| assert_can_accept |
contractor |
Raise if this contractor cannot accept a homeowner payment. |
| maybe_reuse_open_session |
|
If the Stripe Checkout Session with this id is still open, return its URL. Otherwise return None (caller creates a new session). |
| _amount_total_cents |
quote |
Read pre-computed amount_total_cents or fall back to the legacy in-process computation for pre-finance rows. |
| create_session |
|
Create (or reuse) the homeowner escrow Stripe Checkout Session. |
packages/payments/src/payments/client.py
| Function |
Arguments |
Purpose |
| _build_client |
api_key |
Build a real stripe.StripeClient. Import is lazy so tests can run without stripe installed (they inject a fake). |
| get_stripe_client |
ctx |
Return a Stripe client keyed to this request's resolved Stripe secret. |
| build_stripe_client_from_key |
api_key |
Explicit helper used by webhook dispatchers where we've already pulled the key out of the :class:SandboxContext tri-state verification. |
packages/payments/src/payments/connect.py
| Function |
Arguments |
Purpose |
| _call |
fn |
|
| create_account |
|
Create a Stripe Express account for a contractor, idempotent per-contractor. |
| create_onboarding_link |
|
Generate a Stripe AccountLink for contractor onboarding. |
| get_account_status |
|
Read live Stripe account state and opportunistically mark onboarding complete. |
| _get |
key, default |
|
| _accepts_params_kwarg |
fn |
Stripe 7.x+ clients expose .create(params={...}) via a typed signature; legacy stubs may only accept **kwargs. Probe once. |
packages/payments/src/payments/disputes.py
packages/payments/src/payments/errors.py
| Function |
Arguments |
Purpose |
| init |
self, message |
|
packages/payments/src/payments/finance.py
packages/payments/src/payments/milestones.py
| Function |
Arguments |
Purpose |
| _get_milestone |
quote, idx |
|
| _advance_milestone_status |
milestones, idx |
Return a new list with milestones[idx].status = new_status and a released_at/marked_complete_at timestamp stamped as appropriate. |
| submit_proof |
|
Contractor submits proof of work on a milestone. |
| release |
|
Homeowner releases funds for a milestone from escrow to the contractor. |
| _stripe_call |
fn, params |
Invoke a Stripe client method with an idempotency key, mapping the SDK's IdempotencyError to our internal sentinel. |
| _is_idempotency_error |
exc |
|
| _reconcile_transfer_id |
client |
Look up the original transfer_id via transfer_group so callers never receive the 'idempotent-duplicate' sentinel. |
packages/payments/src/payments/refunds.py
packages/payments/src/payments/repo.py
| Function |
Arguments |
Purpose |
| from_row |
cls, row |
|
| from_row |
cls, row |
|
| from_row |
cls, row |
|
| from_row |
cls, row |
|
| from_row |
cls, row |
|
| _rename_fee |
patch |
Rename leo_fee_cents -> stripe_fee_cents at the DB boundary. |
| init |
self, sb |
|
| get_quote_by_token |
self, token |
|
| patch_quote |
self, token, patch |
|
| record_checkout_session |
self, token |
|
| mark_quote_paid |
self, token |
|
| mark_quote_payment_failed |
self, token |
|
| mark_quote_refunded |
self, token |
|
| mark_quote_disputed |
self, token |
|
| get_contractor |
self, contractor_id |
|
| patch_contractor |
self, contractor_id, patch |
|
| find_contractor_by_stripe_account |
self, stripe_account_id |
|
| record_account_created |
self, contractor_id |
|
| mark_onboarding_complete |
self, contractor_id |
|
| insert_milestone_update |
self, row |
|
| mark_milestone_released |
self |
|
| list_milestone_updates |
self, token |
|
| insert_variation |
self, row |
|
| get_variation |
self, variation_id |
|
| patch_variation |
self, variation_id, patch |
|
| mark_variation_paid |
self, variation_id |
|
| list_variations |
self, token |
|
| insert_cancellation |
self, row |
|
| insert_dispute |
self, row |
|
| list_disputes |
self, token |
|
packages/payments/src/payments/sandbox.py
| Function |
Arguments |
Purpose |
| _env |
name |
|
| resolve_sandbox |
x_sandbox, x_allow_whatsapp |
FastAPI dependency. Returns a :class:SandboxContext for this request. |
| resolve_for_quote |
quote_is_sandbox, ctx |
If a quote row was created in sandbox mode but the request header wasn't, return a :class:SandboxContext with test keys; otherwise return ctx. |
packages/payments/src/payments/variations.py
packages/payments/src/payments/webhooks.py
packages/scraping/src/scraping/_cdp.py
| Function |
Arguments |
Purpose |
| get_cdp_ws_url |
port |
Discover the CDP WebSocket URL for the given port. |
| fetch_via_cdp |
url |
Three-strategy browser fetch. |
| _run_scrapling |
fetcher, url |
Invoke scrapling.DynamicFetcher with our canonical kwargs. |
| _httpx_fallback |
url |
Last-resort static fetch. Returns "" on any httpx error. |
packages/scraping/src/scraping/browser.py
| Function |
Arguments |
Purpose |
| browser_context |
cookies, user_agent, viewport, headless, storage_state, extra_args |
Async Playwright BrowserContext for multi-page sessions. |
| browser_page |
cookies, user_agent, viewport, headless, auto_dismiss_gdpr, storage_state, extra_args |
Async Playwright Page with sensible defaults. |
| browser_page_sync |
cookies, user_agent, viewport, headless, storage_state, extra_args |
Sync Playwright Page — used by login flows and session refresh scripts that don't live inside an asyncio loop. |
| browser_context_sync |
cookies, user_agent, viewport, headless, locale, storage_state, extra_args |
Sync Playwright BrowserContext for multi-page crawlers. |
| dismiss_gdpr_async |
page, timeout_ms |
Click the first visible GDPR/cookie consent button in :data:GDPR_SELECTORS. Returns True if one was dismissed. |
| dismiss_gdpr |
page, timeout_ms |
Sync analogue of :func:dismiss_gdpr_async. |
| persistent_browser |
|
Attach to an already-running Chrome via CDP — skips the 3-5s cold-start cost of every browser.chromium.launch(). |
packages/scraping/src/scraping/cache.py
| Function |
Arguments |
Purpose |
| _cache_key |
url, strategy |
Deterministic hex key for (url, strategy). |
| cache_path |
url |
Return the HTML path (<dir>/<key>.html) for an entry. |
| _meta_path |
html_path |
|
| _atomic_write_text |
path, content |
Write content to path via a tempfile rename. |
| cached_fetch |
url |
File-based TTL cache around :func:fetch. |
packages/scraping/src/scraping/css.py
| Function |
Arguments |
Purpose |
| _url_from_function |
fn |
Extract the URL from a url(...) FunctionBlock; returns None if dynamic/empty. |
| _url_from_url_token |
tok |
|
| _walk_tokens |
tokens, line_base |
Yield (token, absolute_line, absolute_col). tinycss2 reports 1-indexed source_line/source_column on top-level tokens; for nested FunctionBlock children, the positions are relative to the function itself — we flatten. |
| iter_css_refs |
text |
Return every external reference in a stylesheet text. |
packages/scraping/src/scraping/errors.py
| Function |
Arguments |
Purpose |
| init |
self, url, user_agent |
|
packages/scraping/src/scraping/fetch.py
| Function |
Arguments |
Purpose |
| extend_js_hosts |
hosts |
Add substrings to :data:JS_HOSTS. Idempotent. |
| _is_js_host |
url |
True if any :data:JS_HOSTS entry is a substring of url. |
| fetch_static |
url |
Static httpx fetch. Raises :class:FetchError on upstream failure. |
| fetch_browser |
url |
CDP-first Playwright fetch. Returns "" on total failure. |
| fetch |
url |
Auto-dispatched fetch. Raises :class:RobotsDisallowed on robots denial (when respect_robots=True), otherwise delegates. |
| fetch_many |
urls |
Fan-out fetch with a semaphore-capped concurrency. |
| _one |
url |
|
| extract_text |
url |
Fetch + :func:html_to_text in one call (D9). |
packages/scraping/src/scraping/html.py
| Function |
Arguments |
Purpose |
| is_external_url |
url |
True if url is not a repo-local reference worth resolving. |
| parse_html |
text |
Parse HTML tolerantly. Preserves 1-indexed sourceline on every tag. |
| iter_tags |
parsed, names |
Iterate tags in document order, optionally filtered by tag name(s). |
| tag_attr |
tag, name |
Case-insensitive attribute lookup. Returns None if absent. |
| tag_lineno |
tag |
1-indexed line of the tag's opening bracket (0 if unknown). |
| tag_text |
tag |
Inner text with no markup, whitespace-collapsed. |
| parse_srcset |
value |
Return the URL portion of every candidate in a srcset string. |
packages/scraping/src/scraping/robots.py
| Function |
Arguments |
Purpose |
| init |
self |
|
| _parser_for |
self, host_root |
Fetch + parse robots.txt for host_root (scheme://host). |
| is_allowed |
self, url, user_agent |
Check whether url is allowed for user_agent. |
| crawl_delay |
self, host, user_agent |
Return the declared crawl-delay for host (seconds), or None if robots.txt is silent on the matter. |
| is_allowed |
url, user_agent |
Module-level convenience wrapper over a shared :class:RobotsChecker. |
packages/scraping/src/scraping/soup.py
| Function |
Arguments |
Purpose |
| parse_soup |
html |
Parse html into a :class:bs4.BeautifulSoup tree. |
packages/scraping/src/scraping/text.py
| Function |
Arguments |
Purpose |
| html_to_text |
html |
Return the readable plain text of an HTML document. |
packages/scraping/src/scraping/user_agents.py
| Function |
Arguments |
Purpose |
| pick_user_agent |
|
Return a random UA from the full pool. |
| pick_desktop |
|
Return a random desktop UA. |
| pick_mobile |
|
Return a random mobile UA (use for IG profile HTML, etc.). |
packages/storage/src/storage/embeddings.py
packages/storage/src/storage/semantic.py
| Function |
Arguments |
Purpose |
| _get_api_key |
|
|
| is_mem0_configured |
|
True iff MEM0_API_KEY is set in the environment. |
| _get_client |
|
Lazy-initialize the mem0 client. Returns None on failure. |
| _auth_headers |
|
|
| _normalize_user_id |
user_id |
Stable per-user namespace key. |
| _parse_created_at |
value |
|
| _row_to_memory |
row |
Coerce a raw mem0 API row to a :class:Memory dataclass. |
| _api_get_all |
uid, limit |
Raw v2 API call. The client's get_all is broken in v1.0.7. |
| _api_search |
uid, query, limit |
Raw v2 API call. The client's search is broken in v1.0.7. |
| recall |
user_id, query |
Retrieve memories for a user. |
| remember |
user_id, messages |
Store conversation turns in mem0. The SaaS extracts facts server-side. |
| forget |
user_id, memory_id |
Delete one memory by id. Returns True on success, False otherwise. |
| migrate_user |
old_id, new_id |
Transfer all memories from old_id to new_id. Non-atomic. |
| format_memories_for_prompt |
memories |
Render memories as "Known facts about this user:\n- ..." text. |
| get_user_context |
user_id, current_message |
Convenience: :func:recall + :func:format_memories_for_prompt. |
packages/ui/src/BriefCanvas.tsx
| Function |
Arguments |
Purpose |
| BriefCanvas |
{ b, photos = [] } |
|
packages/ui/src/ChangeOrderCanvas.tsx
packages/ui/src/ChatBubbles.tsx
| Function |
Arguments |
Purpose |
| LeoBubble |
{ text, variant = 'light', className } |
|
| UserBubble |
{ text, variant = 'light', className } |
|
packages/ui/src/ComposerActionStrip.tsx
| Function |
Arguments |
Purpose |
| cx |
parts |
|
| ComposerActionStrip |
{ |
|
| children, |
|
|
| highlight = false, |
|
|
| elevated = false, |
|
|
| innerClassName, |
|
|
| className, |
|
|
| } |
|
|
packages/ui/src/FluidGradient.tsx
| Function |
Arguments |
Purpose |
| loadRuntime |
src |
|
| FluidGradient |
{ |
|
| preset = 'brendan', |
|
|
| paletteKey, |
|
|
| variant = 'v4', |
|
|
| fpsCap = 24, |
|
|
| overrides, |
|
|
| scriptSrc = '/fluid-gradient-v4.js', |
|
|
| skip = false, |
|
|
| className, |
|
|
| style, |
|
|
| ariaLabel, |
|
|
| } |
|
|
packages/ui/src/FullScreenStep.tsx
| Function |
Arguments |
Purpose |
| FullScreenStep |
{ icon, title, subtitle, children, footer } |
|
packages/ui/src/GlassCard.tsx
| Function |
Arguments |
Purpose |
| GlassCard |
{ |
|
| children, |
|
|
| variant = 'dark', |
|
|
| className = '', |
|
|
| style, |
|
|
| padding = 'md', |
|
|
| } |
|
|
packages/ui/src/GlassFrame.tsx
| Function |
Arguments |
Purpose |
| GlassFrame |
{ url, dark = false, children, className } |
|
packages/ui/src/GlassPill.tsx
| Function |
Arguments |
Purpose |
| GlassPill |
{ children, dot = true, className } |
|
packages/ui/src/GradientScreen.tsx
| Function |
Arguments |
Purpose |
| GradientScreen |
{ |
|
| children, |
|
|
| preset = 'homeowner', |
|
|
| style, |
|
|
| className = '', |
|
|
| noise = true, |
|
|
| } |
|
|
packages/ui/src/MapAreaCard.tsx
| Function |
Arguments |
Purpose |
| MapAreaCard |
{ |
|
| mapImageSrc, |
|
|
| mapImageAlt = '', |
|
|
| areaName, |
|
|
| radiusLabel, |
|
|
| showApproxRing = true, |
|
|
| privacyNote, |
|
|
| } |
|
|
packages/ui/src/MaterialsCard.tsx
| Function |
Arguments |
Purpose |
| MaterialsCard |
{ |
|
| cardHolder = 'J. MITCHELL', |
|
|
| cardNumber = '•••• •••• •••• 4821', |
|
|
| showSplit = true, |
|
|
| showPayButtons = true, |
|
|
| className = '' |
|
|
| } |
|
|
packages/ui/src/MilestoneList.tsx
| Function |
Arguments |
Purpose |
| MilestoneList |
{ milestones, gradientBg = false, gradientSrc } |
Escrow milestone list — "Your money doesn't move until you're happy." |
| Function |
Arguments |
Purpose |
| AppleLogo |
{ size = 16, fill = 'currentColor' } |
PayButton — Apple Pay and Google Pay standard buttons. |
| GoogleGLogo |
{ size = 16 } |
|
| ApplePayButton |
{ variant = 'pill', onClick } |
Apple Pay button. Logo-only (no "Apple" text). "Pay" uses -apple-system (San Francisco) per Apple HIG. |
| GooglePayButton |
{ variant = 'pill', onClick } |
Google Pay button. Google G logo (4-color) + "Pay" in Google Sans. No "Google" text. Google Sans loaded from fonts.gstatic.com (no extra font import needed in static pages that already load brand fonts; React app imports via index.css or ComponentLibrary). |
| Function |
Arguments |
Purpose |
| PlatformLogo |
{ |
|
| platform, |
|
|
| size = 'md', |
|
|
| variant = 'inline', |
|
|
| className |
|
|
| } |
|
|
packages/ui/src/ProfileCanvas.tsx
| Function |
Arguments |
Purpose |
| Stars |
{ rating, size = 12 } |
|
| PhotoViewer |
{ url, onClose } |
|
| BackBar |
{ label, onBack } |
|
| ProfileCanvas |
{ p } |
|
| ProfileView |
{ |
|
| p, |
|
|
| onOpenReviews, |
|
|
| onOpenProject, |
|
|
| onOpenMentions, |
|
|
| onViewPhoto, |
|
|
| } |
|
|
| PlatformReviewCard |
{ source, onTap } |
|
| sourcePill |
source_name |
|
| SocialMentionCard |
{ mention, onTap } |
|
| SocialMentionDetailView |
{ |
|
| mentions, |
|
|
| onBack, |
|
|
| } |
|
|
| PortfolioThumb |
{ project, onTap } |
|
| ReviewsView |
{ source, onBack } |
|
| ProjectView |
{ |
|
| project, |
|
|
| onBack, |
|
|
| onViewPhoto, |
|
|
| } |
|
|
packages/ui/src/QuoteCanvas.tsx
| Function |
Arguments |
Purpose |
| QuoteCanvas |
{ scope: rawScope } |
ScopeCanvas — the Leo quote document. |
| fmtEur |
n |
|
packages/ui/src/ShopMap.tsx
| Function |
Arguments |
Purpose |
| ShopMap |
{ |
|
| accessToken, |
|
|
| points, |
|
|
| onSelect, |
|
|
| center, |
|
|
| height = '100%', |
|
|
| className, |
|
|
| pinClassName = 'scope-shop-map-pin', |
|
|
| } |
|
|
packages/ui/src/StatusBadge.tsx
| Function |
Arguments |
Purpose |
| StatusBadge |
{ status, className = '' } |
|
packages/ui/src/ThemeProvider.tsx
| Function |
Arguments |
Purpose |
| ThemeProvider |
{ |
|
| children, |
|
|
| defaultTheme = 'light', |
|
|
| storageKey = STORAGE_KEY, |
|
|
| element = 'html', |
|
|
| } |
|
|
| setTheme |
next |
|
| useTheme |
|
|
packages/ui/src/VoiceNoteBubble.tsx
| Function |
Arguments |
Purpose |
| fmtDuration |
seconds |
|
| PlayIcon |
|
Play icon: bare rounded triangle (no circle wrapper). Uses SVG path with rounded stroke-linejoin for slightly soft corners. |
| PauseIcon |
|
Pause icon: two rounded bars |
| VoiceNoteBubble |
{ durationSec, waveform, transcript, audioUrl } |
Terra terracotta bubble: play button + waveform bars + duration + italic transcript. |
packages/ui/src/primitives/Badge.tsx
| Function |
Arguments |
Purpose |
| Badge |
{ variant = 'pill', color = 'ink', dot = true, children, className } |
|
packages/ui/src/primitives/Sheet.tsx
| Function |
Arguments |
Purpose |
| Sheet |
{ open, onClose, children, maxHeight = '90dvh', showHandle = true, title, footer } |
|
packages/voice/src/voice/audio.py
| Function |
Arguments |
Purpose |
| ext_for_content_type |
content_type |
Return a filename extension for an audio MIME type. |
| _run_ffmpeg |
src_path, dst_path |
Invoke ffmpeg to convert src_path to dst_path at the given sample rate / channel count. Raises :class:RuntimeError on non-zero exit. |
| to_wav |
audio |
Convert audio bytes to WAV on disk, return the Path. |
| wav_tempfile |
audio |
Context-manager version of :func:to_wav with guaranteed cleanup. |
packages/voice/src/voice/config.py
packages/voice/src/voice/detect.py
| Function |
Arguments |
Purpose |
| detect_language |
text |
Return an ISO-639-1 code for text. |
packages/voice/src/voice/logging.py
packages/voice/src/voice/pipeline.py
| Function |
Arguments |
Purpose |
| transcribe |
audio |
Transcribe audio bytes to text. |
packages/voice/src/voice/polish.py
| Function |
Arguments |
Purpose |
| polish_sync |
raw |
Return lightly-edited transcript from the polish model. |
| polish |
raw |
Async counterpart to :func:polish_sync. |
packages/voice/src/voice/resilience.py
packages/voice/src/voice/stt/init.py
packages/voice/src/voice/stt/deepgram.py
packages/voice/src/voice/stt/groq.py
packages/voice/src/voice/stt/huggingface.py
packages/voice/src/voice/stt/local.py
packages/voice/src/voice/tts/init.py
| Function |
Arguments |
Purpose |
| synthesize |
self, text |
Synthesize text into audio bytes. |
| synthesize |
text |
Synthesize text to audio. Phase 3.5b stub — raises NotImplementedError. |
| list_voices |
language |
Return registered canonical voices, optionally filtered by language. |
packages/voice/src/voice/tts/elevenlabs.py
packages/voice/src/voice/tts/polly.py
Source document ↗