This commit is contained in:
Marks 2026-01-29 14:00:51 -05:00 committed by GitHub
commit 0e14383298
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 631 additions and 0 deletions

View File

@ -46,6 +46,7 @@ See [Venice AI](/providers/venice).
- [GLM models](/providers/glm)
- [MiniMax](/providers/minimax)
- [Venius (Venice AI, privacy-focused)](/providers/venice)
- [Maple AI (TEE-based private inference)](/providers/maple)
- [Ollama (local models)](/providers/ollama)
## Transcription providers

204
docs/providers/maple.md Normal file
View File

@ -0,0 +1,204 @@
# Maple AI Provider
Maple AI provides TEE-based (Trusted Execution Environment) private inference using Confidential Computing. All inference runs in secure enclaves with end-to-end encryption and cryptographic attestations, ensuring your prompts and responses remain private.
## How It Works
Maple AI runs as a local proxy (desktop app or Docker container) that connects to secure TEE enclaves. Your data is encrypted end-to-end and never visible to Maple or any third party. Maple runs the largest, state-of-the-art open models and does not share any data back to the model creators. Sign up at [trymaple.ai](https://trymaple.ai) to get started. Maple Proxy requires a paid account with API credits.
1. **Desktop App or Docker**: Run the Maple proxy locally
2. **Local Proxy**: Default endpoint at `http://127.0.0.1:8080/v1`
3. **TEE Backend**: Requests are forwarded to Maple's secure enclaves
4. **Cryptographic Attestation**: Verify the enclave is running trusted code
## Features
- **End-to-end encryption**: Your prompts and responses are encrypted
- **Cryptographic attestations**: Verify the secure enclave integrity
- **Open-source verifiable code**: Audit the code running in the enclave
- **OpenAI-compatible API**: Standard `/v1` endpoints for easy integration
- **Streaming**: Required for all completions
## Setup
### 1. Install Maple Proxy
**Desktop App (Recommended)**
Download and run the Maple desktop app from [trymaple.ai/downloads](https://trymaple.ai/downloads). The proxy runs automatically on `http://127.0.0.1:8080/v1`.
**Docker**
```bash
docker run -p 8080:8080 \
-e MAPLE_BACKEND_URL=https://enclave.trymaple.ai \
-e MAPLE_ENABLE_CORS=true \
trymaple/proxy
```
### 2. Generate API Key
Open the Maple app and generate an API key. This key authenticates your requests to the local proxy.
### 3. Configure Moltbot
**Option A: Interactive Setup (Recommended)**
```bash
moltbot onboard --auth-choice maple-api-key
```
This will:
1. Prompt for your API key
2. Ask for the proxy URL (defaults to `http://127.0.0.1:8080/v1`)
3. Configure the provider automatically
**Option B: Environment Variable**
```bash
export MAPLE_API_KEY="your-api-key"
```
**Option C: Non-interactive**
```bash
moltbot onboard --non-interactive \
--auth-choice maple-api-key \
--token "your-api-key" \
--token-provider maple
```
### 4. Verify Setup
```bash
moltbot chat --model maple/llama-3.3-70b "Hello, are you working?"
```
## Available Models
| Model ID | Name | Use Case | Pricing |
|----------|------|----------|---------|
| `kimi-k2-thinking` | Kimi K2 Thinking | Complex agentic workflows, multi-step coding, web research | $4/$4 per M tokens |
| `gpt-oss-120b` | GPT OSS 120B | Creative writing, structured data | $4/$4 |
| `deepseek-r1-0528` | DeepSeek R1 | Research, advanced math, coding | $4/$4 |
| `qwen3-coder-480b` | Qwen3 Coder 480B | Agentic coding, large codebase analysis, browser automation | $4/$4 |
| `qwen3-vl-30b` | Qwen3 VL 30B | Image and video analysis, screenshot-to-code, OCR, GUI automation | $4/$4 |
| `llama-3.3-70b` | Llama 3.3 70B | General reasoning, conversation | $4/$4 |
| `gemma-3-27b` | Gemma 3 27B | General purpose, efficient | $10/$10 |
## Model Selection
Change your default model anytime:
```bash
moltbot models set maple/llama-3.3-70b
moltbot models set maple/deepseek-r1-0528
```
List available models:
```bash
moltbot models list | grep maple
```
## Configuration
### Custom Proxy URL
If running the proxy on a different host or port:
```yaml
# ~/.moltbot.yaml
models:
providers:
maple:
baseUrl: "http://192.168.1.100:8080/v1"
api: "openai-completions"
apiKey: "MAPLE_API_KEY"
```
### Docker Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `MAPLE_BACKEND_URL` | TEE enclave URL | `https://enclave.trymaple.ai` |
| `MAPLE_ENABLE_CORS` | Enable CORS headers | `false` |
| `RUST_LOG` | Log level | `info` |
## Usage Examples
```bash
# General chat
moltbot chat --model maple/llama-3.3-70b
# Advanced reasoning
moltbot chat --model maple/kimi-k2-thinking
# Research and coding
moltbot chat --model maple/deepseek-r1-0528
# Vision tasks
moltbot chat --model maple/qwen3-vl-30b
# Coding tasks
moltbot chat --model maple/qwen3-coder-480b
```
## Privacy and Security
### Why TEE?
Trusted Execution Environments (TEEs) provide hardware-level isolation:
- **Memory encryption**: Data is encrypted in memory
- **Attestation**: Cryptographic proof of what code is running
- **Isolation**: Even the host system cannot access enclave data
### Security Proof Attestation
Maple provides cryptographic attestations that prove the integrity of the secure enclave. You can view the current attestations at [trymaple.ai/proof](https://trymaple.ai/proof).
The Maple Proxy automatically verifies these attestations before connecting to the backend. If the attestation is invalid or tampered with, the proxy refuses to connect, similar to how SSL/TLS certificates protect web connections. This ensures you're always communicating with a genuine, unmodified Maple enclave.
### Verification
You can verify the enclave attestation to ensure:
1. The code running matches the open-source release
2. The TEE hardware is genuine
3. No tampering has occurred
Visit [trymaple.ai/proof](https://trymaple.ai/proof) to inspect the current attestation details.
## Troubleshooting
### Proxy not running
Ensure the Maple app is running or Docker container is active:
```bash
curl http://127.0.0.1:8080/health
```
### Connection refused
Check the proxy URL is correct and the service is running:
```bash
# Test connectivity
curl -H "Authorization: Bearer $MAPLE_API_KEY" \
http://127.0.0.1:8080/v1/models
```
### Model not available
The model list is fetched from the proxy. Ensure your Maple subscription includes the model you're trying to use.
## Links
- [Maple AI](https://trymaple.ai)
- [Downloads](https://trymaple.ai/downloads)
- [Security Proof](https://trymaple.ai/proof)
- [Proxy Documentation](https://blog.trymaple.ai/maple-proxy-documentation/)
- [Maple GitHub](https://github.com/OpenSecretCloud/Maple)
- [Maple Proxy GitHub](https://github.com/OpenSecretCloud/maple-proxy)

212
src/agents/maple-models.ts Normal file
View File

@ -0,0 +1,212 @@
import type { ModelDefinitionConfig } from "../config/types.js";
/**
* Maple AI Provider
*
* Maple AI is a privacy-focused AI provider that uses Confidential Computing (TEEs)
* to provide end-to-end encryption with cryptographic attestations. Users run the
* Maple desktop app or Docker container, then point their tools at the local proxy.
*
* Default proxy URL: http://127.0.0.1:8080/v1
*/
export const MAPLE_DEFAULT_BASE_URL = "http://127.0.0.1:8080/v1";
export const MAPLE_DEFAULT_MODEL_ID = "kimi-k2-thinking";
export const MAPLE_DEFAULT_MODEL_REF = `maple/${MAPLE_DEFAULT_MODEL_ID}`;
// Maple uses flat pricing per million tokens
export const MAPLE_DEFAULT_COST = {
input: 4,
output: 4,
cacheRead: 0,
cacheWrite: 0,
};
/**
* Static catalog of Maple AI models.
*
* All models run in TEE-based Confidential Computing environments,
* providing end-to-end encryption and cryptographic attestations.
*
* This catalog serves as a fallback when the Maple API is unreachable.
*/
export const MAPLE_MODEL_CATALOG = [
{
id: "kimi-k2-thinking",
name: "Kimi K2 Thinking",
description: "Complex agentic workflows, multi-step coding, web research",
reasoning: true,
input: ["text"] as const,
contextWindow: 262144,
maxTokens: 8192,
cost: { input: 4, output: 4, cacheRead: 0, cacheWrite: 0 },
},
{
id: "gpt-oss-120b",
name: "GPT OSS 120B",
description: "Creative writing, structured data",
reasoning: false,
input: ["text"] as const,
contextWindow: 131072,
maxTokens: 8192,
cost: { input: 4, output: 4, cacheRead: 0, cacheWrite: 0 },
},
{
id: "deepseek-r1-0528",
name: "DeepSeek R1",
description: "Research, advanced math, coding",
reasoning: true,
input: ["text"] as const,
contextWindow: 131072,
maxTokens: 8192,
cost: { input: 4, output: 4, cacheRead: 0, cacheWrite: 0 },
},
{
id: "qwen3-coder-480b",
name: "Qwen3 Coder 480B",
description: "Agentic coding, large codebase analysis, browser automation",
reasoning: false,
input: ["text"] as const,
contextWindow: 131072,
maxTokens: 8192,
cost: { input: 4, output: 4, cacheRead: 0, cacheWrite: 0 },
},
{
id: "qwen3-vl-30b",
name: "Qwen3 VL 30B",
description: "Image and video analysis, screenshot-to-code, OCR, GUI automation",
reasoning: false,
input: ["text", "image"] as const,
contextWindow: 262144,
maxTokens: 8192,
cost: { input: 4, output: 4, cacheRead: 0, cacheWrite: 0 },
},
{
id: "llama-3.3-70b",
name: "Llama 3.3 70B",
description: "General reasoning, conversation",
reasoning: false,
input: ["text"] as const,
contextWindow: 131072,
maxTokens: 8192,
cost: { input: 4, output: 4, cacheRead: 0, cacheWrite: 0 },
},
{
id: "gemma-3-27b",
name: "Gemma 3 27B",
description: "General purpose, efficient",
reasoning: false,
input: ["text"] as const,
contextWindow: 131072,
maxTokens: 8192,
cost: { input: 10, output: 10, cacheRead: 0, cacheWrite: 0 },
},
] as const;
export type MapleCatalogEntry = (typeof MAPLE_MODEL_CATALOG)[number];
/**
* Build a ModelDefinitionConfig from a Maple catalog entry.
*/
export function buildMapleModelDefinition(entry: MapleCatalogEntry): ModelDefinitionConfig {
return {
id: entry.id,
name: entry.name,
reasoning: entry.reasoning,
input: [...entry.input],
cost: entry.cost,
contextWindow: entry.contextWindow,
maxTokens: entry.maxTokens,
};
}
// Maple API response types (OpenAI-compatible)
interface MapleModel {
id: string;
object: string;
owned_by?: string;
}
interface MapleModelsResponse {
object: string;
data: MapleModel[];
}
/**
* Discover models from Maple API with fallback to static catalog.
* Requires authentication (Bearer token).
*/
export async function discoverMapleModels(params?: {
baseUrl?: string;
apiKey?: string;
}): Promise<ModelDefinitionConfig[]> {
// Skip API discovery in test environment
if (process.env.NODE_ENV === "test" || process.env.VITEST) {
return MAPLE_MODEL_CATALOG.map(buildMapleModelDefinition);
}
const baseUrl = params?.baseUrl ?? MAPLE_DEFAULT_BASE_URL;
const apiKey = params?.apiKey;
// If no API key, return static catalog
if (!apiKey) {
return MAPLE_MODEL_CATALOG.map(buildMapleModelDefinition);
}
try {
const response = await fetch(`${baseUrl}/models`, {
headers: {
Authorization: `Bearer ${apiKey}`,
},
signal: AbortSignal.timeout(5000),
});
if (!response.ok) {
console.warn(
`[maple-models] Failed to discover models: HTTP ${response.status}, using static catalog`,
);
return MAPLE_MODEL_CATALOG.map(buildMapleModelDefinition);
}
const data = (await response.json()) as MapleModelsResponse;
if (!Array.isArray(data.data) || data.data.length === 0) {
console.warn("[maple-models] No models found from API, using static catalog");
return MAPLE_MODEL_CATALOG.map(buildMapleModelDefinition);
}
// Merge discovered models with catalog metadata
const catalogById = new Map<string, MapleCatalogEntry>(
MAPLE_MODEL_CATALOG.map((m) => [m.id, m]),
);
const models: ModelDefinitionConfig[] = [];
for (const apiModel of data.data) {
const catalogEntry = catalogById.get(apiModel.id);
if (catalogEntry) {
// Use catalog metadata for known models
models.push(buildMapleModelDefinition(catalogEntry));
} else {
// Create definition for newly discovered models not in catalog
const isReasoning =
apiModel.id.toLowerCase().includes("thinking") ||
apiModel.id.toLowerCase().includes("reason") ||
apiModel.id.toLowerCase().includes("r1");
models.push({
id: apiModel.id,
name: apiModel.id,
reasoning: isReasoning,
input: ["text"],
cost: MAPLE_DEFAULT_COST,
contextWindow: 128000,
maxTokens: 8192,
});
}
}
return models.length > 0 ? models : MAPLE_MODEL_CATALOG.map(buildMapleModelDefinition);
} catch (error) {
console.warn(`[maple-models] Discovery failed: ${String(error)}, using static catalog`);
return MAPLE_MODEL_CATALOG.map(buildMapleModelDefinition);
}
}

View File

@ -284,6 +284,7 @@ export function resolveEnvApiKey(provider: string): EnvApiKeyResult | null {
xiaomi: "XIAOMI_API_KEY",
synthetic: "SYNTHETIC_API_KEY",
venice: "VENICE_API_KEY",
maple: "MAPLE_API_KEY",
mistral: "MISTRAL_API_KEY",
opencode: "OPENCODE_API_KEY",
};

View File

@ -13,6 +13,7 @@ import {
SYNTHETIC_MODEL_CATALOG,
} from "./synthetic-models.js";
import { discoverVeniceModels, VENICE_BASE_URL } from "./venice-models.js";
import { discoverMapleModels, MAPLE_DEFAULT_BASE_URL } from "./maple-models.js";
type ModelsConfig = NonNullable<MoltbotConfig["models"]>;
export type ProviderConfig = NonNullable<ModelsConfig["providers"]>[string];
@ -379,6 +380,15 @@ async function buildVeniceProvider(): Promise<ProviderConfig> {
};
}
async function buildMapleProvider(params?: { apiKey?: string }): Promise<ProviderConfig> {
const models = await discoverMapleModels({ apiKey: params?.apiKey });
return {
baseUrl: MAPLE_DEFAULT_BASE_URL,
api: "openai-completions",
models,
};
}
async function buildOllamaProvider(): Promise<ProviderConfig> {
const models = await discoverOllamaModels();
return {
@ -431,6 +441,13 @@ export async function resolveImplicitProviders(params: {
providers.venice = { ...(await buildVeniceProvider()), apiKey: veniceKey };
}
const mapleKey =
resolveEnvApiKeyVarName("maple") ??
resolveApiKeyFromProfiles({ provider: "maple", store: authStore });
if (mapleKey) {
providers.maple = { ...(await buildMapleProvider({ apiKey: mapleKey })), apiKey: mapleKey };
}
const qwenProfiles = listProfilesForProvider(authStore, "qwen-portal");
if (qwenProfiles.length > 0) {
providers["qwen-portal"] = {

View File

@ -21,6 +21,7 @@ export type AuthChoiceGroupId =
| "minimax"
| "synthetic"
| "venice"
| "maple"
| "qwen";
export type AuthChoiceGroup = {
@ -72,6 +73,12 @@ const AUTH_CHOICE_GROUP_DEFS: {
hint: "Privacy-focused (uncensored models)",
choices: ["venice-api-key"],
},
{
value: "maple",
label: "Maple AI",
hint: "TEE-based private inference",
choices: ["maple-api-key"],
},
{
value: "google",
label: "Google",
@ -154,6 +161,11 @@ export function buildAuthChoiceOptions(params: {
label: "Venice AI API key",
hint: "Privacy-focused inference (uncensored models)",
});
options.push({
value: "maple-api-key",
label: "Maple AI API key",
hint: "TEE-based private inference (end-to-end encrypted)",
});
options.push({
value: "github-copilot",
label: "GitHub Copilot (GitHub device login)",

View File

@ -25,6 +25,8 @@ import {
applySyntheticProviderConfig,
applyVeniceConfig,
applyVeniceProviderConfig,
applyMapleConfig,
applyMapleProviderConfig,
applyVercelAiGatewayConfig,
applyVercelAiGatewayProviderConfig,
applyXiaomiConfig,
@ -35,6 +37,7 @@ import {
OPENROUTER_DEFAULT_MODEL_REF,
SYNTHETIC_DEFAULT_MODEL_REF,
VENICE_DEFAULT_MODEL_REF,
MAPLE_DEFAULT_MODEL_REF,
VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF,
XIAOMI_DEFAULT_MODEL_REF,
setGeminiApiKey,
@ -44,6 +47,7 @@ import {
setOpenrouterApiKey,
setSyntheticApiKey,
setVeniceApiKey,
setMapleApiKey,
setVercelAiGatewayApiKey,
setXiaomiApiKey,
setZaiApiKey,
@ -89,6 +93,8 @@ export async function applyAuthChoiceApiProviders(
authChoice = "synthetic-api-key";
} else if (params.opts.tokenProvider === "venice") {
authChoice = "venice-api-key";
} else if (params.opts.tokenProvider === "maple") {
authChoice = "maple-api-key";
} else if (params.opts.tokenProvider === "opencode") {
authChoice = "opencode-zen";
}
@ -576,6 +582,78 @@ export async function applyAuthChoiceApiProviders(
return { config: nextConfig, agentModelOverride };
}
if (authChoice === "maple-api-key") {
let hasCredential = false;
let baseUrl: string | undefined;
if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "maple") {
await setMapleApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir);
hasCredential = true;
}
if (!hasCredential) {
await params.prompter.note(
[
"Maple AI provides TEE-based private inference with end-to-end encryption.",
"Download the Maple desktop app at: https://trymaple.ai/downloads",
"Run the app or Docker container, then configure the proxy URL.",
"Default URL: http://127.0.0.1:8080/v1",
"Generate your API key within the Maple app.",
].join("\n"),
"Maple AI",
);
}
const envKey = resolveEnvApiKey("maple");
if (envKey) {
const useExisting = await params.prompter.confirm({
message: `Use existing MAPLE_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,
initialValue: true,
});
if (useExisting) {
await setMapleApiKey(envKey.apiKey, params.agentDir);
hasCredential = true;
}
}
if (!hasCredential) {
const key = await params.prompter.text({
message: "Enter Maple AI API key",
validate: validateApiKeyInput,
});
await setMapleApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
}
// Ask for base URL (with default)
const customUrl = await params.prompter.text({
message: "Enter Maple proxy URL (press Enter for default)",
placeholder: "http://127.0.0.1:8080/v1",
});
if (customUrl && String(customUrl).trim()) {
baseUrl = String(customUrl).trim();
}
nextConfig = applyAuthProfileConfig(nextConfig, {
profileId: "maple:default",
provider: "maple",
mode: "api_key",
});
{
const applied = await applyDefaultModelChoice({
config: nextConfig,
setDefaultModel: params.setDefaultModel,
defaultModel: MAPLE_DEFAULT_MODEL_REF,
applyDefaultConfig: (config) => applyMapleConfig(config, { baseUrl }),
applyProviderConfig: (config) => applyMapleProviderConfig(config, { baseUrl }),
noteDefault: MAPLE_DEFAULT_MODEL_REF,
noteAgentModel,
prompter: params.prompter,
});
nextConfig = applied.config;
agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
}
return { config: nextConfig, agentModelOverride };
}
if (authChoice === "opencode-zen") {
let hasCredential = false;
if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "opencode") {

View File

@ -21,6 +21,7 @@ const PREFERRED_PROVIDER_BY_AUTH_CHOICE: Partial<Record<AuthChoice, string>> = {
"xiaomi-api-key": "xiaomi",
"synthetic-api-key": "synthetic",
"venice-api-key": "venice",
"maple-api-key": "maple",
"github-copilot": "github-copilot",
"copilot-proxy": "copilot-proxy",
"minimax-cloud": "minimax",

View File

@ -11,6 +11,12 @@ import {
VENICE_DEFAULT_MODEL_REF,
VENICE_MODEL_CATALOG,
} from "../agents/venice-models.js";
import {
buildMapleModelDefinition,
MAPLE_DEFAULT_BASE_URL,
MAPLE_DEFAULT_MODEL_REF,
MAPLE_MODEL_CATALOG,
} from "../agents/maple-models.js";
import type { MoltbotConfig } from "../config/config.js";
import {
OPENROUTER_DEFAULT_MODEL_REF,
@ -484,6 +490,85 @@ export function applyVeniceConfig(cfg: MoltbotConfig): MoltbotConfig {
};
}
/**
* Apply Maple provider configuration without changing the default model.
* Registers Maple models and sets up the provider, but preserves existing model selection.
*/
export function applyMapleProviderConfig(
cfg: MoltbotConfig,
params?: { baseUrl?: string },
): MoltbotConfig {
const models = { ...cfg.agents?.defaults?.models };
models[MAPLE_DEFAULT_MODEL_REF] = {
...models[MAPLE_DEFAULT_MODEL_REF],
alias: models[MAPLE_DEFAULT_MODEL_REF]?.alias ?? "Kimi K2 Thinking",
};
const providers = { ...cfg.models?.providers };
const existingProvider = providers.maple;
const existingModels = Array.isArray(existingProvider?.models) ? existingProvider.models : [];
const mapleModels = MAPLE_MODEL_CATALOG.map(buildMapleModelDefinition);
const mergedModels = [
...existingModels,
...mapleModels.filter((model) => !existingModels.some((existing) => existing.id === model.id)),
];
const { apiKey: existingApiKey, ...existingProviderRest } = (existingProvider ?? {}) as Record<
string,
unknown
> as { apiKey?: string };
const resolvedApiKey = typeof existingApiKey === "string" ? existingApiKey : undefined;
const normalizedApiKey = resolvedApiKey?.trim();
const baseUrl = params?.baseUrl ?? MAPLE_DEFAULT_BASE_URL;
providers.maple = {
...existingProviderRest,
baseUrl,
api: "openai-completions",
...(normalizedApiKey ? { apiKey: normalizedApiKey } : {}),
models: mergedModels.length > 0 ? mergedModels : mapleModels,
};
return {
...cfg,
agents: {
...cfg.agents,
defaults: {
...cfg.agents?.defaults,
models,
},
},
models: {
mode: cfg.models?.mode ?? "merge",
providers,
},
};
}
/**
* Apply Maple provider configuration AND set Maple as the default model.
* Use this when Maple is the primary provider choice during onboarding.
*/
export function applyMapleConfig(cfg: MoltbotConfig, params?: { baseUrl?: string }): MoltbotConfig {
const next = applyMapleProviderConfig(cfg, params);
const existingModel = next.agents?.defaults?.model;
return {
...next,
agents: {
...next.agents,
defaults: {
...next.agents?.defaults,
model: {
...(existingModel && "fallbacks" in (existingModel as Record<string, unknown>)
? {
fallbacks: (existingModel as { fallbacks?: string[] }).fallbacks,
}
: undefined),
primary: MAPLE_DEFAULT_MODEL_REF,
},
},
},
};
}
export function applyAuthProfileConfig(
cfg: MoltbotConfig,
params: {

View File

@ -112,6 +112,19 @@ export async function setVeniceApiKey(key: string, agentDir?: string) {
});
}
export async function setMapleApiKey(key: string, agentDir?: string) {
// Write to resolved agent dir so gateway finds credentials on startup.
upsertAuthProfile({
profileId: "maple:default",
credential: {
type: "api_key",
provider: "maple",
key,
},
agentDir: resolveAuthAgentDir(agentDir),
});
}
export const ZAI_DEFAULT_MODEL_REF = "zai/glm-4.7";
export const XIAOMI_DEFAULT_MODEL_REF = "xiaomi/mimo-v2-flash";
export const OPENROUTER_DEFAULT_MODEL_REF = "openrouter/auto";

View File

@ -3,6 +3,7 @@ export {
SYNTHETIC_DEFAULT_MODEL_REF,
} from "../agents/synthetic-models.js";
export { VENICE_DEFAULT_MODEL_ID, VENICE_DEFAULT_MODEL_REF } from "../agents/venice-models.js";
export { MAPLE_DEFAULT_MODEL_ID, MAPLE_DEFAULT_MODEL_REF } from "../agents/maple-models.js";
export {
applyAuthProfileConfig,
applyKimiCodeConfig,
@ -15,6 +16,8 @@ export {
applySyntheticProviderConfig,
applyVeniceConfig,
applyVeniceProviderConfig,
applyMapleConfig,
applyMapleProviderConfig,
applyVercelAiGatewayConfig,
applyVercelAiGatewayProviderConfig,
applyXiaomiConfig,
@ -45,6 +48,7 @@ export {
setOpenrouterApiKey,
setSyntheticApiKey,
setVeniceApiKey,
setMapleApiKey,
setVercelAiGatewayApiKey,
setXiaomiApiKey,
setZaiApiKey,

View File

@ -17,6 +17,7 @@ export type AuthChoice =
| "kimi-code-api-key"
| "synthetic-api-key"
| "venice-api-key"
| "maple-api-key"
| "codex-cli"
| "apiKey"
| "gemini-api-key"
@ -72,6 +73,8 @@ export type OnboardOptions = {
minimaxApiKey?: string;
syntheticApiKey?: string;
veniceApiKey?: string;
mapleApiKey?: string;
mapleBaseUrl?: string;
opencodeZenApiKey?: string;
gatewayPort?: number;
gatewayBind?: GatewayBind;