Skip to content

[FEAT] Add Mistral embedding adapter (mistral-embed)#2158

Merged
chandrasekharan-zipstack merged 2 commits into
Zipstack:mainfrom
ahmedk20:feat/mistral-embedding-adapter
Jul 13, 2026
Merged

[FEAT] Add Mistral embedding adapter (mistral-embed)#2158
chandrasekharan-zipstack merged 2 commits into
Zipstack:mainfrom
ahmedk20:feat/mistral-embedding-adapter

Conversation

@ahmedk20

@ahmedk20 ahmedk20 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Mistral was a first-class LLM adapter but had no embedding adapter, despite shipping a real, popular embedding model (mistral-embed). This adds a native Mistral embedding adapter that routes through LiteLLM's mistral/ provider, so cost calculation works out of the box.

  • MistralEmbeddingParameters in base1.py (idempotent mistral/ prefix, required-model validation)
  • MistralEmbeddingAdapter + UI JSON schema, reusing the existing logo
  • Registered in embedding1/init.py
  • 28 unit tests mirroring the Gemini embedding coverage

Closes #2157

What

  • Adds a native Mistral embedding adapter (mistral-embed) to unstract/sdk1. Mistral was already a first-class LLM adapter but had no embedding counterpart.

  • MistralEmbeddingParameters in base1.py (idempotent mistral/ prefix, required-model validation)

  • MistralEmbeddingAdapter + UI JSON schema (embedding1/static/mistral.json), reusing the existing Mistral logo

  • Registered in embedding1/__init__.py

  • 28 unit tests mirroring the Gemini embedding coverage

Why

  • Users who standardize on Mistral for generation had to switch providers just for embeddings — a second API key, second billing relationship, and mixed providers inside one RAG pipeline.
  • The gap was a plain asymmetry: 14 LLM adapters include mistral, but the 9 embedding adapters did not, despite mistral-embed being a real, popular model.
  • Routing through LiteLLM's native mistral/ provider means cost calculation works out of the box (litellm_provider: "mistral" matches get_provider()).

How

  • New MistralEmbeddingParameters(BaseEmbeddingParameters) validates the required model and prepends the mistral/ prefix idempotently (won't double-prefix an already-prefixed model).
  • MistralEmbeddingAdapter follows the existing embedding-adapter contract (get_id/get_provider/get_adapter_type/etc.), returns AdapterTypes.EMBEDDING, and is auto-discovered by register_adapters().
  • Verified against LiteLLM pricing data: mistral/mistral-embedlitellm_provider: "mistral", mode: "embedding", 8192 max tokens.

Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)

  • No. The change is purely additive: one new adapter file, one new JSON schema, one new parameter class, and one new import line. No existing adapter, schema, or shared code path is modified. Adapters are auto-registered by directory scan, so nothing else needs to change. The new provider name (mistral) already exists as an LLM provider, so cost-calculation behavior for existing adapters is untouched.

Database Migrations

  • None.

Env Config

  • None. Users supply their Mistral API key through the adapter UI like any other embedding adapter.

Relevant Docs

Related Issues or PRs

Dependencies Versions

  • No new dependencies. Uses the already-vendored LiteLLM mistral/ provider.

Notes on Testing

  • Added tests/test_mistral_embedding.py — 28 tests covering registration, ID format, provider name, JSON schema (required fields, defaults, password format), model-prefix idempotency, input-mutation safety, and validation errors (empty/whitespace/None/missing model, missing API key).
  • Full run: 52 passed (28 new + 24 Gemini embedding as a regression check).
  • Lint clean with the repo's pinned ruff 0.3.4: ruff check → all passed; ruff format --check → all files formatted.

Screenshots

N/A — no custom UI; the adapter renders through the standard auto-generated config form.

Checklist

I have read and understood the Contribution Guidelines.

Mistral was a first-class LLM adapter but had no embedding adapter,
despite shipping a real, popular embedding model (mistral-embed).
This adds a native Mistral embedding adapter that routes through
LiteLLM's `mistral/` provider, so cost calculation works out of the box.

