Skip to content

feat(ai): add Mistral provider and support optional API key for local endpoints#214

Open
FloChab wants to merge 2 commits into
reqcore-inc:mainfrom
FloChab:feat/mistral-ai-provider
Open

feat(ai): add Mistral provider and support optional API key for local endpoints#214
FloChab wants to merge 2 commits into
reqcore-inc:mainfrom
FloChab:feat/mistral-ai-provider

Conversation

@FloChab

@FloChab FloChab commented Jun 22, 2026

Copy link
Copy Markdown

Summary

  • What does this PR change?

    1. Adds Mistral AI as a supported provider

    • Integrates @ai-sdk/mistral for official Mistral API support
    • Adds Mistral models to PROVIDER_REGISTRY:
      • mistral-large-latest (powerful)
      • mistral-medium-latest (recommended)
      • mistral-small-latest (cheap)
    • Enables users to select Mistral from the AI configuration UI

    2. Allows optional API key for custom endpoints

    • Custom OpenAI-compatible endpoints (Ollama, LM Studio, vLLM, etc.) no longer require an API key
    • Frontend validation updated to skip API key requirement for openai_compatible provider
    • Backend schema validation now accepts empty API key strings
    • API key is always included in request body (even if empty) to maintain schema compatibility
  • Why is this needed?

    For Mistral: offer the ability to use Mistral AI models alongside existing providers (OpenAI, Anthropic, Google) for more choice and European-based privacy-focused options.

    For optional API key: Local AI endpoints don't necessary require authentication, but the previous validation forced users to enter a dummy key. This creates a better UX for local/development setups while maintaining security for cloud providers.


Type of change

  • Feature
  • Bug fix

Validation

  • I tested locally - Verified:

    • Mistral provider configuration and connection test
    • Custom endpoint (Ollama) works without API key
    • Existing providers (OpenAI, Anthropic, Google) still function correctly
    • Frontend validation properly enables/disables save button
  • I added/updated relevant documentation

  • I verified multi-tenant scoping and auth behavior for affected API paths (existing auth middleware unchanged)


DCO

  • All commits in this PR are signed off (Signed-off-by) via git commit -s

Summary by CodeRabbit

Release Notes

  • New Features

    • Mistral is now available as a supported AI provider option.
  • Improvements

    • Custom AI endpoint configurations can now be created without requiring an API key upfront.
    • API key validation for custom endpoints has been improved to better handle edge cases during configuration updates.

FloChab added 2 commits June 22, 2026 14:01
- Add Mistral to provider.ts (import, type, registry, createLanguageModel)
- Add Mistral to scoring.ts schemas (createAiConfigSchema, updateAiConfigSchema)
- Add @ai-sdk/mistral dependency

Signed-off-by: Florian Chab <fchabreiron@gmail.com>
- Update createAiConfigSchema and updateAiConfigSchema to accept empty API key (min:0)
- Modify createLanguageModel to handle empty API key for openai_compatible provider
- Update AiConfigForm validation to not require API key for custom endpoints
- Ensure API key is always included in request body (even if empty string)

This enables local endpoints (Ollama, LM Studio, vLLM, etc.) to work
without requiring an API key, while maintaining security for cloud providers.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>

Signed-off-by: Florian Chab <fchabreiron@gmail.com>
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds Mistral as a supported AI provider by introducing the @ai-sdk/mistral SDK dependency, registering a mistral entry in PROVIDER_REGISTRY, and adding a mistral case in createLanguageModel. Schemas and the frontend config form are updated to accept mistral and allow empty API keys for OpenAI-compatible endpoints.

Changes

Mistral Provider and API Key Handling

