Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Text generation provider
AI_PROVIDER=minimax
NEXT_PUBLIC_AI_PROVIDER=minimax
AI_DEFAULT_MODEL=MiniMax-M2.7
AI_DEFAULT_MODEL=MiniMax-M3
MINIMAX_API_KEY=your_minimax_api_key_here
# Optional override if you need a non-default MiniMax API base URL.
MINIMAX_API_BASE_URL=
Expand All @@ -24,7 +24,7 @@ SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key_here
CSRF_SALT=generate_a_long_random_string_here

# Optional client-side AI model hint
NEXT_PUBLIC_AI_MODEL=MiniMax-M2.7
NEXT_PUBLIC_AI_MODEL=MiniMax-M3

# Optional features
NEXT_PUBLIC_ENABLE_TRANSLATION_SELECTOR=false
Expand Down
4 changes: 2 additions & 2 deletions .env.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Text generation provider
AI_PROVIDER=minimax
NEXT_PUBLIC_AI_PROVIDER=minimax
AI_DEFAULT_MODEL=MiniMax-M2.7
AI_DEFAULT_MODEL=MiniMax-M3
MINIMAX_API_KEY=your_minimax_api_key_here
# Optional override for self-hosted or alternate MiniMax gateways.
MINIMAX_API_BASE_URL=
Expand All @@ -23,7 +23,7 @@ SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key_here
CSRF_SALT=generate_a_long_random_string_here

# Optional client-side AI model hint
NEXT_PUBLIC_AI_MODEL=MiniMax-M2.7
NEXT_PUBLIC_AI_MODEL=MiniMax-M3

# Optional features
NEXT_PUBLIC_ENABLE_TRANSLATION_SELECTOR=false
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ Required in `.env.local`:
Also commonly needed:
- `AI_PROVIDER`: Server-side text provider selection (`minimax`, `grok`, or `gemini`)
- `NEXT_PUBLIC_AI_PROVIDER`: Set this to match `AI_PROVIDER` for consistent client/server provider behavior in Phase 1
- `AI_DEFAULT_MODEL`: Optional text model override (Phase 1 default: `MiniMax-M2.7`)
- `AI_DEFAULT_MODEL`: Optional text model override (current default: `MiniMax-M3`)
- `NEXT_PUBLIC_AI_MODEL`: Optional client-side model hint; it does not select the server provider by itself
- `GEMINI_API_KEY`: Still required for `app/api/generate-image/route.ts`

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Create `.env.local` in the repo root:
| `CSRF_SALT` | yes | Long random string used to sign CSRF tokens |
| `AI_PROVIDER` | recommended | `minimax`, `grok`, or `gemini`; determines which server-side text provider adapter is used |
| `NEXT_PUBLIC_AI_PROVIDER` | recommended | Set this to match `AI_PROVIDER` for consistent client/server provider behavior in Phase 1 |
| `AI_DEFAULT_MODEL` | recommended | Override provider default model (for Phase 1, `MiniMax-M2.7`) |
| `AI_DEFAULT_MODEL` | recommended | Override provider default model (currently `MiniMax-M3`) |
| `NEXT_PUBLIC_AI_MODEL` | optional | Client-side model hint for UI/config display; does not control server routing by itself |
| `NEXT_PUBLIC_APP_URL` | optional | Canonical app URL (defaults to `http://localhost:3000`) |
| `NEXT_PUBLIC_ENABLE_TRANSLATION_SELECTOR` | optional | Set to `true` to show the transcript translation dropdown (hidden otherwise) |
Expand All @@ -128,7 +128,7 @@ Create `.env.local` in the repo root:

<sup>\**</sup> `GEMINI_API_KEY` is still required if image generation should work, because `app/api/generate-image/route.ts` remains Gemini-backed.

> Recommended Phase 1 setup: `AI_PROVIDER=minimax`, `NEXT_PUBLIC_AI_PROVIDER=minimax`, `AI_DEFAULT_MODEL=MiniMax-M2.7`, `MINIMAX_API_KEY=...`. Keep `GEMINI_API_KEY` set if you want image generation, and optionally keep `XAI_API_KEY` available for Grok fallback/testing.
> Recommended setup: `AI_PROVIDER=minimax`, `NEXT_PUBLIC_AI_PROVIDER=minimax`, `AI_DEFAULT_MODEL=MiniMax-M3`, `MINIMAX_API_KEY=...`. Keep `GEMINI_API_KEY` set if you want image generation, and optionally keep `XAI_API_KEY` available for Grok fallback/testing.

> Generate a unique `CSRF_SALT` (e.g., `openssl rand -base64 32`). `UNLIMITED_VIDEO_USERS` entries are normalized to lowercase.

Expand Down
22 changes: 22 additions & 0 deletions docs/superpowers/specs/2026-06-04-minimax-m3-default-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# MiniMax M3 Default Model Design

## Context

LongCut currently defaults MiniMax text generation to `MiniMax-M2.7`. MiniMax has released `MiniMax-M3`, and the project should use M3 by default while preserving existing environment-variable overrides for rollback or experimentation.

## Scope

