feat: add MiniMax provider and fix ANTHROPIC_BASE_URL not passed to SDK#103
Conversation
- Add `MinimaxProvider` (`src/providers/minimax.ts`) that calls MiniMax's
Anthropic-compatible API via raw `fetch` instead of the Anthropic SDK.
The SDK auto-injects `x-stainless-*` headers that MiniMax rejects with 403;
using `fetch` directly avoids this entirely.
- Fix `AnthropicProvider` constructor to accept an optional `baseURL` and
forward it to `new Anthropic({ apiKey, baseURL })`. Previously the provider
always connected to `api.anthropic.com` even when `ANTHROPIC_BASE_URL` was
set in `.env`, because `getMergedEnv()` returns a plain JS object that the
Anthropic SDK never sees.
- `detectProvider()` in `config.ts`:
- Checks `MINIMAX_API_KEY` first and returns `provider: "minimax"`.
- Propagates `ANTHROPIC_BASE_URL` as `baseURL` in the Anthropic config.
- Update `ProviderConfig` in `types.ts` to include optional `baseURL` field.
- Update `ProviderType` union to include `"minimax"`.
- Update `VALID_PROVIDERS` set in `config.ts` to include `"minimax"`.
📝 WalkthroughWalkthroughThese changes introduce support for a new Minimax provider by adding configuration detection for Changes
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~23 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/providers/minimax.ts (1)
3-16: Trim the top-level WHAT-comment block and keep only essential rationale.Most of this section duplicates behavior already obvious from class/method names and constructor fields; consider moving env-var details to README/docs.
As per coding guidelines, "Use clear, self-documenting variable and function names instead of code comments explaining WHAT".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/providers/minimax.ts` around lines 3 - 16, Trim the long top-level comment in the MiniMax provider to a concise rationale: keep a one- or two-line note that this provider uses raw fetch to avoid Anthropic SDK headers (reference the MiniMax class/constructor), remove redundant WHAT/details already expressed by clear names, and move environment variable usage and defaults (MINIMAX_API_KEY, MINIMAX_MODEL, MAX_TOKENS, MINIMAX_BASE_URL) into README or the constructor JSDoc if you want inline docs; ensure the MiniMax provider constructor and its parameter names remain self-explanatory after removing the verbose block.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/config.ts`:
- Around line 47-54: The minimax branch in detectProvider currently returns a
config missing the base URL, so forward env["MINIMAX_BASE_URL"] into the
provider config; update the minimax return object in detectProvider to include a
baseURL (read from env["MINIMAX_BASE_URL"] or undefined/default) so downstream
provider construction receives and uses MINIMAX_BASE_URL consistently (refer to
detectProvider and the minimax provider config keys like provider, model,
maxTokens).
In `@src/providers/minimax.ts`:
- Around line 42-55: The fetch call that posts to MiniMax must use an
AbortController to avoid hanging: create an AbortController before calling
fetch, start a timeout (e.g., setTimeout using the provider's desired timeout
value) that calls controller.abort(), pass controller.signal in the fetch
options, and clear the timeout after fetch completes; update the code around the
POST request that references this.apiKey / this.model / this.maxTokens /
systemPrompt / userPrompt to include the signal and add error handling for an
AbortError so the provider method returns a controlled error/path when the
request times out.
---
Nitpick comments:
In `@src/providers/minimax.ts`:
- Around line 3-16: Trim the long top-level comment in the MiniMax provider to a
concise rationale: keep a one- or two-line note that this provider uses raw
fetch to avoid Anthropic SDK headers (reference the MiniMax class/constructor),
remove redundant WHAT/details already expressed by clear names, and move
environment variable usage and defaults (MINIMAX_API_KEY, MINIMAX_MODEL,
MAX_TOKENS, MINIMAX_BASE_URL) into README or the constructor JSDoc if you want
inline docs; ensure the MiniMax provider constructor and its parameter names
remain self-explanatory after removing the verbose block.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 1b88b4dc-8d07-4dba-839e-83c2268b1061
📒 Files selected for processing (5)
src/config.tssrc/providers/anthropic.tssrc/providers/index.tssrc/providers/minimax.tssrc/types.ts
| // MiniMax: Anthropic-compatible API, requires raw fetch to avoid SDK stainless headers | ||
| if (env["MINIMAX_API_KEY"]) { | ||
| return { | ||
| provider: "minimax", | ||
| model: env["MINIMAX_MODEL"] || "MiniMax-M2.7", | ||
| maxTokens, | ||
| }; | ||
| } |
There was a problem hiding this comment.
Forward MINIMAX_BASE_URL in provider config.
detectProvider builds minimax config without baseURL. That prevents consistent use of ~/.agentmemory/.env-sourced base URLs through the same config pipeline used elsewhere.
🔧 Proposed fix
if (env["MINIMAX_API_KEY"]) {
return {
provider: "minimax",
model: env["MINIMAX_MODEL"] || "MiniMax-M2.7",
maxTokens,
+ baseURL: env["MINIMAX_BASE_URL"],
};
}Also wire this through provider construction:
// src/providers/index.ts
- return new MinimaxProvider(requireEnvVar("MINIMAX_API_KEY"), config.model, config.maxTokens);
+ return new MinimaxProvider(
+ requireEnvVar("MINIMAX_API_KEY"),
+ config.model,
+ config.maxTokens,
+ config.baseURL,
+ );
// src/providers/minimax.ts
- constructor(apiKey: string, model: string, maxTokens: number) {
+ constructor(apiKey: string, model: string, maxTokens: number, baseURL?: string) {
this.apiKey = apiKey
this.model = model
this.maxTokens = maxTokens
- this.baseUrl = process.env['MINIMAX_BASE_URL'] || 'https://api.minimaxi.com/anthropic'
+ this.baseUrl = baseURL || 'https://api.minimaxi.com/anthropic'
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/config.ts` around lines 47 - 54, The minimax branch in detectProvider
currently returns a config missing the base URL, so forward
env["MINIMAX_BASE_URL"] into the provider config; update the minimax return
object in detectProvider to include a baseURL (read from env["MINIMAX_BASE_URL"]
or undefined/default) so downstream provider construction receives and uses
MINIMAX_BASE_URL consistently (refer to detectProvider and the minimax provider
config keys like provider, model, maxTokens).
| const response = await fetch(url, { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| 'x-api-key': this.apiKey, | ||
| 'anthropic-version': '2023-06-01', | ||
| }, | ||
| body: JSON.stringify({ | ||
| model: this.model, | ||
| max_tokens: this.maxTokens, | ||
| system: systemPrompt, | ||
| messages: [{ role: 'user', content: userPrompt }], | ||
| }), | ||
| }) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify whether MiniMax outbound calls currently use cancellation/timeout primitives.
# Expected today: a fetch call exists, but no `signal:`/AbortController wiring in this file.
set -euo pipefail
rg -n -C3 'fetch\(|signal:|AbortController' src/providers/minimax.tsRepository: rohitg00/agentmemory
Length of output: 336
🏁 Script executed:
cat -n src/providers/minimax.tsRepository: rohitg00/agentmemory
Length of output: 2740
Add a timeout/cancellation signal to the MiniMax fetch call.
The fetch() call at lines 42–55 lacks an AbortController signal. If the upstream service stalls or hangs, the operation will block indefinitely with no recovery mechanism.
⏱️ Proposed implementation
private async call(systemPrompt: string, userPrompt: string): Promise<string> {
const url = `${this.baseUrl}/v1/messages`
- const response = await fetch(url, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'x-api-key': this.apiKey,
- 'anthropic-version': '2023-06-01',
- },
- body: JSON.stringify({
- model: this.model,
- max_tokens: this.maxTokens,
- system: systemPrompt,
- messages: [{ role: 'user', content: userPrompt }],
- }),
- })
+ const controller = new AbortController()
+ const timeout = setTimeout(() => controller.abort(), 30_000)
+ let response: Response
+ try {
+ response = await fetch(url, {
+ method: 'POST',
+ signal: controller.signal,
+ headers: {
+ 'Content-Type': 'application/json',
+ 'x-api-key': this.apiKey,
+ 'anthropic-version': '2023-06-01',
+ },
+ body: JSON.stringify({
+ model: this.model,
+ max_tokens: this.maxTokens,
+ system: systemPrompt,
+ messages: [{ role: 'user', content: userPrompt }],
+ }),
+ })
+ } finally {
+ clearTimeout(timeout)
+ }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/providers/minimax.ts` around lines 42 - 55, The fetch call that posts to
MiniMax must use an AbortController to avoid hanging: create an AbortController
before calling fetch, start a timeout (e.g., setTimeout using the provider's
desired timeout value) that calls controller.abort(), pass controller.signal in
the fetch options, and clear the timeout after fetch completes; update the code
around the POST request that references this.apiKey / this.model /
this.maxTokens / systemPrompt / userPrompt to include the signal and add error
handling for an AbortError so the provider method returns a controlled
error/path when the request times out.
Problem
Two related issues prevented agentmemory from working with MiniMax's Anthropic-compatible API:
x-stainless-*headers rejected with 403 — The Anthropic SDK automatically injectsx-stainless-arch,x-stainless-os,x-stainless-runtime, etc. MiniMax rejects these with HTTP 403.ANTHROPIC_BASE_URLsilently ignored —AnthropicProviderconstructed the SDK client asnew Anthropic({ apiKey })without forwardingbaseURL. The value in.envnever reachedprocess.env, so the client always connected toapi.anthropic.com.Solution
New
MinimaxProvider(src/providers/minimax.ts): usesfetchdirectly, bypassing the SDK andits stainless headers. Reads
MINIMAX_API_KEY,MINIMAX_MODEL(default:MiniMax-M2.7),MAX_TOKENS, and optionallyMINIMAX_BASE_URL.Fix
AnthropicProvider: constructor now accepts optionalbaseURLand passes it tonew Anthropic({ apiKey, baseURL }).config.ts: detectsMINIMAX_API_KEYbeforeANTHROPIC_API_KEY; propagatesANTHROPIC_BASE_URLto Anthropic config; adds"minimax"toVALID_PROVIDERS.types.ts: addsbaseURL?: stringtoProviderConfig; adds"minimax"toProviderType.Testing
Verified end-to-end on Windows (Claude Code extension) with agentmemory worker in WSL,
using MiniMax's API. Compression and session summarization both work correctly.
Summary by CodeRabbit
Release Notes