Add fail-closed AI web research discovery provider
CI / compose (push) Successful in 10m53s

This commit is contained in:
Marco0300
2026-09-03 20:32:33 +02:00
parent bf5b54679a
commit da91c188f3
7 changed files with 235 additions and 10 deletions
+23
View File
@@ -16,6 +16,29 @@ Set `PROSPECT_API_PORT` or pass `--port`; set `PROSPECT_API_DB` or pass `--db` t
## Endpoint contract
### Criteria-first AI web research
`POST /api/v1/discovery` with `criteria` and no `seed_urls` uses the optional,
fail-closed AI research provider. It sends bounded criteria to the configured
approved browsing provider and accepts only a bounded list of HTTPS URL targets;
the server then fetches those targets through the existing SSRF-safe crawler.
Only fetched-page evidence is persisted. Provider claims, summaries, prompts,
and contact data are never persisted as discovery evidence. Explicit `seed_urls`
remain the controlled, operator-supplied mode.
The provider status is available at authenticated `GET
/api/v1/discovery/ai-provider-status` (the older
`/api/v1/discovery/provider-status` alias is retained). Configure only on the
server with `AI_RESEARCH_PROVIDER` (`openai_web_search`, `anthropic_web_search`,
or `google_web_search`), `AI_RESEARCH_PROVIDER_MODEL`,
`AI_RESEARCH_PROVIDER_URL` (HTTPS), `AI_RESEARCH_PROVIDER_ALLOWED_HOSTS`
(exact hostname allowlist), and `AI_RESEARCH_PROVIDER_API_KEY`. Requests have an
8-second timeout, 64 KiB response limit, 8 KiB criteria limit, and 50-target
maximum. Missing credentials, unapproved providers, unsafe endpoints, malformed
responses, prompt-injection-shaped criteria, and unsafe URLs fail closed.
`SEARCH_PROVIDER_*` is a deprecated migration adapter only and is not the
primary AI workflow.
All protected endpoints require the server-side session cookie. Every query is constrained by the authenticated user's `organization_id`; IDs from another tenant behave as not found and must not disclose whether a record exists.
Phase 7 domain routes (all tenant-scoped) are `POST /api/v1/businesses/{id}/domains/check`, `GET /api/v1/businesses/{id}/domains/check?domain=...`, `GET /api/v1/domain-checks`, `GET /api/v1/businesses/{id}/domain-candidates`, and `POST /api/v1/businesses/{id}/domain-candidates/check-availability`. The current implementation is intentionally conservative: a successful address lookup is reported as `ok`, unresolved/empty results as `unknown`, and an availability check returns `unknown`/`not_configured` because no provider is enabled. Treat these as observation states, not ownership or availability claims.