- MistralEmbeddingParameters in base1.py (idempotent `mistral/` prefix,
  required-model validation)
- MistralEmbeddingAdapter + UI JSON schema, reusing the existing logo
- Registered in embedding1/__init__.py
- 28 unit tests mirroring the Gemini embedding coverage

Closes Zipstack#2157

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@CLAassistant

CLAassistant commented Jul 8, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: db69058a-c40f-401c-82f3-1317339f2ae4

📥 Commits

Reviewing files that changed from the base of the PR and between cb11a6f and 16dc46f.

📒 Files selected for processing (5)
  • unstract/sdk1/src/unstract/sdk1/adapters/base1.py
  • unstract/sdk1/src/unstract/sdk1/adapters/embedding1/__init__.py
  • unstract/sdk1/src/unstract/sdk1/adapters/embedding1/mistral.py
  • unstract/sdk1/src/unstract/sdk1/adapters/embedding1/static/mistral.json
  • unstract/sdk1/tests/test_mistral_embedding.py

Summary by CodeRabbit

  • New Features

    • Added support for a new Mistral embedding adapter, including its configuration, identity, and provider details.
    • Introduced a new setup schema so it can be configured with an API key, model, and timeout settings.
  • Bug Fixes

    • Improved model handling by normalizing Mistral model names and validating required fields more strictly.
    • Added coverage to ensure adapter settings are parsed consistently and invalid input is rejected.

Walkthrough

Adds a new Mistral embedding adapter to the Unstract SDK, including a MistralEmbeddingParameters class with model validation, a MistralEmbeddingAdapter class with registry metadata, package exports, a UI JSON schema, and a corresponding test suite.

Changes

Mistral Embedding Adapter

Layer / File(s) Summary
Parameter validation
unstract/sdk1/src/unstract/sdk1/adapters/base1.py
Adds MistralEmbeddingParameters with api_key and optional embed_batch_size fields, validate() returning normalized model_dump(), and validate_model() enforcing non-empty model names prefixed with mistral/.
Adapter class and registration
unstract/sdk1/src/unstract/sdk1/adapters/embedding1/mistral.py, unstract/sdk1/src/unstract/sdk1/adapters/embedding1/__init__.py
Implements MistralEmbeddingAdapter with get_id, get_metadata, get_name, get_description, get_provider, get_icon, and get_adapter_type (EMBEDDING), and registers/exports it via the package __init__.
JSON configuration schema
unstract/sdk1/src/unstract/sdk1/adapters/embedding1/static/mistral.json
Adds a schema defining required fields (adapter_name, api_key, model) with defaults for model, password-formatted api_key, and a constrained numeric timeout.
Test coverage
unstract/sdk1/tests/test_mistral_embedding.py
Adds tests validating adapter registration, identity/provider values, schema correctness, model/API key validation behavior, and metadata output.

Estimated code review effort: 2 (Simple) | ~15 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: adding a Mistral embedding adapter for mistral-embed.
Description check ✅ Passed The description includes the required sections and covers what, why, how, risks, testing, and related issues.
Linked Issues check ✅ Passed The changes implement the requested Mistral embedding adapter, schema, provider routing, and parameter class from #2157.
Out of Scope Changes check ✅ Passed The patch appears additive and focused on the requested adapter, schema, exports, and tests with no unrelated changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a native Mistral embedding adapter (mistral-embed) to the SDK, closing the asymmetry where Mistral was a first-class LLM provider but had no embedding counterpart.

  • MistralEmbeddingParameters in base1.py closely mirrors the existing GeminiEmbeddingParameters: it validates and idempotently prepends the mistral/ prefix, raises a clear ValueError for blank/None model values, and copies the input dict before mutating to avoid side effects.
  • MistralEmbeddingAdapter and its JSON schema (embedding1/static/mistral.json) follow the established adapter contract exactly — same get_id/get_provider/get_adapter_type shape, same icon reuse from the LLM adapter, same adapter_name + model + api_key + timeout schema layout as Gemini.
  • 28 unit tests mirror the Gemini embedding test suite, covering registration, schema shape, prefix idempotency, mutation safety, and validation error paths.

