mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
## Description Clarifies the recommended install path for the Headroom CLI on macOS Apple Silicon and Linux. The docs now prefer `uv tool install --python 3.13 "headroom-ai[all]"` for host-level CLI use, keep `pip install` scoped to Python project environments, and call out absolute executable paths for MCP clients that do not inherit interactive shell `PATH`. ## Type of Change - [ ] Bug fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [x] Documentation update - [ ] Performance improvement - [ ] Code refactoring (no functional changes) ## Changes Made - Added `uv tool install --python 3.13` guidance to the README, docs install page, quickstarts, and wiki install pages. - Documented `uv tool update-shell` for shells that cannot find the installed `headroom` command. - Clarified absolute MCP server command paths for clients that do not inherit the interactive shell `PATH`. - Pointed Intel macOS users at the Docker-native install path until native wheel support lands. ## Testing Describe the tests you ran to verify your changes: - [ ] Unit tests pass (`pytest`) - not run; docs-only change. - [ ] Linting passes (`ruff check .`) - not run; docs-only change. - [ ] Type checking passes (`mypy headroom`) - not run; docs-only change. - [ ] New tests added for new functionality - not applicable. - [x] Manual testing performed - [x] `git diff --check upstream/main...HEAD` ## Real Behavior Proof ```bash $ git diff --check upstream/main...HEAD # exits 0; no whitespace errors ``` `npm --prefix docs run types:check` was also attempted. It regenerated MDX and route types successfully, then failed in existing docs app code because `@/lib/...` imports cannot resolve from files such as `app/(home)/layout.tsx`, `app/api/search/route.ts`, and `components/button.tsx`. This PR only changes `README.md`, `docs/content/docs/installation.mdx`, `docs/content/docs/quickstart.mdx`, and `wiki/*.md` files. ## Review Readiness - [x] Draft PR; docs wording and install-path accuracy are ready for review. - [x] No code or runtime files changed. - [x] Known docs type-check blocker is documented above. ## Test Output ```bash $ git diff --check upstream/main...HEAD # no output ``` ```text $ npm --prefix docs run types:check [MDX] generated files ✓ Types generated successfully app/(home)/layout.tsx(2,29): error TS2307: Cannot find module @/lib/layout.shared or its corresponding type declarations. ... components/button.tsx(4,20): error TS2307: Cannot find module @/lib/cn or its corresponding type declarations. ``` ## Checklist - [x] My code follows the project's style guidelines - [x] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - not applicable; docs-only change. - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - not applicable; docs-only change. - [ ] New and existing unit tests pass locally with my changes - not run; docs-only change. - [ ] I have updated the CHANGELOG.md if applicable - not applicable. ## Screenshots (if applicable) Not applicable. ## Additional Notes The PR remains a draft while docs verification is limited by the existing docs app `@/lib/*` resolution issue. --------- Co-authored-by: JerrettDavis <mxjerrett@gmail.com>
718 lines
16 KiB
Markdown
718 lines
16 KiB
Markdown
# macOS Deployment Guide
|
|
|
|
This guide covers deploying the headroom proxy server as a background service on macOS using LaunchAgent. The service will start automatically on login and restart on crash.
|
|
|
|
## Overview
|
|
|
|
macOS LaunchAgent provides a native way to run background services with:
|
|
|
|
- **Automatic startup** on user login
|
|
- **Crash recovery** with automatic restart
|
|
- **Standard logging** to `~/Library/Logs/`
|
|
- **Native lifecycle management** via `launchctl`
|
|
|
|
This is ideal for local development environments where you want "set and forget" proxy configuration.
|
|
|
|
## Prerequisites
|
|
|
|
- macOS 10.13+ (High Sierra or later)
|
|
- headroom-ai installed with proxy support
|
|
- Anthropic API key configured
|
|
|
|
### Installing Headroom with Proxy Support
|
|
|
|
```bash
|
|
# Install the host CLI with proxy support
|
|
uv tool install --python 3.13 "headroom-ai[proxy]"
|
|
|
|
# If your shell cannot find `headroom` after installation
|
|
uv tool update-shell
|
|
|
|
# Verify installation
|
|
headroom proxy --help
|
|
```
|
|
|
|
On macOS with Homebrew, `python3` may point at a newer interpreter than the
|
|
current Headroom wheel set. Passing `--python 3.13` keeps the CLI install on a
|
|
wheel-supported interpreter. If Python 3.13 is missing, install it first:
|
|
|
|
```bash
|
|
brew install python@3.13
|
|
```
|
|
|
|
### API Key Configuration
|
|
|
|
Your Anthropic API key can be configured in several ways:
|
|
|
|
**Option 1: Shell environment (recommended)**
|
|
|
|
```bash
|
|
# Add to ~/.bashrc or ~/.zshrc
|
|
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
```
|
|
|
|
**Option 2: LaunchAgent plist**
|
|
|
|
```xml
|
|
<key>EnvironmentVariables</key>
|
|
<dict>
|
|
<key>ANTHROPIC_API_KEY</key>
|
|
<string>sk-ant-...</string>
|
|
</dict>
|
|
```
|
|
|
|
**Option 3: System environment**
|
|
|
|
```bash
|
|
# Add to /etc/launchd.conf (requires admin)
|
|
setenv ANTHROPIC_API_KEY sk-ant-...
|
|
```
|
|
|
|
## Quick Install
|
|
|
|
The automated installer handles all setup:
|
|
|
|
```bash
|
|
# Clone or navigate to headroom repository
|
|
cd examples/deployment/macos-launchagent
|
|
|
|
# Run installer
|
|
./install.sh
|
|
```
|
|
|
|
The installer will:
|
|
|
|
1. Detect your headroom installation
|
|
2. Prompt for port configuration (default: 8787)
|
|
3. Create log directory
|
|
4. Generate LaunchAgent plist
|
|
5. Load and start the service
|
|
6. Verify service is running
|
|
|
|
### Installation Options
|
|
|
|
**Custom port:**
|
|
|
|
```bash
|
|
./install.sh --port 9000
|
|
```
|
|
|
|
**Unattended install (no prompts):**
|
|
|
|
```bash
|
|
./install.sh --port 8787 --unattended
|
|
```
|
|
|
|
**Reinstall over existing:**
|
|
|
|
```bash
|
|
# Installer will prompt to reinstall if service exists
|
|
./install.sh
|
|
```
|
|
|
|
## Manual Installation
|
|
|
|
If you prefer full control over the installation:
|
|
|
|
### Step 1: Create Log Directory
|
|
|
|
```bash
|
|
mkdir -p ~/Library/Logs/headroom
|
|
```
|
|
|
|
### Step 2: Generate LaunchAgent Plist
|
|
|
|
Copy and customize the template:
|
|
|
|
```bash
|
|
cd examples/deployment/macos-launchagent
|
|
cp com.headroom.proxy.plist.template ~/Library/LaunchAgents/com.headroom.proxy.plist
|
|
```
|
|
|
|
Edit `~/Library/LaunchAgents/com.headroom.proxy.plist`:
|
|
|
|
1. Replace `__HEADROOM_PATH__` with your headroom path:
|
|
|
|
```bash
|
|
command -v headroom
|
|
# Example output: /usr/local/bin/headroom
|
|
```
|
|
|
|
2. Replace `__PORT__` with your desired port (e.g., `8787`)
|
|
|
|
3. Replace `__HOME__` with your home directory:
|
|
|
|
```bash
|
|
echo $HOME
|
|
# Example output: /Users/yourusername
|
|
```
|
|
|
|
### Step 3: Load the LaunchAgent
|
|
|
|
```bash
|
|
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.headroom.proxy.plist
|
|
```
|
|
|
|
### Step 4: Verify Service
|
|
|
|
```bash
|
|
# Check if service is running
|
|
launchctl print gui/$(id -u)/com.headroom.proxy
|
|
|
|
# Check if port is listening
|
|
lsof -iTCP:8787 -sTCP:LISTEN
|
|
|
|
# Test health endpoint
|
|
curl http://localhost:8787/health
|
|
```
|
|
|
|
## Configuration
|
|
|
|
### Port Customization
|
|
|
|
The default port is 8787. To use a custom port:
|
|
|
|
**During installation:**
|
|
|
|
```bash
|
|
./install.sh --port 9000
|
|
```
|
|
|
|
**After installation:**
|
|
|
|
1. Uninstall: `./uninstall.sh`
|
|
2. Reinstall with new port: `./install.sh --port 9000`
|
|
3. Update shell integration: `export HEADROOM_PORT=9000`
|
|
|
|
### Log Location
|
|
|
|
Logs are written to standard macOS locations:
|
|
|
|
- **Standard output**: `~/Library/Logs/headroom/proxy.log`
|
|
- **Error output**: `~/Library/Logs/headroom/proxy-error.log`
|
|
|
|
To change log locations, edit the plist:
|
|
|
|
```xml
|
|
<key>StandardOutPath</key>
|
|
<string>/custom/path/proxy.log</string>
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
Configure additional options in the plist `EnvironmentVariables` section:
|
|
|
|
```xml
|
|
<key>EnvironmentVariables</key>
|
|
<dict>
|
|
<!-- Required: Proxy port -->
|
|
<key>HEADROOM_PORT</key>
|
|
<string>8787</string>
|
|
|
|
<!-- Optional: API key (or set in shell) -->
|
|
<key>ANTHROPIC_API_KEY</key>
|
|
<string>sk-ant-...</string>
|
|
|
|
</dict>
|
|
```
|
|
|
|
**Note:** The earlier LLMLingua-2 launch-agent variables
|
|
(`HEADROOM_COMPRESSION_PROVIDER=llmlingua`, `HEADROOM_LLMLINGUA_DEVICE`,
|
|
the `headroom-ai[llmlingua]` extra) were retired with the
|
|
`--llmlingua` flag. For ML compression today, install the `[ml]`
|
|
extra and follow `wiki/transforms.md`.
|
|
|
|
### Crash Recovery
|
|
|
|
The LaunchAgent is configured with:
|
|
|
|
- **KeepAlive**: Automatically restarts on crash
|
|
- **ThrottleInterval**: 10 seconds between restart attempts
|
|
|
|
To disable automatic restart, edit the plist:
|
|
|
|
```xml
|
|
<key>KeepAlive</key>
|
|
<false/>
|
|
```
|
|
|
|
## Shell Integration
|
|
|
|
Automatically configure your shell to use the proxy when available.
|
|
|
|
### Setup
|
|
|
|
Add to `~/.bashrc` (bash) or `~/.zshrc` (zsh):
|
|
|
|
```bash
|
|
# Configure port (optional, defaults to 8787)
|
|
export HEADROOM_PORT=8787
|
|
|
|
# Source shell integration
|
|
source /path/to/headroom/examples/deployment/macos-launchagent/shell-integration.sh
|
|
```
|
|
|
|
### What It Does
|
|
|
|
The shell integration script:
|
|
|
|
1. Checks if proxy is running on configured port
|
|
2. If running, sets `ANTHROPIC_BASE_URL=http://localhost:8787`
|
|
3. If not running, attempts to start the LaunchAgent
|
|
4. Provides status messages on first load
|
|
|
|
This makes Claude clients automatically use the proxy without manual configuration.
|
|
|
|
### Manual Configuration
|
|
|
|
If you prefer not to use shell integration:
|
|
|
|
```bash
|
|
# Add to ~/.bashrc or ~/.zshrc
|
|
export ANTHROPIC_BASE_URL=http://localhost:8787
|
|
```
|
|
|
|
## Service Management
|
|
|
|
### Check Status
|
|
|
|
```bash
|
|
# View service status
|
|
launchctl print gui/$(id -u)/com.headroom.proxy
|
|
|
|
# Check if port is listening
|
|
lsof -iTCP:8787 -sTCP:LISTEN
|
|
|
|
# Test health endpoint
|
|
curl http://localhost:8787/health
|
|
```
|
|
|
|
### View Logs
|
|
|
|
```bash
|
|
# Tail standard output
|
|
tail -f ~/Library/Logs/headroom/proxy.log
|
|
|
|
# Tail error output
|
|
tail -f ~/Library/Logs/headroom/proxy-error.log
|
|
|
|
# View last 50 lines
|
|
tail -n 50 ~/Library/Logs/headroom/proxy-error.log
|
|
```
|
|
|
|
### Restart Service
|
|
|
|
```bash
|
|
# Graceful restart (stop and let KeepAlive restart it)
|
|
launchctl kickstart -k gui/$(id -u)/com.headroom.proxy
|
|
|
|
# Manual stop/start
|
|
launchctl bootout gui/$(id -u)/com.headroom.proxy
|
|
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.headroom.proxy.plist
|
|
```
|
|
|
|
### Stop Service Temporarily
|
|
|
|
```bash
|
|
# Disable without uninstalling
|
|
launchctl disable gui/$(id -u)/com.headroom.proxy
|
|
|
|
# Re-enable
|
|
launchctl enable gui/$(id -u)/com.headroom.proxy
|
|
```
|
|
|
|
## Verification
|
|
|
|
After installation, verify everything is working:
|
|
|
|
### 1. Check Service Status
|
|
|
|
```bash
|
|
launchctl print gui/$(id -u)/com.headroom.proxy
|
|
```
|
|
|
|
Expected output includes:
|
|
|
|
```
|
|
state = running
|
|
```
|
|
|
|
### 2. Check Port
|
|
|
|
```bash
|
|
lsof -iTCP:8787 -sTCP:LISTEN
|
|
```
|
|
|
|
Should show headroom listening on port 8787.
|
|
|
|
### 3. Test Health Endpoint
|
|
|
|
```bash
|
|
curl http://localhost:8787/health
|
|
```
|
|
|
|
Expected response:
|
|
|
|
```json
|
|
{"status": "healthy"}
|
|
```
|
|
|
|
### 4. Test Proxy Functionality
|
|
|
|
```bash
|
|
# Set base URL
|
|
export ANTHROPIC_BASE_URL=http://localhost:8787
|
|
|
|
# Test with Python
|
|
python -c "
|
|
import anthropic
|
|
client = anthropic.Anthropic()
|
|
response = client.messages.create(
|
|
model='claude-3-5-sonnet-20241022',
|
|
max_tokens=50,
|
|
messages=[{'role': 'user', 'content': 'Hi'}]
|
|
)
|
|
print(response.content[0].text)
|
|
"
|
|
```
|
|
|
|
### 5. Check Logs for Errors
|
|
|
|
```bash
|
|
tail -n 20 ~/Library/Logs/headroom/proxy-error.log
|
|
```
|
|
|
|
Should show no errors. Common startup errors are listed in [Troubleshooting](#troubleshooting).
|
|
|
|
## Troubleshooting
|
|
|
|
### Service Won't Start
|
|
|
|
**Symptom:** `launchctl print` shows service not loaded or failed state
|
|
|
|
**Check logs:**
|
|
|
|
```bash
|
|
tail -n 50 ~/Library/Logs/headroom/proxy-error.log
|
|
```
|
|
|
|
**Common causes:**
|
|
|
|
| Error | Solution |
|
|
|-------|----------|
|
|
| `ANTHROPIC_API_KEY not set` | Set API key in environment or plist |
|
|
| `ModuleNotFoundError: No module named 'headroom'` | Install: `uv tool install --python 3.13 "headroom-ai[proxy]"` |
|
|
| `command not found: headroom` | Update plist with correct path: `command -v headroom` |
|
|
| `Address already in use` | Change port or stop conflicting service |
|
|
|
|
### Port Already in Use
|
|
|
|
**Symptom:** Service starts but port not listening, logs show "Address already in use"
|
|
|
|
**Find what's using the port:**
|
|
|
|
```bash
|
|
lsof -iTCP:8787 -sTCP:LISTEN
|
|
```
|
|
|
|
**Solutions:**
|
|
|
|
1. Stop conflicting service
|
|
2. Use different port: `./uninstall.sh && ./install.sh --port 9000`
|
|
|
|
### Service Crashes Immediately
|
|
|
|
**Symptom:** Service starts but immediately exits
|
|
|
|
**Check for Python errors:**
|
|
|
|
```bash
|
|
tail -f ~/Library/Logs/headroom/proxy-error.log
|
|
```
|
|
|
|
**Common causes:**
|
|
|
|
- Missing dependencies: `uv tool install --python 3.13 "headroom-ai[proxy]"`
|
|
- Invalid API key: Verify `ANTHROPIC_API_KEY`
|
|
- Python version incompatible: Requires Python 3.10+
|
|
|
|
### ANTHROPIC_BASE_URL Not Set
|
|
|
|
**Symptom:** Shell integration not setting environment variable
|
|
|
|
**Verify proxy is running:**
|
|
|
|
```bash
|
|
curl http://localhost:8787/health
|
|
```
|
|
|
|
**Reload shell configuration:**
|
|
|
|
```bash
|
|
source ~/.bashrc # or ~/.zshrc
|
|
```
|
|
|
|
**Check shell integration is sourced:**
|
|
|
|
```bash
|
|
# Should be set to 1
|
|
echo $HEADROOM_SHELL_INTEGRATION_LOADED
|
|
```
|
|
|
|
### Service Not Auto-Starting on Login
|
|
|
|
**Symptom:** Service doesn't start after reboot
|
|
|
|
**Verify LaunchAgent is loaded:**
|
|
|
|
```bash
|
|
launchctl list | grep headroom
|
|
```
|
|
|
|
**If not listed:**
|
|
|
|
```bash
|
|
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.headroom.proxy.plist
|
|
```
|
|
|
|
**Check RunAtLoad is enabled:**
|
|
|
|
```bash
|
|
grep -A1 RunAtLoad ~/Library/LaunchAgents/com.headroom.proxy.plist
|
|
```
|
|
|
|
Should show:
|
|
|
|
```xml
|
|
<key>RunAtLoad</key>
|
|
<true/>
|
|
```
|
|
|
|
### Permission Issues
|
|
|
|
**Symptom:** "Operation not permitted" errors
|
|
|
|
**Ensure plist has correct permissions:**
|
|
|
|
```bash
|
|
chmod 644 ~/Library/LaunchAgents/com.headroom.proxy.plist
|
|
```
|
|
|
|
**Verify ownership:**
|
|
|
|
```bash
|
|
ls -l ~/Library/LaunchAgents/com.headroom.proxy.plist
|
|
```
|
|
|
|
Should be owned by your user, not root.
|
|
|
|
## Uninstallation
|
|
|
|
### Quick Uninstall
|
|
|
|
```bash
|
|
cd examples/deployment/macos-launchagent
|
|
./uninstall.sh
|
|
```
|
|
|
|
This will:
|
|
|
|
1. Stop the service
|
|
2. Remove LaunchAgent plist
|
|
3. Optionally remove log directory (prompts)
|
|
|
|
### Remove Everything
|
|
|
|
```bash
|
|
# Uninstall service and remove logs
|
|
./uninstall.sh --remove-logs
|
|
|
|
# Remove shell integration from ~/.bashrc or ~/.zshrc
|
|
# Delete or comment out:
|
|
# export HEADROOM_PORT=8787
|
|
# source .../shell-integration.sh
|
|
```
|
|
|
|
### Manual Uninstall
|
|
|
|
```bash
|
|
# Stop service
|
|
launchctl bootout gui/$(id -u)/com.headroom.proxy
|
|
|
|
# Remove plist
|
|
rm ~/Library/LaunchAgents/com.headroom.proxy.plist
|
|
|
|
# Remove logs (optional)
|
|
rm -rf ~/Library/Logs/headroom
|
|
```
|
|
|
|
## Production Deployment
|
|
|
|
For production environments, consider:
|
|
|
|
- **System-wide LaunchDaemon** instead of per-user LaunchAgent
|
|
- **Resource limits** in plist (CPU, memory)
|
|
- **Log rotation** for long-running deployments
|
|
- **Monitoring** via external tools
|
|
- **Multiple instances** on different ports for redundancy
|
|
|
|
LaunchAgent is designed for single-user development. For production, evaluate:
|
|
|
|
- [Docker deployment](proxy.md#docker-deployment) for containerized environments
|
|
- systemd on Linux servers
|
|
- Cloud-native solutions (ECS, Cloud Run, etc.)
|
|
|
|
## Related Documentation
|
|
|
|
- [Proxy Server Documentation](proxy.md) - Core proxy configuration and features
|
|
- [Configuration Guide](configuration.md) - Detailed configuration options
|
|
- [Architecture](ARCHITECTURE.md) - How Headroom works internally
|
|
- [Troubleshooting](troubleshooting.md) - General troubleshooting guide
|
|
|
|
## Platform Alternatives
|
|
|
|
- **Linux**: Use systemd instead of LaunchAgent
|
|
- **Windows**: Use Task Scheduler or NSSM (Non-Sucking Service Manager)
|
|
- **Docker**: See [proxy.md](proxy.md) for containerized deployment
|
|
|
|
## Security Considerations
|
|
|
|
### LaunchAgent vs LaunchDaemon
|
|
|
|
**LaunchAgent** (used here):
|
|
|
|
- Runs in user context
|
|
- No root privileges required
|
|
- Starts on user login
|
|
- Per-user isolation
|
|
|
|
**LaunchDaemon** (not covered):
|
|
|
|
- Runs as root or specific user
|
|
- System-wide service
|
|
- Starts on boot
|
|
- Requires admin privileges
|
|
|
|
For single-user development, LaunchAgent is recommended for security.
|
|
|
|
### API Key Security
|
|
|
|
Store API keys securely:
|
|
|
|
- ✅ Use environment variables in shell config
|
|
- ✅ Use macOS Keychain (advanced)
|
|
- ✅ Restrict plist file permissions: `chmod 600`
|
|
- ❌ Don't commit API keys to version control
|
|
- ❌ Don't store in world-readable files
|
|
|
|
### Network Security
|
|
|
|
The proxy binds to `127.0.0.1` (localhost only) by default:
|
|
|
|
- ✅ Only accessible from local machine
|
|
- ✅ No external network exposure
|
|
- ❌ Don't bind to `0.0.0.0` without firewall rules
|
|
|
|
## Advanced Configuration
|
|
|
|
### Multiple Proxy Instances
|
|
|
|
Run multiple proxies on different ports:
|
|
|
|
```bash
|
|
# Install first instance
|
|
./install.sh --port 8787
|
|
|
|
# For second instance, manually create plist with different label
|
|
cp com.headroom.proxy.plist.template ~/Library/LaunchAgents/com.headroom.proxy-2.plist
|
|
# Edit: Change Label to com.headroom.proxy-2, port to 8788
|
|
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.headroom.proxy-2.plist
|
|
```
|
|
|
|
### Custom LaunchAgent Schedule
|
|
|
|
Run proxy only during business hours:
|
|
|
|
```xml
|
|
<!-- Add to plist -->
|
|
<key>StartCalendarInterval</key>
|
|
<dict>
|
|
<key>Hour</key>
|
|
<integer>9</integer>
|
|
<key>Minute</key>
|
|
<integer>0</integer>
|
|
</dict>
|
|
```
|
|
|
|
### Resource Limits
|
|
|
|
Limit CPU and memory usage:
|
|
|
|
```xml
|
|
<!-- Add to plist -->
|
|
<key>HardResourceLimits</key>
|
|
<dict>
|
|
<key>NumberOfProcesses</key>
|
|
<integer>1</integer>
|
|
<key>MemoryMax</key>
|
|
<integer>536870912</integer> <!-- 512 MB -->
|
|
</dict>
|
|
```
|
|
|
|
## Apple GPU (MPS) Embedding Offload
|
|
|
|
On Apple Silicon, the proxy's memory embedder can run on the Apple GPU (MPS)
|
|
instead of the default ONNX CPU backend. Offloading embedding to the GPU frees
|
|
the CPU under load, keeping the proxy responsive — useful on fanless Macs (e.g.
|
|
the M5 Air) that are prone to CPU-saturation timeouts.
|
|
|
|
Enable it by installing the extra and setting the env var:
|
|
|
|
```bash
|
|
pip install 'headroom-ai[pytorch-mps]' # also works as [pytorch_mps]
|
|
export HEADROOM_EMBEDDER_RUNTIME=pytorch_mps
|
|
```
|
|
|
|
Under a LaunchAgent, set the env var in the plist `EnvironmentVariables`
|
|
section:
|
|
|
|
```xml
|
|
<key>HEADROOM_EMBEDDER_RUNTIME</key>
|
|
<string>pytorch_mps</string>
|
|
```
|
|
|
|
It only engages when Apple MPS is actually available (Apple Silicon + torch).
|
|
If MPS is unavailable or the dependencies are missing, the proxy logs a warning
|
|
and uses the existing default embedder selection path. This is strictly opt-in;
|
|
default behavior is unchanged. See [Memory](memory.md#embedding-runtime--gpu-offload-apple-silicon)
|
|
for details.
|
|
|
|
## FAQ
|
|
|
|
**Q: Why LaunchAgent instead of running `headroom proxy` manually?**
|
|
|
|
A: LaunchAgent provides automatic startup, crash recovery, and proper lifecycle management. You don't have to remember to start the proxy or keep a terminal window open.
|
|
|
|
**Q: Can I use this in production?**
|
|
|
|
A: LaunchAgent is designed for development. For production, use Docker, systemd, or cloud-native deployment.
|
|
|
|
**Q: How much does the proxy impact performance?**
|
|
|
|
A: Minimal. The proxy adds ~10-50ms latency while reducing token costs by 50-90%. The cost savings far outweigh the latency.
|
|
|
|
**Q: Do I need to restart the proxy when configuration changes?**
|
|
|
|
A: Yes. After changing the plist, reload the service:
|
|
|
|
```bash
|
|
launchctl kickstart -k gui/$(id -u)/com.headroom.proxy
|
|
```
|
|
|
|
**Q: Can I use this with multiple API providers?**
|
|
|
|
A: The LaunchAgent setup is Anthropic-specific. For other providers, see [proxy.md](proxy.md) for configuration options.
|
|
|
|
**Q: Does this work with Apple Silicon (M1/M2/M3)?**
|
|
|
|
A: Yes, fully compatible. ML compression (Kompress, opt-in via `headroom-ai[ml]`) auto-detects MPS on Apple Silicon.
|