Metadata-Version: 2.4
Name: ai-filter-gateway
Version: 0.1.0
Summary: AI API request/response filter gateway based on mitmproxy — transparent path desensitization for LLM prompts.
Author-email: cgw <guowei1264@163.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/guowei1003/ai-filter-gateway
Project-URL: Repository, https://github.com/guowei1003/ai-filter-gateway
Project-URL: Issues, https://github.com/guowei1003/ai-filter-gateway/issues
Keywords: ai,llm,mitmproxy,proxy,filter,gateway,privacy,path-mask
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Security
Classifier: Topic :: Internet :: Proxy Servers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: mitmproxy>=12.0
Requires-Dist: pyyaml>=6.0
Provides-Extra: test
Requires-Dist: pytest>=7.0; extra == "test"
Requires-Dist: pytest-asyncio>=0.21; extra == "test"
Dynamic: license-file

# ai-filter-gateway

> AI API request/response filter gateway — transparent path desensitization proxy based on mitmproxy.

A lightweight MITM proxy that **automatically detects and masks real file paths** in LLM API requests and responses, preventing local path information leakage to large language models.

![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)
![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)
![Status: Alpha](https://img.shields.io/badge/status-alpha-orange.svg)

[中文版](README_CN.md)

---

## Features

| Feature | Description |
|---------|-------------|
| **Request Masking** | Intercepts real file paths in LLM API request bodies, replacing them with unique placeholders (e.g. `/data/ws/1`) |
| **Response Restoration** | Intercepts JSON or SSE streaming responses and restores placeholders to real paths |
| **Reverse Proxy** | Supports `reverse` mode, directly proxying to target AI API server |
| **Upstream Proxy (Transit)** | Supports `upstream` mode, transit through another proxy (e.g. Clash, Shadowsocks) |
| **Outbound Proxy** | Configurable HTTP/HTTPS outbound proxy (e.g. Clash, Shadowsocks) |
| **Cross-Platform** | macOS / Linux / Windows |

### How It Works

#### Reverse Proxy Mode (Default)

```
User App                          ai-filter-gateway                      AI API Server
   |                                      |                                       |
   |── POST /chat/completions ─────────> |  <--- reverse proxy ---->       |
   |   {"prompt": "file: /Users/x/a.py"}|                                       |
   |                                      |  [Mask] /Users/x/a.py -> /data/ws/1 |
   |                                      |── POST /chat/completions ────>    |
   |                                      |   {"prompt": "file: /data/ws/1"}  |
   |                                      |   {"response": "see /data/ws/1"}  |
   |                                      |  [Restore] /data/ws/1 -> /Users/x/a.py |
   |<-- {"response": "see /Users/x/a.py"}--                                     |
```

#### Upstream Proxy Mode (Transit)

```
User App                          ai-filter-gateway                    Upstream Proxy                 AI API Server
   |                                      |                                   |                            |
   |── POST /chat/completions ─────────> |  <--- upstream proxy ---->  |                            |
   |   {"prompt": "file: /Users/x/a.py"}|                                   |                            |
   |                                      |  [Mask] /Users/x/a.py -> /data/ws/1 |                            |
   |                                      |── POST /chat/completions ────> |                            |
   |                                      |   {"prompt": "file: /data/ws/1"}  |                            |
   |                                      |   {"response": "see /data/ws/1"}  |                            |
   |                                      |  [Restore] /data/ws/1 -> /Users/x/a.py |                            |
   |<-- {"response": "see /Users/x/a.py"}--                                    |                            |
```

---

## Installation

### Prerequisites

- Python 3.10+
- [mitmproxy](https://mitmproxy.org/)

### Install

```bash
git clone https://github.com/your-username/ai-filter-gateway.git
cd ai-filter-gateway
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e .
```

---

## Usage

### Option 1: Bash Script (Recommended)

```bash
# Start proxy (default: reverse mode to https://api.openai.com)
./ai-proxy start

# Start in upstream mode (transit through another proxy)
AI_PROXY_MODE=upstream AI_PROXY_TARGET=http://127.0.0.1:7890 ./ai-proxy start

# Check status
./ai-proxy status

# View logs
./ai-proxy logs

# Stop proxy
./ai-proxy stop

# Restart proxy
./ai-proxy restart
```

### Option 2: Python Module

```bash
# Start (default: reverse proxy to https://api.openai.com)
python -m ai_filter_gateway

# Reverse proxy to custom target
python -m ai_filter_gateway --mode reverse:https://api.openai.com

# Upstream proxy mode (transit through another proxy)
python -m ai_filter_gateway --mode upstream:http://127.0.0.1:7890

# Custom port
python -m ai_filter_gateway --listen-port 8080

# Configure outbound proxy (reverse mode only)
python -m ai_filter_gateway --outbound-proxy http://127.0.0.1:7890
```

### Option 3: Direct mitmproxy Load

```bash
# Reverse proxy mode
mitmproxy -s src/ai_filter_gateway/path_mask.py --mode reverse:https://api.openai.com
mitmdump -s src/ai_filter_gateway/path_mask.py --mode reverse:https://api.openai.com

# Upstream proxy mode
mitmproxy -s src/ai_filter_gateway/path_mask.py --mode upstream:http://127.0.0.1:7890
mitmdump -s src/ai_filter_gateway/path_mask.py --mode upstream:http://127.0.0.1:7890
```

### Client Configuration

Point your AI client's API address to the proxy:

```bash
# Example: OpenAI SDK
export OPENAI_BASE_URL="http://127.0.0.1:7878"

# Example: Custom API call
curl -X POST http://127.0.0.1:7878/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Analyze this file /Users/name/project/config.py"}'
```

---

## Configuration

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `AI_PROXY_MODE` | `reverse` | Proxy mode: `reverse` or `upstream` |
| `AI_PROXY_TARGET` | `https://api.openai.com` | Target URL (reverse mode) or upstream proxy URL (upstream mode) |
| `AI_PROXY_HOST` | `127.0.0.1` | Listen address |
| `AI_PROXY_PORT` | `7878` | Listen port |
| `AI_PROXY_OUTBOUND_PROXY` | *(empty)* | Outbound proxy address (reverse mode only) |

### Code Configuration

Edit constants in `src/ai_filter_gateway/path_mask.py`:

```python
# Hostname whitelist (empty = monitor all)
MONITOR_HOSTNAMES: list[str] = []
# Example: ["api.openai.com", "localhost:11434"]

# Placeholder path format
PH_PREFIX = "/data/ws/"
PH_SUFFIX = ""
```

---

## Path Detection Rules

| Type | Example | Matched |
|------|---------|---------|
| Unix absolute path | `/Users/name/project/file.py` | ✅ |
| Unix relative path | `./data/test.txt` | ✅ |
| Windows path | `C:\Users\name\app.exe` | ✅ |
| URL path segment | `https://example.com/api/v1` | ❌ |
| Date format | `2026/07/08` | ❌ |
| Pure numeric path | `/123/456/789` | ❌ |

---

## Project Structure

```
ai-filter-gateway/
├── src/
│   └── ai_filter_gateway/
│       ├── __init__.py          # Package definition
│       ├── __main__.py          # CLI entry point
│       └── path_mask.py         # Core filter logic
├── tests/
│   └── test_path_mask.py        # Unit tests
├── .github/workflows/
│   └── ci.yml                   # CI configuration
├── ai-proxy                     # Bash management script
├── pyproject.toml               # Project metadata
├── requirements.txt             # Dependency list
├── README.md                    # English documentation
├── README_CN.md                 # Chinese documentation
├── LICENSE                      # MIT License
├── CHANGELOG.md                 # Changelog
├── CONTRIBUTING.md              # Contribution guide
└── Dockerfile                   # Container deployment
```

---

## Development

### Run Tests

```bash
pip install pytest
pytest tests/ -v
```

### Code Style

This project uses Ruff for linting:

```bash
pip install ruff
ruff check src/ tests/
```

---

## FAQ

### Q: How to monitor only specific AI API endpoints?

Modify the `MONITOR_HOSTNAMES` list:

```python
MONITOR_HOSTNAMES = ["api.openai.com", "localhost:11434"]
```

### Q: Does the proxy impact performance?

Text replacement overhead is minimal, adding <1ms per request. Streaming responses are processed chunk-by-chunk with no noticeable latency.

### Q: Is Windows supported?

Yes. On Windows, run `.\ai-proxy` in PowerShell or CMD. Windows path formats (`C:\path\to\file`) are correctly detected and masked.

### Q: How to disable path masking?

Comment out or remove the `addons = [PathMask()]` line. Alternatively, set `MONITOR_HOSTNAMES` to not include your target host.

---

## License

MIT License — see [LICENSE](LICENSE).

---

## Contributing

Issues and Pull Requests are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md).

---

## Related Projects

- [mitmproxy](https://mitmproxy.org/) — A powerful interactive HTTPS proxy
- [OpenAI Python SDK](https://github.com/openai/openai-python) — Official OpenAI API SDK
