# Next Session: Fix SearXNG Binding for Phone Web Search

## What

Annie's phone loop on Panda can't reach SearXNG on Titan because it's bound to `127.0.0.1:8888` (localhost only). When Rajesh asks Annie to search something during a phone call, the tool call dispatches correctly but `search_web()` gets "All connection attempts failed."

## Root Cause

`services/annie-voice/docker-compose.yml:36` binds SearXNG to localhost:
```yaml
ports:
  - "127.0.0.1:8888:8080"  # Localhost only — not exposed externally
```

The phone loop runs on Panda (192.168.68.57), which calls `search_web()` from `phone_tools.py:299`. This imports `search_web` from `tools.py:40`, which uses `SEARXNG_BASE_URL` defaulting to `http://localhost:8888`. On Panda, "localhost" is Panda itself — not Titan.

## Two Problems to Fix

### Problem 1: SearXNG Docker binding (Titan-side)

Change the port binding so SearXNG is reachable from the LAN (Panda):

**File:** `services/annie-voice/docker-compose.yml:36`
- **Current:** `"127.0.0.1:8888:8080"` 
- **Option A (simple):** `"0.0.0.0:8888:8080"` — binds to all interfaces
- **Option B (safer):** `"192.168.68.52:8888:8080"` — binds only to Titan's LAN IP

Option B is safer (no exposure on other interfaces). But Option A is simpler and the LAN is trusted (home network, behind ASUS router).

**Security consideration:** SearXNG has no auth by default. Binding to LAN means anyone on the network can use it. This is fine for a home network but document the decision.

### Problem 2: SEARXNG_BASE_URL env var (Panda-side)

The phone loop on Panda needs to know SearXNG's address on Titan.

**File:** `start.sh` (Panda phone launcher, line ~800)
- Add: `SEARXNG_BASE_URL='http://192.168.68.52:8888'`

**Also add to** Panda's `~/.her-os/.env`:
```
SEARXNG_BASE_URL=http://192.168.68.52:8888
```

The `search_web()` function in `tools.py:26` already reads this env var:
```python
SEARXNG_BASE_URL = os.getenv("SEARXNG_BASE_URL", "http://localhost:8888")
```

So no code changes needed in `tools.py` or `phone_tools.py`.

## Implementation Steps

1. Edit `services/annie-voice/docker-compose.yml:36` — change binding
2. Edit `start.sh` Panda launcher (~line 800) — add `SEARXNG_BASE_URL` env var
3. SSH Panda: add `SEARXNG_BASE_URL=http://192.168.68.52:8888` to `~/.her-os/.env`
4. Restart SearXNG: `./stop.sh searxng && ./start.sh searxng`
5. Restart Panda phone: `./stop.sh panda && ./start.sh panda`
6. Verify from Panda: `ssh panda "curl -s 'http://192.168.68.52:8888/search?q=test&format=json' | head -c 200"`
7. Call Annie on Pixel, ask for RCB score — should get web search results

## Files to Modify

| File | Change | Lines |
|------|--------|-------|
| `services/annie-voice/docker-compose.yml` | Port binding: `127.0.0.1` → `0.0.0.0` or Titan IP | 1 line |
| `start.sh` | Add `SEARXNG_BASE_URL` to Panda launcher env | 1 line |
| Panda `~/.her-os/.env` | Add `SEARXNG_BASE_URL` (SSH) | 1 line |

**Total: 2 file edits + 1 SSH command. ~5 minutes.**

## Verification

1. From Panda: `curl -s 'http://192.168.68.52:8888/search?q=hello&format=json' | python3 -c "import sys,json; print(json.load(sys.stdin)['results'][0]['title'])"` — should return a result
2. Phone call test: ask Annie "What's the RCB score?" — she should answer with actual search results instead of "trouble connecting"

## Context

- Discovered during Gemma 4 swap (session 434) — Rajesh called Annie asking for RCB IPL cricket score
- Gemma 4 correctly dispatched `web_search({'query': 'latest RCB IPL score'})` but SearXNG was unreachable from Panda
- The Annie Voice pipeline (WebRTC on Titan) works fine because it calls SearXNG on localhost
- Only the phone loop (on Panda) is affected
