diff --git a/.env.example b/.env.example
index 4f475d5..7d2bca3 100644
--- a/.env.example
+++ b/.env.example
@@ -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=
@@ -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
diff --git a/.env.local.example b/.env.local.example
index b1d54c1..5e03a34 100644
--- a/.env.local.example
+++ b/.env.local.example
@@ -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=
@@ -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
diff --git a/CLAUDE.md b/CLAUDE.md
index ca59637..b288bf8 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -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`
diff --git a/README.md b/README.md
index 0b60481..08e8a06 100644
--- a/README.md
+++ b/README.md
@@ -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) |
@@ -128,7 +128,7 @@ Create `.env.local` in the repo root:
\** `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.
diff --git a/docs/superpowers/specs/2026-06-04-minimax-m3-default-design.md b/docs/superpowers/specs/2026-06-04-minimax-m3-default-design.md
new file mode 100644
index 0000000..d742466
--- /dev/null
+++ b/docs/superpowers/specs/2026-06-04-minimax-m3-default-design.md
@@ -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.
diff --git a/lib/__tests__/minimax-adapter.test.ts b/lib/__tests__/minimax-adapter.test.ts
index fc73914..0e1da34 100644
--- a/lib/__tests__/minimax-adapter.test.ts
+++ b/lib/__tests__/minimax-adapter.test.ts
@@ -42,7 +42,7 @@ test('MiniMax adapter strips tags and normalizes usage', async () => {
async () =>
new Response(
JSON.stringify({
- model: 'MiniMax-M2.7',
+ model: 'MiniMax-M3',
choices: [
{
message: {
@@ -64,7 +64,7 @@ test('MiniMax adapter strips 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,
@@ -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: {
@@ -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: {
diff --git a/lib/__tests__/provider-config.test.ts b/lib/__tests__/provider-config.test.ts
index 9ca2f41..4d9dd76 100644
--- a/lib/__tests__/provider-config.test.ts
+++ b/lib/__tests__/provider-config.test.ts
@@ -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', () => {
@@ -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',
});
}
);
@@ -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',
});
}
);
diff --git a/lib/__tests__/validation.test.ts b/lib/__tests__/validation.test.ts
index 23b8cf8..bdeb6d5 100644
--- a/lib/__tests__/validation.test.ts
+++ b/lib/__tests__/validation.test.ts
@@ -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');
}
);
});
diff --git a/lib/ai-providers/minimax-adapter.ts b/lib/ai-providers/minimax-adapter.ts
index 421f372..1a80cde 100644
--- a/lib/ai-providers/minimax-adapter.ts
+++ b/lib/ai-providers/minimax-adapter.ts
@@ -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) {
diff --git a/lib/ai-providers/provider-config.ts b/lib/ai-providers/provider-config.ts
index c93d080..ce5d365 100644
--- a/lib/ai-providers/provider-config.ts
+++ b/lib/ai-providers/provider-config.ts
@@ -5,7 +5,7 @@ const PROVIDER_ORDER: ProviderKey[] = ['grok', 'gemini', 'minimax'];
const PROVIDER_DEFAULT_MODELS: Record = {
grok: 'grok-4-1-fast-non-reasoning',
gemini: 'gemini-2.5-flash-lite',
- minimax: 'MiniMax-M2.7',
+ minimax: 'MiniMax-M3',
};
const PROVIDER_BEHAVIORS: Record = {