# Knowledge Base Management

## Correct Workflow

**CRITICAL**: `knowledge_base_id` can ONLY be set at agent creation time. `update_agent` silently ignores this field. Always create the KB BEFORE the agent.

1. **`create_knowledge_base(name=...)`** — Creates an empty KB, returns a `dataset_id` UUID.
2. **Import content** using the real `dataset_id`:
   - `import_knowledge_from_website(dataset_id=<uuid>, url=...)` — BFS crawl (recommended)
   - `import_knowledge_from_url(dataset_id=<uuid>, title=..., urls=[...])` — specific pages
3. **`create_agent(name=..., knowledge_base_id=<uuid>)`** — Create the agent WITH the KB. This is the only time KB can be linked.

**CRITICAL**: Do NOT use `dataset_id=new` — it's not a valid UUID and will cause 500 errors.

**NOTE**: The backend expects the create request wrapped as `{"kb_data": {...}}`. The gateway client handles this automatically.

## Import Strategies

### Website Crawl — RECOMMENDED (Most Reliable)
```
create_knowledge_base(name="Company KB") → dataset_id
import_knowledge_from_website(dataset_id=<uuid>, url="https://docs.example.com", max_pages=50)
```
- BFS crawl from the root URL
- Returns immediately with a `job_id`; crawling happens async in background
- Best for structured sites with internal links

### URL Import — MAY FAIL (Root Cause Known)
```
import_knowledge_from_url(dataset_id=<uuid>, title="FAQ Pages", urls=["https://example.com/faq"])
```
- May return 500 with "Failed to import document: Expecting value: line 1 column 1 (char 0)"
- **Root cause**: The RAG service calls Dify's `/datasets/{id}/documents` API but does NOT check `response.status_code` before calling `.json()`. When Dify returns a non-JSON error, parsing fails.
- **Underlying Dify failure**: Usually because the tenant lacks `jinareader` API credentials.
- Does NOT work with: Google Sheets, Google Docs, pages behind auth, SPAs

### There Is NO Text Document Creation Endpoint
The `POST /knowledge-bases/{id}/documents` endpoint is Dify's internal document upload API requiring `{tenant_id, urls, job_id, size}`. It is NOT for creating text documents from raw content. If you need to add curated text content, use annotations (`create_annotation`) instead.

## Import Status Checking

`get_import_status` may return 500 for BFS crawl jobs:
- **Root cause**: RAG's `check_crawl_status()` hardcodes `provider=jinareader` in the Dify status URL. Dify rejects it if the tenant has no jinareader credentials.
- **Workaround**: Don't poll status. Start the crawl, do other work, verify later by listing documents.

## Fallback: Use Annotations

When imports fail or for critical Q&A pairs:
- `create_annotation(agent_id, title, questions=[...], answer="...")` — works immediately, no KB needed
- Annotations take priority over KB retrieval for matching questions
- Best for: fee guardrails, competitor deflections, exact verified facts, location redirects

## Google Sheets / Docs Data

Google Sheets and Docs URLs **cannot be imported** via any endpoint (auth required, dynamic content). Ask the user to export as text, then use annotations to add the content.
