feat: add MiniMax as an AI-coach provider - #54
Merged
Merged
Conversation
MiniMax speaks the OpenAI-compatible Chat Completions API, so it slots into the existing provider-agnostic pattern (ResponsesClient + a per-provider Keychain store + the CoachClientResolver switch), same as OpenRouter/Gemini. - New MiniMaxClient: translating adapter for POST /v1/chat/completions — flat->nested tool conversion, stateful tool-call replay, tool_calls parsing, and <think>-block stripping so coach_response JSON parses. Deliberately omits cache_control, response_format, the OpenAI reasoning object, and provider routing (none documented for MiniMax's compat endpoint); relies on the promptInstruction system message + the orchestrator's JSON-repair loop. - New MiniMaxKeychainStore (separate service, coexists with other keys). - Wired .userMiniMaxKey through CoachProviderMode, MiniMaxModel presets, CoachFeatureFlags gating + status line, the three resolveClient sites, and the Settings provider/model/key UI. - MiniMax has no hosted web search, so the Web search toggle is hidden when MiniMax is active (and forced off on switch) — all other tool calls work. Tests: MiniMaxClientTests (endpoint/model, tool_calls parse, web_search drop, omits response_format/reasoning/provider, <think> stripping); OpenRouter suite still green.
Owner
|
I don't have any ways to check this either. Going to merge this and create an issue so that the user who requested can test and report after the Test Flight release. |
saksham2001
approved these changes
Jul 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Adds MiniMax as an AI-coach provider, alongside OpenAI, Gemini, and OpenRouter. It slots into the same provider-agnostic pattern already in the codebase (
ResponsesClient+ a per-provider Keychain store + theCoachClientResolverswitch), so the rest of the coach is unchanged.How it works
MiniMax speaks the OpenAI Chat Completions API, while this app speaks the OpenAI Responses API, so (exactly like
OpenRouterClient/GeminiClient) the newMiniMaxClientis a translating adapter rather than a base-URL swap. It:toolsshape, and replays tool calls statefully across the agent loop (Chat Completions is stateless, so it accumulatesmessagesper turn);<think>…</think>reasoning blocks from assistant content so thecoach_responseJSON parses cleanly;response_format,cache_control,reasoning, or provider-routing block — none are documented for MiniMax's compat endpoint. Output shape is enforced by the injectedpromptInstructionsystem message plus the orchestrator's existing JSON-repair loop (same fallback path OpenRouter uses).Endpoint:
POST https://api.minimax.io/v1/chat/completions,Authorization: Bearer <key>.Model selection (Settings)
When MiniMax is the active provider, the Model row shows the current MiniMax catalog (default MiniMax-M3; also M2.7 / M2.5 / M2.1 and their
-highspeedvariants, plus M2). The key is stored in its own Keychain service.Web search
MiniMax's compat endpoint exposes no hosted web search (its
web_searchis an MCP-only tool that an iOS app can't call over plain HTTP). So the Web search toggle is hidden when MiniMax is active (and forced off on switch), and the hostedweb_searchspec is dropped in the adapter. All other tools (retrieval, charts, analysis, memory, actions) work normally.Image input
Only MiniMax-M3 is multimodal, so the "Image input" toggle is shown only when M3 is selected and force-cleared if you switch to a text-only model.
Scope / wiring
Coach/MiniMax/MiniMaxClient.swift,Coach/MiniMax/MiniMaxKeychainStore.swift.userMiniMaxKeythroughCoachProviderMode,MiniMaxModelpresets,CoachFeatureFlags(gate + status line), the threeresolveClientsites (chat / summaries / notifications),SettingsView.coachTrailing, andCoachSettingsSection(provider option, model picker, key field).Testing done
MiniMaxClientTests(6): endpoint/model, tool-call parsing, hostedweb_searchdropped,response_format/reasoning/provideromitted,<think>stripping, and the stateful continuation replay (assistanttool_callsmessage re-inserted before thetoolresult).PulseLoopTestssuite passes (275 tests); existing OpenRouter suite still green.Everything above is compile- and unit-tested, but the wire protocol was built from MiniMax's docs and not exercised against a real key. Please confirm on device with a MiniMax key:
Ready · MiniMax-M3. A 401 would mean a Bearer token alone isn't enough (e.g. a GroupId is required) — the docs say Bearer-only, but this is the first thing to check.coach_responseJSON even thoughresponse_formatis omitted (prompt-instruction + JSON-repair only). This is the main behavioral risk.<think>…</think>text.Region note: the client uses the global host
api.minimax.io. China-region accounts useapi.minimaxi.com— there's a code comment at the endpoint marking where to flip it.