- Change source-controlled MiniMax default model strings from `MiniMax-M2.7` to `MiniMax-M3`.
- Update provider and validation tests that assert MiniMax defaults.
- Update active environment examples and active documentation.
- Do not change the MiniMax adapter API shape, base URL, provider fallback order, request payload structure, or generated build output.
- Do not edit unrelated existing worktree changes such as `package.json`.

## Approach

Use the existing provider configuration and adapter defaults. `AI_DEFAULT_MODEL`, `AI_FAST_MODEL`, `AI_PRO_MODEL`, and `NEXT_PUBLIC_AI_MODEL` remain supported as overrides. This makes rollback possible by setting `AI_DEFAULT_MODEL=MiniMax-M2.7` without code changes.

## Verification

- Run targeted tests for MiniMax adapter, provider config, and validation defaults.
- Run lint if the targeted tests pass and time permits.
8 changes: 4 additions & 4 deletions lib/__tests__/minimax-adapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ test('MiniMax adapter strips <think> tags and normalizes usage', async () => {
async () =>
new Response(
JSON.stringify({
model: 'MiniMax-M2.7',
model: 'MiniMax-M3',
choices: [
{
message: {
Expand All @@ -64,7 +64,7 @@ test('MiniMax adapter strips <think> tags and normalizes usage', async () => {

assert.equal(result.content, '{"ok":true}');
assert.equal(result.provider, 'minimax');
assert.equal(result.model, 'MiniMax-M2.7');
assert.equal(result.model, 'MiniMax-M3');
assert.deepEqual(result.usage, {
promptTokens: 11,
completionTokens: 7,
Expand Down Expand Up @@ -116,7 +116,7 @@ test('MiniMax adapter uses prompt-based schema compatibility when zodSchema is p

return new Response(
JSON.stringify({
model: 'MiniMax-M2.7',
model: 'MiniMax-M3',
choices: [
{
message: {
Expand Down Expand Up @@ -158,7 +158,7 @@ test('MiniMax adapter coerces metadata values to strings for API compatibility',

return new Response(
JSON.stringify({
model: 'MiniMax-M2.7',
model: 'MiniMax-M3',
choices: [
{
message: {
Expand Down
16 changes: 8 additions & 8 deletions lib/__tests__/provider-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ test('deterministic fallback order prefers Grok before Gemini before MiniMax', (
assert.deepEqual(getProviderFallbackOrder('grok'), ['gemini', 'minimax']);
});

test('provider default model returns MiniMax-M2.7 for MiniMax', () => {
assert.equal(getProviderDefaultModel('minimax'), 'MiniMax-M2.7');
test('provider default model returns MiniMax-M3 for MiniMax', () => {
assert.equal(getProviderDefaultModel('minimax'), 'MiniMax-M3');
});

test('provider model defaults derive fast and pro topic models from configured MiniMax provider', () => {
Expand All @@ -81,9 +81,9 @@ test('provider model defaults derive fast and pro topic models from configured M
},
() => {
assert.deepEqual(getProviderModelDefaults(), {
defaultModel: 'MiniMax-M2.7',
fastModel: 'MiniMax-M2.7',
proModel: 'MiniMax-M2.7',
defaultModel: 'MiniMax-M3',
fastModel: 'MiniMax-M3',
proModel: 'MiniMax-M3',
});
}
);
Expand All @@ -104,9 +104,9 @@ test('effective provider resolves to MiniMax when only MINIMAX_API_KEY is presen
() => {
assert.equal(getEffectiveProviderKey(), 'minimax');
assert.deepEqual(getProviderModelDefaults(), {
defaultModel: 'MiniMax-M2.7',
fastModel: 'MiniMax-M2.7',
proModel: 'MiniMax-M2.7',
defaultModel: 'MiniMax-M3',
fastModel: 'MiniMax-M3',
proModel: 'MiniMax-M3',
});
}
);
Expand Down
2 changes: 1 addition & 1 deletion lib/__tests__/validation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ test('model schema defaults to MiniMax model when only MINIMAX_API_KEY is presen
},
async () => {
const { modelSchema } = await importFreshValidationModule();
assert.equal(modelSchema.parse(undefined), 'MiniMax-M2.7');
assert.equal(modelSchema.parse(undefined), 'MiniMax-M3');
}
);
});
2 changes: 1 addition & 1 deletion lib/ai-providers/minimax-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { z } from 'zod';
import type { ProviderAdapter, ProviderGenerateParams, ProviderGenerateResult } from './types';

const PROVIDER_NAME = 'minimax';
const DEFAULT_MODEL = 'MiniMax-M2.7';
const DEFAULT_MODEL = 'MiniMax-M3';
const DEFAULT_BASE_URL = 'https://api.minimax.io/v1';

function buildAbortController(timeoutMs?: number) {
Expand Down
2 changes: 1 addition & 1 deletion lib/ai-providers/provider-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const PROVIDER_ORDER: ProviderKey[] = ['grok', 'gemini', 'minimax'];
const PROVIDER_DEFAULT_MODELS: Record<ProviderKey, string> = {
grok: 'grok-4-1-fast-non-reasoning',
gemini: 'gemini-2.5-flash-lite',
minimax: 'MiniMax-M2.7',
minimax: 'MiniMax-M3',
};

const PROVIDER_BEHAVIORS: Record<ProviderKey, ProviderBehavior> = {
Expand Down
Loading