Layer / File(s) Summary
Schema and provider type contracts
server/utils/ai/provider.ts, server/utils/schemas/scoring.ts
SupportedProvider union gains 'mistral'. Both createAiConfigSchema and updateAiConfigSchema add 'mistral' to their provider enum and lower apiKey minimum length from 1 to 0.
Mistral registry entry and model instantiation
package.json, server/utils/ai/provider.ts
Adds @ai-sdk/mistral to dependencies, adds a mistral entry in PROVIDER_REGISTRY with metadata and model list, and adds a mistral case in createLanguageModel using createMistral({ apiKey }).
API key handling for OpenAI-compatible and form
server/utils/ai/provider.ts, app/components/AiConfigForm.vue
Removes the throw for an empty decrypted key when provider is openai_compatible, adds apiKey || 'dummy-key' fallback for the OpenAI client constructor, updates canSave to skip the API key requirement for openai_compatible during creation, and changes handleSave to include an empty string apiKey rather than omitting it.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 A new provider hops into the mix,
Mistral's winds now among my tricks!
Empty keys no longer block the way,
dummy-key saves the OpenAI day.
From schema down to form I bound—
min(0) keeps the path wide and sound! 🌬️

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the two main changes: adding Mistral provider support and enabling optional API keys for local endpoints, matching the changeset content.
Description check ✅ Passed The description covers all required sections: detailed summary of changes with reasoning, proper type of change selection, comprehensive validation checklist with specifics, and DCO confirmation. All critical sections are complete and substantive.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

@FloChab FloChab marked this pull request as ready for review June 22, 2026 13:30

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
server/utils/ai/provider.ts (1)

148-148: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider an empty string instead of 'dummy-key' for keyless endpoints.

Using 'dummy-key' may cause confusing error messages from the OpenAI SDK or endpoint logs when debugging authentication issues. An empty string (apiKey || '') conveys "no key provided" more clearly.

That said, this is a minor readability/debugging concern and the current approach is functionally correct for Ollama-style endpoints.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/utils/ai/provider.ts` at line 148, Replace the dummy key value with an
empty string in the apiKey field assignment. Instead of using 'dummy-key' as the
fallback value when apiKey is not provided, change it to an empty string. This
makes it clearer in logs and error messages that no API key was provided for
keyless endpoints, reducing confusion during debugging.
app/components/AiConfigForm.vue (1)

148-152: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Condition is always true since apiKey is always defined.

form.value.apiKey is initialized to '' on line 72, so form.value.apiKey !== undefined is always true. The condition could be removed, but since the intent is to always send apiKey (per PR objectives: "API key is always included in the request body"), the behavior is correct.

No change needed — just noting for clarity.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/components/AiConfigForm.vue` around lines 148 - 152, No change is
required for this code. The reviewer has noted that while the condition `if
(form.value.apiKey !== undefined)` in the body assignment is always true (since
form.value.apiKey is initialized to an empty string on line 72), this behavior
is intentional and correct according to the PR objectives which require the API
key to always be included in the request body. The condition could be optionally
removed for code clarity, but doing so is not necessary.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@app/components/AiConfigForm.vue`:
- Around line 148-152: No change is required for this code. The reviewer has
noted that while the condition `if (form.value.apiKey !== undefined)` in the
body assignment is always true (since form.value.apiKey is initialized to an
empty string on line 72), this behavior is intentional and correct according to
the PR objectives which require the API key to always be included in the request
body. The condition could be optionally removed for code clarity, but doing so
is not necessary.

In `@server/utils/ai/provider.ts`:
- Line 148: Replace the dummy key value with an empty string in the apiKey field
assignment. Instead of using 'dummy-key' as the fallback value when apiKey is
not provided, change it to an empty string. This makes it clearer in logs and
error messages that no API key was provided for keyless endpoints, reducing
confusion during debugging.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6a98bcd0-f2ef-45c2-881f-fbe35ead70e4

📥 Commits

Reviewing files that changed from the base of the PR and between 92a9832 and c265e70.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • app/components/AiConfigForm.vue
  • package.json
  • server/utils/ai/provider.ts
  • server/utils/schemas/scoring.ts

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.

1 participant