# DeepSeek API Quirks

Observed behavior of `deepseek/deepseek-v4-flash` (and likely other DeepSeek V4 models) when used as an OpenAI-compatible provider.

## Reasoning Mode Eats Token Budget

When `reasoning_config: {enabled: true}` is set (Hermes default), DeepSeek uses reasoning tokens that count against `max_tokens`. A response with 3000 chars of reasoning + 50 chars of answer needs `max_tokens > 3050`. If `max_tokens` is too low, the model runs out before producing visible content.

**Fix:** Either disable reasoning or set `max_tokens` generously (at least 300 for simple tasks, 800+ for classification).

## Empty `content` in Response

When reasoning is enabled and `max_tokens` is exhausted, the API returns:
```json
{
  "message": {
    "role": "assistant",
    "content": "",
    "reasoning_content": "..."  // reasoning consumed all tokens
  },
  "finish_reason": "length"
}
```

Code reading `message["content"]` gets `""` — which looks like the model refused to answer, but it actually just ran out of budget.

## Reasoning Config Placement

DeepSeek accepts `reasoning_config` as a **top-level key** in the request body, NOT inside `extra_body`:

```python
payload = {
    "model": "deepseek-v4-flash",
    "messages": [...],
    "max_tokens": 300,
    "reasoning_config": {"enabled": False}   # ✅ top-level
}
```

Putting it inside `extra_body` is silently ignored.

## JSON Mode + Reasoning

`response_format: {type: "json_object"}` works fine with DeepSeek even with reasoning disabled. Tested with `max_tokens=400` on classification tasks (judging session relationships). When reasoning IS enabled, JSON mode may produce empty content on complex prompts — disable reasoning for any `json_mode=True` call.

**Critical: prompt must contain the word "json".** DeepSeek enforces a guard: if `response_format: {type: "json_object"}` is in the request but the prompt text does NOT contain the word "json" (case-insensitive), the API returns a 400 error:
```
Prompt must contain the word 'json' in some form to use 'response_format' of type 'json_object'.
```
The system/instruction prompt's mention of "JSON" satisfies this — the word must appear somewhere in the concatenated messages, not necessarily in every segment.

## `.bashrc` Env Var Guard

Standard Debian `.bashrc` has a non-interactive guard on lines 5-9:
```bash
case $- in
    *i*) ;;
      *) return;;
esac
```

This skips all exports on line 133+ (including `DEEPSEEK_API_KEY`) in non-interactive shells (`bash -c`, `python3 subprocess`, etc.). **Never rely on `.bashrc` for API keys.** Always use `~/.hermes/.env` which has no guard.

## Quick Test Snippet

```python
import requests, os
key = os.environ["DEEPSEEK_API_KEY"]
headers = {"Authorization": f"Bearer {key}"}
r = requests.post(
    "https://api.deepseek.com/v1/chat/completions",
    json={
        "model": "deepseek-v4-flash",
        "messages": [{"role": "user", "content": "say hi"}],
        "max_tokens": 10,
        "reasoning_config": {"enabled": False},
    },
    headers=headers,
    timeout=15,
)
print(r.status_code, r.json()["choices"][0]["message"]["content"])
```
