Skip to content

Commit 1c368ed

Browse files
authored
feat(models): add MiniMax OAuth provider flow (#549)
* fix(models): remove custom BYOK provider * fix(models): support minimax oauth and api key auth * fix(home): correct GitHub star CTA translation key * fix(models): default minimax to oauth login * fix(models): polish minimax provider oauth actions * fix(models): allow dismissing minimax oauth errors * fix(desktop): restore surface frame prop aliases * fix(models): align minimax oauth runtime config * fix(models): restore minimax oauth completion polling * fix(models): sync minimax oauth remove state * fix(models): harden minimax oauth review follow-ups * more fix
1 parent 12d2153 commit 1c368ed

31 files changed

Lines changed: 2320 additions & 397 deletions

apps/controller/openapi.json

Lines changed: 275 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"openapi": "3.1.0",
33
"info": {
4-
"title": "Nexu Controller API",
4+
"title": "nexu Controller API",
55
"version": "1.0.0"
66
},
77
"components": {
@@ -4788,9 +4788,31 @@
47884788
"type": "string",
47894789
"nullable": true
47904790
},
4791+
"authMode": {
4792+
"type": "string",
4793+
"enum": [
4794+
"apiKey",
4795+
"oauth"
4796+
]
4797+
},
47914798
"hasApiKey": {
47924799
"type": "boolean"
47934800
},
4801+
"hasOauthCredential": {
4802+
"type": "boolean"
4803+
},
4804+
"oauthRegion": {
4805+
"type": "string",
4806+
"nullable": true,
4807+
"enum": [
4808+
"global",
4809+
"cn"
4810+
]
4811+
},
4812+
"oauthEmail": {
4813+
"type": "string",
4814+
"nullable": true
4815+
},
47944816
"modelsJson": {
47954817
"type": "string",
47964818
"nullable": true
@@ -4832,7 +4854,20 @@
48324854
"parameters": [
48334855
{
48344856
"schema": {
4835-
"type": "string"
4857+
"type": "string",
4858+
"enum": [
4859+
"anthropic",
4860+
"openai",
4861+
"google",
4862+
"siliconflow",
4863+
"ppio",
4864+
"openrouter",
4865+
"minimax",
4866+
"kimi",
4867+
"glm",
4868+
"moonshot",
4869+
"zai"
4870+
]
48364871
},
48374872
"required": true,
48384873
"name": "providerId",
@@ -4859,6 +4894,13 @@
48594894
"displayName": {
48604895
"type": "string"
48614896
},
4897+
"authMode": {
4898+
"type": "string",
4899+
"enum": [
4900+
"apiKey",
4901+
"oauth"
4902+
]
4903+
},
48624904
"modelsJson": {
48634905
"type": "string"
48644906
}
@@ -4895,9 +4937,31 @@
48954937
"type": "string",
48964938
"nullable": true
48974939
},
4940+
"authMode": {
4941+
"type": "string",
4942+
"enum": [
4943+
"apiKey",
4944+
"oauth"
4945+
]
4946+
},
48984947
"hasApiKey": {
48994948
"type": "boolean"
49004949
},
4950+
"hasOauthCredential": {
4951+
"type": "boolean"
4952+
},
4953+
"oauthRegion": {
4954+
"type": "string",
4955+
"nullable": true,
4956+
"enum": [
4957+
"global",
4958+
"cn"
4959+
]
4960+
},
4961+
"oauthEmail": {
4962+
"type": "string",
4963+
"nullable": true
4964+
},
49014965
"modelsJson": {
49024966
"type": "string",
49034967
"nullable": true
@@ -4954,9 +5018,31 @@
49545018
"type": "string",
49555019
"nullable": true
49565020
},
5021+
"authMode": {
5022+
"type": "string",
5023+
"enum": [
5024+
"apiKey",
5025+
"oauth"
5026+
]
5027+
},
49575028
"hasApiKey": {
49585029
"type": "boolean"
49595030
},
5031+
"hasOauthCredential": {
5032+
"type": "boolean"
5033+
},
5034+
"oauthRegion": {
5035+
"type": "string",
5036+
"nullable": true,
5037+
"enum": [
5038+
"global",
5039+
"cn"
5040+
]
5041+
},
5042+
"oauthEmail": {
5043+
"type": "string",
5044+
"nullable": true
5045+
},
49605046
"modelsJson": {
49615047
"type": "string",
49625048
"nullable": true
@@ -4995,7 +5081,20 @@
49955081
"parameters": [
49965082
{
49975083
"schema": {
4998-
"type": "string"
5084+
"type": "string",
5085+
"enum": [
5086+
"anthropic",
5087+
"openai",
5088+
"google",
5089+
"siliconflow",
5090+
"ppio",
5091+
"openrouter",
5092+
"minimax",
5093+
"kimi",
5094+
"glm",
5095+
"moonshot",
5096+
"zai"
5097+
]
49995098
},
50005099
"required": true,
50015100
"name": "providerId",
@@ -5024,6 +5123,165 @@
50245123
}
50255124
}
50265125
},
5126+
"/api/v1/providers/minimax/oauth/status": {
5127+
"get": {
5128+
"tags": [
5129+
"Providers"
5130+
],
5131+
"responses": {
5132+
"200": {
5133+
"description": "MiniMax OAuth status",
5134+
"content": {
5135+
"application/json": {
5136+
"schema": {
5137+
"type": "object",
5138+
"properties": {
5139+
"connected": {
5140+
"type": "boolean"
5141+
},
5142+
"inProgress": {
5143+
"type": "boolean"
5144+
},
5145+
"region": {
5146+
"type": "string",
5147+
"nullable": true,
5148+
"enum": [
5149+
"global",
5150+
"cn"
5151+
]
5152+
},
5153+
"error": {
5154+
"type": "string",
5155+
"nullable": true
5156+
}
5157+
},
5158+
"required": [
5159+
"connected",
5160+
"inProgress"
5161+
]
5162+
}
5163+
}
5164+
}
5165+
}
5166+
}
5167+
}
5168+
},
5169+
"/api/v1/providers/minimax/oauth/login": {
5170+
"post": {
5171+
"tags": [
5172+
"Providers"
5173+
],
5174+
"requestBody": {
5175+
"content": {
5176+
"application/json": {
5177+
"schema": {
5178+
"type": "object",
5179+
"properties": {
5180+
"region": {
5181+
"type": "string",
5182+
"enum": [
5183+
"global",
5184+
"cn"
5185+
]
5186+
}
5187+
},
5188+
"required": [
5189+
"region"
5190+
]
5191+
}
5192+
}
5193+
}
5194+
},
5195+
"responses": {
5196+
"200": {
5197+
"description": "Start MiniMax OAuth login",
5198+
"content": {
5199+
"application/json": {
5200+
"schema": {
5201+
"type": "object",
5202+
"properties": {
5203+
"connected": {
5204+
"type": "boolean"
5205+
},
5206+
"inProgress": {
5207+
"type": "boolean"
5208+
},
5209+
"region": {
5210+
"type": "string",
5211+
"nullable": true,
5212+
"enum": [
5213+
"global",
5214+
"cn"
5215+
]
5216+
},
5217+
"error": {
5218+
"type": "string",
5219+
"nullable": true
5220+
},
5221+
"started": {
5222+
"type": "boolean"
5223+
},
5224+
"browserUrl": {
5225+
"type": "string"
5226+
}
5227+
},
5228+
"required": [
5229+
"connected",
5230+
"inProgress",
5231+
"started"
5232+
]
5233+
}
5234+
}
5235+
}
5236+
}
5237+
}
5238+
},
5239+
"delete": {
5240+
"tags": [
5241+
"Providers"
5242+
],
5243+
"responses": {
5244+
"200": {
5245+
"description": "Cancel MiniMax OAuth login",
5246+
"content": {
5247+
"application/json": {
5248+
"schema": {
5249+
"type": "object",
5250+
"properties": {
5251+
"connected": {
5252+
"type": "boolean"
5253+
},
5254+
"inProgress": {
5255+
"type": "boolean"
5256+
},
5257+
"region": {
5258+
"type": "string",
5259+
"nullable": true,
5260+
"enum": [
5261+
"global",
5262+
"cn"
5263+
]
5264+
},
5265+
"error": {
5266+
"type": "string",
5267+
"nullable": true
5268+
},
5269+
"cancelled": {
5270+
"type": "boolean"
5271+
}
5272+
},
5273+
"required": [
5274+
"connected",
5275+
"inProgress",
5276+
"cancelled"
5277+
]
5278+
}
5279+
}
5280+
}
5281+
}
5282+
}
5283+
}
5284+
},
50275285
"/api/v1/providers/{providerId}/verify": {
50285286
"post": {
50295287
"tags": [
@@ -5032,7 +5290,20 @@
50325290
"parameters": [
50335291
{
50345292
"schema": {
5035-
"type": "string"
5293+
"type": "string",
5294+
"enum": [
5295+
"anthropic",
5296+
"openai",
5297+
"google",
5298+
"siliconflow",
5299+
"ppio",
5300+
"openrouter",
5301+
"minimax",
5302+
"kimi",
5303+
"glm",
5304+
"moonshot",
5305+
"zai"
5306+
]
50365307
},
50375308
"required": true,
50385309
"name": "providerId",

apps/controller/src/app/container.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,9 @@ export async function createContainer(): Promise<ControllerContainer> {
120120
);
121121
const modelProviderService = new ModelProviderService(
122122
configStore,
123-
env.nodeEnv,
123+
env,
124+
openclawSyncService,
125+
openclawProcess,
124126
);
125127
const runtimeModelStateService = new RuntimeModelStateService(env);
126128

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
export const supportedByokProviderIds = [
2+
"anthropic",
3+
"openai",
4+
"google",
5+
"siliconflow",
6+
"ppio",
7+
"openrouter",
8+
"minimax",
9+
"kimi",
10+
"glm",
11+
"moonshot",
12+
"zai",
13+
] as const;
14+
15+
export type SupportedByokProviderId = (typeof supportedByokProviderIds)[number];
16+
17+
const supportedByokProviderIdSet = new Set<string>(supportedByokProviderIds);
18+
19+
export function isSupportedByokProviderId(
20+
providerId: string,
21+
): providerId is SupportedByokProviderId {
22+
return supportedByokProviderIdSet.has(providerId);
23+
}

0 commit comments

Comments
 (0)