> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vrin.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Querying

> Query the knowledge base with full-text answers or raw facts

## query()

Query the knowledge base with natural language. Returns either a complete result dict or a streaming response.

```python theme={null}
result = client.query("What is ACME's revenue?")
print(result["summary"])
```

### Parameters

<ParamField body="query" type="string" required>
  Natural-language question to answer.
</ParamField>

<ParamField body="stream" type="bool" default="False">
  If `True`, return a [`StreamingResponse`](/sdk/streaming) that yields tokens as they arrive.
</ParamField>

<ParamField body="response_mode" type="string" default="chat">
  Controls answer depth and reasoning style.

  | Mode         | Description                                                      |
  | ------------ | ---------------------------------------------------------------- |
  | `"chat"`     | Concise, direct answers. Fastest.                                |
  | `"thinking"` | Includes reasoning chains and cross-document analysis.           |
  | `"research"` | Exhaustive multi-hop research with parallel strategies. Slowest. |
</ParamField>

<ParamField body="query_depth" type="string">
  Override the retrieval depth independently of response mode. Values: `"basic"`, `"thinking"`, `"research"`.
</ParamField>

<ParamField body="model" type="string">
  LLM model override (e.g. `"gpt-4o"`). Uses the default cost-efficient model if not specified.
</ParamField>

<ParamField body="session_id" type="string">
  Explicit conversation session ID to continue. Use this or `maintain_context`, not both.
</ParamField>

<ParamField body="maintain_context" type="bool" default="False">
  If `True`, maintain conversation state across queries. The client tracks the session ID automatically.
</ParamField>

<ParamField body="include_summary" type="bool" default="True">
  If `True`, include the AI-generated summary. Set to `False` for raw fact retrieval.
</ParamField>

<ParamField body="web_search_enabled" type="bool" default="False">
  Enable web search augmentation for questions that may need external information.
</ParamField>

<ParamField body="conversation_upload_ids" type="List[str]">
  List of upload IDs to include as additional context for this query.
</ParamField>

### Non-streaming response

```python theme={null}
result = client.query("What is ACME's revenue?")
```

Returns a dict with:

```json theme={null}
{
  "success": true,
  "summary": "ACME Corp reported $50M revenue in Q4 2025...",
  "session_id": "sess_abc123",
  "total_facts": 12,
  "total_chunks": 5,
  "metadata": {
    "entities": ["ACME Corp"],
    "model": "gpt-4o-mini",
    "search_time": "1.2s"
  }
}
```

### Streaming response

```python theme={null}
resp = client.query("Summarize Q4 results", stream=True)
for token in resp:
    print(token, end="", flush=True)

# Metadata available after iteration
print(resp.total_facts)
print(resp.sources)
```

See [StreamingResponse](/sdk/streaming) for all available properties.

### Response modes

```python theme={null}
# Fast, concise answer
result = client.query("Who is ACME's CEO?", response_mode="chat")

# Reasoning chains included
result = client.query(
    "Why did revenue decline in Q3?",
    response_mode="thinking"
)

# Exhaustive multi-hop research
result = client.query(
    "Compare ACME and Widget Corp's growth trajectories",
    response_mode="research"
)
```

## query\_facts()

Fast fact retrieval without AI summary generation. Returns the same dict structure but with raw graph facts and vector chunks only.

```python theme={null}
facts = client.query_facts("ACME revenue")
```

### Parameters

<ParamField body="query" type="string" required>
  Natural-language question.
</ParamField>

<ParamField body="max_results" type="int" default="10">
  Maximum number of results to return.
</ParamField>

### Returns

Same dict structure as `query()` but `summary` will be empty or minimal since no LLM generation occurs.

## Insufficient coverage

When the knowledge base has zero relevant facts for a query, Vrin returns early without calling the LLM:

```python theme={null}
result = client.query("What is the weather on Mars?")
if result.get("insufficient_coverage"):
    print("No relevant knowledge found for this query")
```

In streaming mode, check `resp.insufficient_coverage` after iteration completes.
