# AI Service — API Reference

## Overview

The AI service exposes a FastAPI application that wraps an AI provider (OpenAI, Anthropic, or a mock) to perform code analysis and test generation.

---

## Configuration

| Environment Variable | Default | Description |
|---|---|---|
| `OPENAI_API_KEY` | _(unset)_ | Your OpenAI secret key. When present, the service can call the OpenAI API. |
| `ANTHROPIC_API_KEY` | _(unset)_ | Your Anthropic secret key. Required when `AI_PROVIDER=anthropic`. |
| `AI_PROVIDER` | auto | Force a specific provider: `openai`, `anthropic`, or `mock`. When unset the service picks `openai` if `OPENAI_API_KEY` is set, `anthropic` if only `ANTHROPIC_API_KEY` is set, `mock` otherwise. |
| `OPENAI_MODEL` | `gpt-4o` | OpenAI chat model to use (e.g. `gpt-4o`, `gpt-3.5-turbo`). |
| `ANTHROPIC_MODEL` | `claude-3-haiku-20240307` | Anthropic model to use (e.g. `claude-3-opus-20240229`, `claude-3-sonnet-20240229`). |

---

## Python client wrapper

`packages/ai-service/openai_client.py` provides a lightweight abstraction:

```python
from openai_client import create_ai_client

# Auto-selects provider from environment
client = create_ai_client()

reply = client.chat("Write a unit test for a sum() function in Python.")
print(reply)
```

### Force a specific provider

```python
# Always use OpenAI (raises ValueError if OPENAI_API_KEY is absent)
client = create_ai_client(provider="openai", api_key="sk-...")

# Always use Anthropic (raises ValueError if ANTHROPIC_API_KEY is absent)
client = create_ai_client(provider="anthropic", api_key="sk-ant-...")

# Always use the mock (no API key required — great for CI)
client = create_ai_client(provider="mock")
```

### Direct instantiation

```python
from openai_client import OpenAIClient, MockAIClient
from anthropic_client import AnthropicClient

# OpenAI
real_openai = OpenAIClient(api_key="sk-...", model="gpt-4o")
reply = real_openai.chat("Hello!")

# Anthropic
real_anthropic = AnthropicClient(api_key="sk-ant-...", model="claude-3-haiku-20240307")
reply = real_anthropic.chat("Hello!")
# Health check (no API call)
status = real_anthropic.health_check()
# → {"status": "ok", "provider": "anthropic", "model": "claude-3-haiku-20240307"}

# Real Anthropic client
claude = AnthropicClient(api_key="sk-ant-...", model="claude-3-haiku-20240307")
reply = claude.chat("Hello!")

# Mock client (zero-dependency, deterministic)
mock = MockAIClient()
reply = mock.chat("Hello!")  # → "[MOCK RESPONSE] ..."
```

---

## Anthropic provider

`packages/ai-service/anthropic_client.py` wraps the [Anthropic Python SDK](https://github.com/anthropics/anthropic-sdk-python).

### Quick start

```bash
export ANTHROPIC_API_KEY="sk-ant-..."
export AI_PROVIDER="anthropic"
# Optionally override the model
export ANTHROPIC_MODEL="claude-3-opus-20240229"
```

### `AnthropicClient` interface

| Method | Signature | Description |
|---|---|---|
| `chat` | `(prompt, system?) → str` | Send a user message and return the assistant's reply. |
| `generate_tests` | `(prompt, system?) → str` | Alias for `chat()` — same signature. |
| `health_check` | `() → dict` | Return provider/model info without making an API call. |

The client reads `ANTHROPIC_API_KEY` and `ANTHROPIC_MODEL` from the environment by default, both of which can be overridden via constructor arguments.

---

## REST endpoints

### `GET /provider`

Returns the name of the currently active AI provider.

```json
{
  "provider": "openai"
}
```

Possible values: `"openai"`, `"anthropic"`, `"mock"`.

### `GET /health`

Returns service health and the active AI provider.

```json
{
  "status": "healthy",
  "timestamp": "2026-03-08T10:00:00.000Z",
  "ai_provider": "anthropic"
}
```

### `POST /generate-tests`

Generates test cases powered by the configured AI provider (OpenAI or Anthropic when a key is available, mock otherwise).

**Request body**

```json
{
  "code_analysis": { ... },
  "test_type": "unit",
  "framework": "jest",
  "ai_provider": "anthropic",
  "ai_model": "claude-3-haiku-20240307"
}
```

> **Note:** `ai_provider` / `ai_model` in the request body are informational.
> The service uses the provider selected via environment variables.

**Response**

```json
{
  "tests": {
    "unit_tests": [
      {
        "name": "should validate email format",
        "file": "src/utils/validation.test.ts",
        "code": "...",
        "coverage": "src/utils/validation.ts"
      }
    ]
  },
  "coverage_estimate": 85.5,
  "test_count": 2,
  "execution_time": "2m 30s"
}
```

---

## Running the tests

```bash
# From the repository root
python3 -m unittest discover \
  -s packages/ai-service/tests \
  -p "test_*.py" -v

# Or with pytest (if installed)
pytest packages/ai-service/tests/ -v
```

All tests use `unittest.mock` — no real API key is required.
