Metadata-Version: 2.4
Name: ai-protocol-mock
Version: 0.1.5
Summary: Unified mock server for AI-Protocol runtimes - HTTP provider and MCP JSON-RPC mocking
Author: AI-Protocol Team
License-Expression: MIT OR Apache-2.0
License-File: LICENSE-APACHE
License-File: LICENSE-MIT
Requires-Python: >=3.10
Requires-Dist: fastapi>=0.109.0
Requires-Dist: httpx>=0.25.0
Requires-Dist: pydantic>=2.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: uvicorn[standard]>=0.27.0
Provides-Extra: dev
Requires-Dist: black>=24.0; extra == 'dev'
Requires-Dist: pre-commit>=3.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.8; extra == 'dev'
Description-Content-Type: text/markdown

# ai-protocol-mock

Unified mock server for AI-Protocol runtimes. Provides HTTP provider mock (OpenAI and Anthropic formats) and MCP JSON-RPC mock for testing ai-lib-python, ai-lib-rust, and other runtimes.

## Features

- **Manifest-driven HTTP mock**: Generates responses in OpenAI or Anthropic format based on provider manifests
- **STT / TTS / Rerank mock**: Simulates speech-to-text, text-to-speech, and document reranking endpoints (OpenAI/Cohere compliant)
- **MCP JSON-RPC mock**: Implements `tools/list`, `tools/call`, `capabilities`, `initialize`
- **Configurable**: Response delay, error rate, mock content via environment variables
- **Docker**: One-command startup with `docker-compose up`

## Quick Start

```bash
# Install and run
pip install -e .
python scripts/sync_manifests.py --force  # Sync manifests from ai-protocol
uvicorn ai_protocol_mock.main:app --host 0.0.0.0 --port 4010
```

Or with Docker:

```bash
docker-compose up -d
```

## Configuration

| Variable | Default | Description |
|----------|---------|-------------|
| HTTP_PORT | 4010 | Port for HTTP and MCP (MCP at /mcp) |
| MANIFEST_DIR | manifests | Directory for synced manifests |
| MANIFEST_SYNC_URL | https://raw.githubusercontent.com/hiddenpath/ai-protocol/main/ | Source for manifest sync |
| RESPONSE_DELAY | 0 | Delay in seconds before responding |
| ERROR_RATE | 0 | Probability (0-1) of returning 429/500/503 |
| MOCK_CONTENT | Mock response from ai-protocol-mock | Default response content |

### Test Control Headers (X-Mock-*)

For integration tests, requests can include these headers to control mock behavior:

| Header | Description | Example |
|--------|-------------|---------|
| X-Mock-Status | Force HTTP error status (400-599) | 429, 500, 503 |
| X-Mock-Content | Override response content for this request | Custom text |
| X-Mock-Tool-Calls | Return tool_calls instead of text | 1, true, yes |

## Endpoints

- `POST /v1/chat/completions` - OpenAI-format chat
- `POST /v1/messages` - Anthropic-format chat
- `POST /v1/audio/transcriptions` - STT (OpenAI Whisper format), returns `{"text": "..."}`
- `POST /v1/audio/speech` - TTS (OpenAI format), returns `audio/mpeg` bytes
- `POST /v2/rerank` - Rerank (Cohere v2 format), request `{query, documents, top_n}`, returns `{results, id, meta}`
- `POST /mcp` - MCP JSON-RPC (`tools/list`, `tools/call`, `capabilities`, `initialize`)
- `GET /health` - Health check
- `GET /status` - Status with manifest sync metadata
- `GET /providers` - Provider contracts from manifests (provider_id, api_style, chat_path)

## Using with ai-lib-python

```python
import os
os.environ["MOCK_HTTP_URL"] = "http://localhost:4010"

from ai_lib_python.client import AiClient
from ai_lib_python.types.message import Message

client = await AiClient.create(
    "openai/gpt-4o",
    api_key="sk-test",
    base_url="http://localhost:4010"
)
response = await client.chat().messages([Message.user("Hi")]).execute()
print(response.content)
```

Or run tests with mock:

```bash
MOCK_HTTP_URL=http://localhost:4010 MOCK_MCP_URL=http://localhost:4010/mcp pytest tests/ -v
```

**Remote / proxy environments**: If your machine uses HTTP/HTTPS proxy, set `NO_PROXY` to include the mock server IP so Python's httpx can reach it directly:

```bash
NO_PROXY=192.168.2.13,localhost,127.0.0.1 MOCK_HTTP_URL=http://192.168.2.13:4010 MOCK_MCP_URL=http://192.168.2.13:4010/mcp pytest tests/ -v
```

## Using with ai-lib-rust

```bash
export MOCK_HTTP_URL=http://localhost:4010
cargo run --example basic_usage
```

Or run mock integration tests:

```bash
MOCK_HTTP_URL=http://localhost:4010 MOCK_MCP_URL=http://localhost:4010/mcp cargo test -- --ignored --nocapture
```

Or in code:

```rust
let client = AiClientBuilder::new()
    .base_url_override("http://localhost:4010")
    .build("openai/gpt-4o")
    .await?;
```

## Manifest Sync

Sync manifests from the ai-protocol repository:

```bash
python scripts/sync_manifests.py [--force] [--url URL] [--tag REF]
```

- `--force` - Overwrite existing files
- `--tag REF` - Pin to a specific ai-protocol ref (e.g. `v0.7.1`, `main`)
- `--url URL` - Custom base URL (default: ai-protocol main)

Run before starting the server to ensure manifests are up to date. Docker Compose runs sync automatically on startup. A GitHub Action runs sync daily to validate the script.

## Development

```bash
pip install -e ".[dev]"
pytest tests/ -v
ruff check src tests scripts
```

## License

MIT OR Apache-2.0
