# Services (Search / Rerank / Moderation)

Built-in service mocks for web search, reranking, and content moderation APIs. Register fixture patterns on the LLMock instance and requests are matched by query/input text. No separate server needed — services are built into the LLMock HTTP server.

## Search (Tavily-Compatible)

Mock web search API at `POST /search`. Matches the request `query` field against registered patterns.

onSearch API typescript

    import { LLMock } from "@copilotkit/aimock";

    const mock = new LLMock();

    // String pattern — case-insensitive substring match
    mock.onSearch("weather", [
      { title: "Weather Report", url: "https://example.com/weather", content: "Sunny today" },
    ]);

    // RegExp pattern
    mock.onSearch(/stock\s+price/i, [
      { title: "ACME Stock", url: "https://example.com/stocks", content: "$42.00", score: 0.95 },
    ]);

    // Catch-all — empty results for unmatched queries
    mock.onSearch(/.*/, []);

### Search Endpoint

Method | Path | Request Body | Response
--- | --- | --- | ---
`POST` | `/search` | `{ "query": "...", "max_results": 5 }` | `{ "results": [...] }`

## Rerank (Cohere-Compatible)

Mock reranking API at `POST /v2/rerank`. Matches the request `query` field against registered patterns.

onRerank API typescript

    mock.onRerank("machine learning", [
      { index: 0, relevance_score: 0.99 },
      { index: 2, relevance_score: 0.85 },
    ]);

    // The response includes document text from the request body
    // Response format: { id, results: [{ index, relevance_score, document: { text } }] }

### Rerank Endpoint

Method | Path | Request Body | Response
--- | --- | --- | ---
`POST` | `/v2/rerank` | `{ "query": "...", "documents": [...], "model": "..." }` | `{ "id": "...", "results": [...], "meta": {...} }`

## Moderation (OpenAI-Compatible)

Mock content moderation API at `POST /v1/moderations`. Matches the request `input` field against registered patterns. Unmatched requests return a default unflagged result.

onModerate API typescript

    // Flag specific content
    mock.onModerate("violent", {
      flagged: true,
      categories: { violence: true, hate: false },
      category_scores: { violence: 0.95, hate: 0.01 },
    });

    // Catch-all — everything passes
    mock.onModerate(/.*/, {
      flagged: false,
      categories: {},
    });

### Moderation Endpoint

Method | Path | Request Body | Response
--- | --- | --- | ---
`POST` | `/v1/moderations` | `{ "input": "..." }` | `{ "id": "...", "model": "...", "results": [...] }`

## Pattern Matching

All three services use the same matching logic:

- String patterns — case-insensitive substring match
- RegExp patterns — full regex test
- First match wins — register specific patterns before catch-alls

## Config File

Enable services via the aimock config file with default catch-all responses:

aimock.json json

    {
      "services": {
        "search": true,
        "rerank": true,
        "moderate": true
      }
    }

When enabled via config, each service registers a `/.*/` catch-all pattern. Search and rerank return empty results; moderation returns unflagged. For custom responses, use the programmatic API.

## Journal Integration

All service requests are recorded in the LLMock journal with the `service` field set to `"search"`, `"rerank"`, or `"moderation"`:

Journal entries typescript

    const entries = mock.getRequests();
    const searchRequests = entries.filter((e) => e.service === "search");
    const rerankRequests = entries.filter((e) => e.service === "rerank");
    const moderationRequests = entries.filter((e) => e.service === "moderation");