feat(providers): add xAI Grok OAuth with capability-gated X Search (#5035)
This commit is contained in:
+25
-2
@@ -16,6 +16,8 @@ import type {
|
||||
NetworkSafetySettingsUpdate,
|
||||
PairingPayload,
|
||||
ProviderModelsPayload,
|
||||
ProviderOAuthCompletionResult,
|
||||
ProviderOAuthLoginResult,
|
||||
ProviderSettingsUpdate,
|
||||
SessionDeleteResult,
|
||||
SessionAutomationsPayload,
|
||||
@@ -51,6 +53,7 @@ function isSlashCommandLifecycle(value: unknown): value is SlashCommandLifecycle
|
||||
}
|
||||
const CHANNEL_VALUES_HEADER = "X-Nanobot-Channel-Values";
|
||||
const API_SERVICE_VALUES_HEADER = "X-Nanobot-API-Service-Values";
|
||||
const OAUTH_CODE_HEADER = "X-Nanobot-OAuth-Code";
|
||||
|
||||
export class ApiError extends Error {
|
||||
status: number;
|
||||
@@ -809,6 +812,7 @@ export async function updateProviderSettings(
|
||||
if (update.apiKey !== undefined) query.set("api_key", update.apiKey);
|
||||
if (update.apiBase !== undefined) query.set("api_base", update.apiBase);
|
||||
if (update.apiType !== undefined) query.set("api_type", update.apiType);
|
||||
if (update.proxy !== undefined) query.set("proxy", update.proxy);
|
||||
return request<SettingsPayload>(
|
||||
`${base}/api/settings/provider/update?${query}`,
|
||||
token,
|
||||
@@ -819,12 +823,31 @@ export async function loginProviderOAuth(
|
||||
token: string,
|
||||
provider: string,
|
||||
base: string = "",
|
||||
): Promise<SettingsPayload> {
|
||||
): Promise<ProviderOAuthLoginResult> {
|
||||
const query = new URLSearchParams();
|
||||
query.set("provider", provider);
|
||||
return request<SettingsPayload>(
|
||||
return request<ProviderOAuthLoginResult>(
|
||||
`${base}/api/settings/provider/oauth-login?${query}`,
|
||||
token,
|
||||
{ cache: "no-store" },
|
||||
);
|
||||
}
|
||||
|
||||
export async function completeProviderOAuth(
|
||||
token: string,
|
||||
provider: string,
|
||||
flowId: string,
|
||||
authorizationCode?: string,
|
||||
base: string = "",
|
||||
): Promise<ProviderOAuthCompletionResult> {
|
||||
const query = new URLSearchParams();
|
||||
query.set("provider", provider);
|
||||
query.set("flow_id", flowId);
|
||||
const headers = authorizationCode ? { [OAUTH_CODE_HEADER]: authorizationCode } : undefined;
|
||||
return request<ProviderOAuthCompletionResult>(
|
||||
`${base}/api/settings/provider/oauth-login/complete?${query}`,
|
||||
token,
|
||||
{ cache: "no-store", ...(headers ? { headers } : {}) },
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -131,6 +131,8 @@ export const PROVIDER_BRAND_ALIASES: Record<string, string> = {
|
||||
minimaxAnthropic: "minimax",
|
||||
minimax_anthropic: "minimax",
|
||||
openai_codex: "openai",
|
||||
"xai-grok": "xai",
|
||||
xai_grok: "xai",
|
||||
xiaomi: "xiaomi_mimo",
|
||||
volcengine_coding_plan: "volcengine",
|
||||
};
|
||||
@@ -141,6 +143,8 @@ export const PROVIDER_LABEL_ALIASES: Record<string, string> = {
|
||||
minimaxAnthropic: "MiniMax",
|
||||
minimax_anthropic: "MiniMax",
|
||||
openai_codex: "OpenAI",
|
||||
"xai-grok": "xAI",
|
||||
xai_grok: "xAI",
|
||||
volcengine_coding_plan: "Volcengine",
|
||||
};
|
||||
|
||||
@@ -194,6 +198,7 @@ const PROVIDER_BRANDS: Record<string, ProviderBrand> = {
|
||||
xiaomi_mimo: brand("mimo.xiaomi.com", "#FF6900", "MI", [
|
||||
"https://mimo.xiaomi.com/mimo-v2-pro/assets/logo.svg",
|
||||
]),
|
||||
xai: brand("x.ai", "#111827", "xAI"),
|
||||
zhipu: brand("z.ai", "#155EEF", "Z", [
|
||||
"https://z-cdn.chatglm.cn/z-ai/static/logo.svg",
|
||||
"https://www.google.com/s2/favicons?domain=z.ai&sz=64",
|
||||
|
||||
@@ -377,6 +377,23 @@ export interface ProviderModelsPayload {
|
||||
fetched_at?: number;
|
||||
}
|
||||
|
||||
export interface ProviderOAuthAuthorizationRequired {
|
||||
status: "authorization_required";
|
||||
provider: string;
|
||||
flow_id: string;
|
||||
authorization_url: string;
|
||||
expires_in: number;
|
||||
}
|
||||
|
||||
export interface ProviderOAuthPending {
|
||||
status: "pending";
|
||||
provider: string;
|
||||
flow_id: string;
|
||||
}
|
||||
|
||||
export type ProviderOAuthLoginResult = SettingsPayload | ProviderOAuthAuthorizationRequired;
|
||||
export type ProviderOAuthCompletionResult = SettingsPayload | ProviderOAuthPending;
|
||||
|
||||
export interface SettingsPayload {
|
||||
surface?: RuntimeSurface;
|
||||
runtime_surface?: RuntimeSurface;
|
||||
@@ -430,6 +447,7 @@ export interface SettingsPayload {
|
||||
oauth_account?: string | null;
|
||||
oauth_expires_at?: number | null;
|
||||
oauth_login_supported?: boolean;
|
||||
proxy?: string | null;
|
||||
}>;
|
||||
web_search: {
|
||||
provider: string;
|
||||
@@ -936,6 +954,7 @@ export interface ProviderSettingsUpdate {
|
||||
apiKey?: string;
|
||||
apiBase?: string;
|
||||
apiType?: "auto" | "chat_completions" | "responses";
|
||||
proxy?: string;
|
||||
}
|
||||
|
||||
export interface WebSearchSettingsUpdate {
|
||||
|
||||
Reference in New Issue
Block a user