Confidence Score: 5/5

Purely additive change — one new parameter class, one new adapter, one new JSON schema, and one registration line. No existing code is modified.

All new code follows the established Gemini embedding adapter pattern exactly. The parameter class, adapter, JSON schema, and tests are internally consistent. No shared code paths are touched, and the adapter is auto-discovered at startup, so there is no risk of breaking existing adapters.

No files require special attention.

Important Files Changed

Filename Overview
unstract/sdk1/src/unstract/sdk1/adapters/base1.py Adds MistralEmbeddingParameters, directly mirroring GeminiEmbeddingParameters — same api_key + embed_batch_size fields, same idempotent prefix logic, same mutation-safe validate() pattern using a dict copy.
unstract/sdk1/src/unstract/sdk1/adapters/embedding1/mistral.py New MistralEmbeddingAdapter implementing the full BaseAdapter contract; correctly reuses the LLM Mistral icon and returns AdapterTypes.EMBEDDING.
unstract/sdk1/src/unstract/sdk1/adapters/embedding1/static/mistral.json New JSON schema for the Mistral embedding UI form; layout and field constraints are identical to gemini.json, with appropriate Mistral-specific defaults and descriptions.
unstract/sdk1/src/unstract/sdk1/adapters/embedding1/init.py Adds MistralEmbeddingAdapter to both the import list and all; alphabetical ordering is maintained.
unstract/sdk1/tests/test_mistral_embedding.py 28 tests covering registration, schema shape, prefix idempotency, mutation safety, and error-path validation; mirrors the Gemini embedding test suite for consistency.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant UI as User / UI Form
    participant Schema as mistral.json (JSON Schema)
    participant Adapter as MistralEmbeddingAdapter
    participant Params as MistralEmbeddingParameters
    participant LiteLLM as LiteLLM (mistral/ provider)

    UI->>Schema: Render config form
    Schema-->>UI: adapter_name, model, api_key, timeout fields
    UI->>Adapter: validate(adapter_metadata)
    Adapter->>Params: validate_model(metadata_copy)
    Params-->>Adapter: mistral/model prefix added idempotently
    Adapter->>Params: MistralEmbeddingParameters model_dump()
    Params-->>Adapter: validated dict
    Adapter-->>UI: validated adapter config
    Adapter->>LiteLLM: embedding call
    LiteLLM-->>Adapter: embedding vectors + cost via mistral provider
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant UI as User / UI Form
    participant Schema as mistral.json (JSON Schema)
    participant Adapter as MistralEmbeddingAdapter
    participant Params as MistralEmbeddingParameters
    participant LiteLLM as LiteLLM (mistral/ provider)

    UI->>Schema: Render config form
    Schema-->>UI: adapter_name, model, api_key, timeout fields
    UI->>Adapter: validate(adapter_metadata)
    Adapter->>Params: validate_model(metadata_copy)
    Params-->>Adapter: mistral/model prefix added idempotently
    Adapter->>Params: MistralEmbeddingParameters model_dump()
    Params-->>Adapter: validated dict
    Adapter-->>UI: validated adapter config
    Adapter->>LiteLLM: embedding call
    LiteLLM-->>Adapter: embedding vectors + cost via mistral provider
Loading

Reviews (2): Last reviewed commit: "Merge branch 'main' into feat/mistral-em..." | Re-trigger Greptile

@ahmedk20

Copy link
Copy Markdown
Contributor Author

@chandrasekharan-zipstack

@sonarqubecloud

Copy link
Copy Markdown

@chandrasekharan-zipstack chandrasekharan-zipstack merged commit f3484bb into Zipstack:main Jul 13, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] Add Mistral embedding adapter (mistral-embed)

3 participants