From f5a9421b10cd62e4ecc4a387e83436285b35cfc2 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 12 Jan 2026 11:04:58 +0000 Subject: [PATCH] fix: auto-add minimax provider from auth --- src/agents/models-config.ts | 61 ++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/src/agents/models-config.ts b/src/agents/models-config.ts index d3fe04078..7982b40ec 100644 --- a/src/agents/models-config.ts +++ b/src/agents/models-config.ts @@ -3,11 +3,24 @@ import path from "node:path"; import { type ClawdbotConfig, loadConfig } from "../config/config.js"; import { resolveClawdbotAgentDir } from "./agent-paths.js"; +import { ensureAuthProfileStore, listProfilesForProvider } from "./auth-profiles.js"; +import { resolveEnvApiKey } from "./model-auth.js"; type ModelsConfig = NonNullable; type ProviderConfig = NonNullable[string]; const DEFAULT_MODE: NonNullable = "merge"; +const MINIMAX_API_BASE_URL = "https://api.minimax.io/anthropic"; +const MINIMAX_DEFAULT_MODEL_ID = "MiniMax-M2.1"; +const MINIMAX_DEFAULT_CONTEXT_WINDOW = 200000; +const MINIMAX_DEFAULT_MAX_TOKENS = 8192; +// Pricing: MiniMax doesn't publish public rates. Override in models.json for accurate costs. +const MINIMAX_API_COST = { + input: 15, + output: 60, + cacheRead: 2, + cacheWrite: 10, +}; function isRecord(value: unknown): value is Record { return Boolean(value && typeof value === "object" && !Array.isArray(value)); @@ -54,23 +67,55 @@ async function readJson(pathname: string): Promise { } } +function buildMinimaxApiProvider(): ProviderConfig { + return { + baseUrl: MINIMAX_API_BASE_URL, + api: "anthropic-messages", + models: [ + { + id: MINIMAX_DEFAULT_MODEL_ID, + name: "MiniMax M2.1", + reasoning: false, + input: ["text"], + cost: MINIMAX_API_COST, + contextWindow: MINIMAX_DEFAULT_CONTEXT_WINDOW, + maxTokens: MINIMAX_DEFAULT_MAX_TOKENS, + }, + ], + }; +} + +function resolveImplicitProviders(params: { + cfg: ClawdbotConfig; + agentDir: string; +}): ModelsConfig["providers"] { + const providers: Record = {}; + const minimaxEnv = resolveEnvApiKey("minimax"); + const authStore = ensureAuthProfileStore(params.agentDir); + const hasMinimaxProfile = + listProfilesForProvider(authStore, "minimax").length > 0; + if (minimaxEnv || hasMinimaxProfile) { + providers.minimax = buildMinimaxApiProvider(); + } + return providers; +} + export async function ensureClawdbotModelsJson( config?: ClawdbotConfig, agentDirOverride?: string, ): Promise<{ agentDir: string; wrote: boolean }> { const cfg = config ?? loadConfig(); - const providers = cfg.models?.providers; - if (!providers || Object.keys(providers).length === 0) { - const agentDir = agentDirOverride?.trim() - ? agentDirOverride.trim() - : resolveClawdbotAgentDir(); + const agentDir = agentDirOverride?.trim() + ? agentDirOverride.trim() + : resolveClawdbotAgentDir(); + const configuredProviders = cfg.models?.providers ?? {}; + const implicitProviders = resolveImplicitProviders({ cfg, agentDir }); + const providers = { ...implicitProviders, ...configuredProviders }; + if (Object.keys(providers).length === 0) { return { agentDir, wrote: false }; } const mode = cfg.models?.mode ?? DEFAULT_MODE; - const agentDir = agentDirOverride?.trim() - ? agentDirOverride.trim() - : resolveClawdbotAgentDir(); const targetPath = path.join(agentDir, "models.json"); let mergedProviders = providers;