# AI Search Grounded Answers

This module guide covers the PR12 grounded Ask AI slice layered on top of the existing semantic indexing and retrieval stack.

For the cross-cutting AI Search architecture, rollout gates, and risk controls,
start with [AI Search Architecture](./AI_SEARCH_ARCHITECTURE.md).

## Files

- `src/app/api/search/ask/route.ts`.
- `src/lib/search/ai/retrieval/http.ts`.
- `src/lib/search/ai/retrieval/grounded-answer-service.ts`.
- `src/lib/search/ai/retrieval/openai-grounded-answer.ts`.
- `src/lib/search/ai/retrieval/index-coverage.ts`.
- `src/hooks/useAskAi.ts`.
- `src/components/search/AskAiCard.tsx`.
- `src/hooks/useAiSearchAvailability.ts`.
- `src/hooks/useAiSearchUiState.ts`.

## Public Contract

`POST /api/search/ask`

Request body:

```json
{
  "question": "What do the indexed design docs say about citations?",
  "services": ["google"],
  "accountIds": ["google-account-1"]
}
```

Response envelope data:

```json
{
  "status": "answered",
  "answer": "Grounded answer text",
  "citations": [
    {
      "resourceId": "file-1",
      "resourceName": "Design Doc",
      "service": "google",
      "accountId": "google-account-1",
      "accountLabel": "user@example.com (Business)",
      "snippet": "Grounded evidence excerpt"
    }
  ],
  "citationCount": 1,
  "grounded": true,
  "indexCoverage": "partial",
  "reason": null
}
```

Safe no-answer responses use:

- `status: "no_answer"`.
- `answer: null`.
- `citations: []`.
- `grounded: false`.
- a human-readable `reason`.

## Scope Rules

- Ask AI is always scoped by `userId`.
- Ask AI also enforces canonical `service` and `accountId` filters from the current UI scope.
- Unsupported or foreign account ids are rejected at the route boundary.
- The UI does not surface provider-native ids or backend-native vector metadata.

## Availability and Rollout

Ask AI is shown only when all of the following are true:

- the user can access AI search through the existing subscription gate.
- `AI_SEARCH_ENABLED=true`.
- `AI_RAG_ENABLED=true`.
- embeddings are configured.
- the semantic index backend is configured.
- grounded answer generation is configured.
- at least one in-scope Google Drive, OneDrive, or Dropbox account is eligible.
- `AI_RAG_TIMEOUT_MS` is set to a sane internal rollout value so slow generations abort cleanly.

`/api/search/availability` now returns a separate `ask` capability alongside `search` and `indexing`.

## Safety Model

- The answer generator only sees retrieved indexed excerpts.
- Successful answers always include citations.
- If retrieval quality is insufficient, the service returns `no_answer`.
- If embeddings, semantic retrieval, or answer generation are unavailable, the service returns `no_answer`.
- Citation cards never render raw provider/account ids; they use a readable account label when connected-account metadata provides one.
- Slow or hung answer-generation requests are aborted at `AI_RAG_TIMEOUT_MS` and return the same safe `no_answer` path.
- Callers must not rewrite `no_answer` into a conversational fallback.

## Current Limitations

- Ask AI currently scopes to user/service/account filters, not full folder-subtree semantics.
- Citation cards intentionally stay canonical and compact; they do not expose raw vector ids or backend chunk internals.
- Indexing execution is still the current best-effort in-process runner, so rollout should remain conservative until a more durable worker path exists.
- Rollout remains phased: internal indexing first, internal semantic search second, and Ask AI only after internal validation confirms search and citation quality.
