Embeddings

The POST /v1/embeddings endpoint returns OpenAI-compatible embedding vectors. You can provide explicit vectors in fixtures or let aimock generate deterministic embeddings automatically from the input text.

Endpoint

Method Path Format
POST /v1/embeddings JSON

How It Works

Gemini deterministic fallback uses 768 dimensions when outputDimensionality is absent or null. In this fallback, negative or fractional numbers and nonnumeric strings return HTTP 400 with INVALID_ARGUMENT. This check applies only when fallback generation uses the dimension value.

The fallback also rejects numeric values and numeric strings greater than 100000, the local serialization budget. This budget is not a provider or model limit. Fixture replay, strict mode, chaos responses, and proxy responses retain their existing behavior. Zero dimensions and existing numeric-string coercion remain supported within this budget.

Native POST /v1/embeddings requires a model field and returns HTTP 400 if it is absent. Azure deployment routes and compatible embedding routes retain their model defaults.

aimock preserves empty embedding inputs as a compatibility convenience. An empty string, [""], and [[]] each produce one embedding for empty text. An empty outer array ([]) produces an empty data list. These forms remain accepted with an explicit model, alongside string batches and token arrays.

For Cohere embedding output, embedding_types must be an array of strings. Omitted, null, and empty-array values retain the default float output. String extension names remain accepted. Invalid containers or nonstring members return HTTP 400 when aimock builds embedding output from a fixture or deterministic fallback. Error fixtures, strict-mode errors, and proxy responses retain their existing behavior.

Unit Test: Fixture-based Embedding

embedding-fixture.test.ts ts
const mock = new LLMock();
await mock.start();

// Register a fixture with explicit embedding vector
mock.onEmbedding("embed-this", { embedding: [0.1, -0.2, 0.3, 0.4, -0.5] });

const res = await fetch(`${mock.url}/v1/embeddings`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    model: "text-embedding-3-small",
    input: "embed-this",
  }),
});

const body = await res.json();
expect(body.object).toBe("list");
expect(body.data[0].embedding).toEqual([0.1, -0.2, 0.3, 0.4, -0.5]);
expect(body.data[0].index).toBe(0);

Unit Test: Auto-generated Embedding

embedding-auto.test.ts ts
import { generateDeterministicEmbedding } from "@copilotkit/aimock/helpers";

// Deterministic: same input always produces the same output
const a = generateDeterministicEmbedding("hello world");
const b = generateDeterministicEmbedding("hello world");
expect(a).toEqual(b);

// Default dimension is 1536
expect(a).toHaveLength(1536);

// Custom dimension
const c = generateDeterministicEmbedding("hello", 768);
expect(c).toHaveLength(768);

// All values are between -1 and 1
for (const val of a) {
  expect(val).toBeGreaterThanOrEqual(-1);
  expect(val).toBeLessThanOrEqual(1);
}

JSON Fixture

fixtures/embeddings.json json
{
  "fixtures": [
    {
      "match": { "inputText": "embed-this" },
      "response": {
        "embedding": [0.1, -0.2, 0.3, 0.4, -0.5]
      }
    }
  ]
}

Response Format

Matches the OpenAI /v1/embeddings response format:

Response shape json
{
  "object": "list",
  "model": "text-embedding-3-small",
  "data": [
    {
      "object": "embedding",
      "index": 0,
      "embedding": [0.1, -0.2, 0.3, ...]
    }
  ],
  "usage": { "prompt_tokens": 0, "total_tokens": 0 }
}

Embedding fixtures use match.inputText instead of match.userMessage. The inputText matcher checks the embedding input string (or each string in an input array).