mirror of
https://github.com/Fasthei/taiji-pda-v0.git
synced 2026-09-26 20:02:01 +00:00
- 数据与工具页面:在"使用的模型"右侧添加Agent评估按钮 - 编排中心:将"创建工作流"改为下拉菜单,支持"工具集"和"工作流"两种编排方式 - 工具集功能:支持选择最多8个工具组合成工具集 - API客户端:添加工具集相关接口(getToolsets, createToolset, deleteToolset)
2911 lines
87 KiB
TypeScript
2911 lines
87 KiB
TypeScript
// API client for Taiji AI Platform
|
||
// Base URLs for different services
|
||
export const API_BASE_URLS = {
|
||
dataIngestion: process.env.NEXT_PUBLIC_DATA_INGESTION_URL || "https://apimtaiji.azure-api.net/api/mcp",
|
||
mcpServer: process.env.NEXT_PUBLIC_MCP_SERVER_URL || "https://apimtaiji.azure-api.net/api/mcp",
|
||
gateway: process.env.NEXT_PUBLIC_API_GATEWAY_URL || "https://apimtaiji.azure-api.net/api/mcp",
|
||
}
|
||
|
||
import { getAuthToken, clearAllTokens } from "@/lib/auth"
|
||
|
||
// Helper function to get API key
|
||
function getApiKey(): string | null {
|
||
if (typeof window !== "undefined") {
|
||
return localStorage.getItem("api_key")
|
||
}
|
||
return null
|
||
}
|
||
|
||
// Helper function to build headers and ensure authentication
|
||
function buildHeaders(contentType = "application/json", requireAuth = false): HeadersInit {
|
||
const headers: HeadersInit = {
|
||
Accept: "application/json",
|
||
}
|
||
|
||
if (contentType) {
|
||
headers["Content-Type"] = contentType
|
||
}
|
||
|
||
const token = getAuthToken()
|
||
const apiKey = getApiKey()
|
||
|
||
// 需要认证的请求必须有token或API key
|
||
if (requireAuth && !token && !apiKey) {
|
||
throw new Error(
|
||
"认证失败:未找到有效的token或API key。请重新登录。(Authentication failed: No valid token or API key found. Please log in again.)",
|
||
)
|
||
}
|
||
|
||
if (token) {
|
||
headers.Authorization = `Bearer ${token}`
|
||
} else if (apiKey) {
|
||
headers["X-API-Key"] = apiKey
|
||
}
|
||
|
||
return headers
|
||
}
|
||
|
||
// Helper function to check if user is authenticated
|
||
function requireAuth(): void {
|
||
const token = getAuthToken()
|
||
const apiKey = getApiKey()
|
||
|
||
if (!token && !apiKey) {
|
||
throw new Error(
|
||
"认证失败:未找到有效的token或API key。请重新登录。(Authentication failed: No valid token or API key found. Please log in again.)",
|
||
)
|
||
}
|
||
}
|
||
|
||
// API Response types
|
||
export interface APIResponse<T = any> {
|
||
success: boolean
|
||
data?: T
|
||
message?: string
|
||
error?: {
|
||
code?: string
|
||
message?: string
|
||
}
|
||
}
|
||
|
||
// Helper function to handle API responses
|
||
async function handleResponse<T = any>(response: Response): Promise<T> {
|
||
const contentType = response.headers.get("content-type")
|
||
|
||
// 先读取响应文本
|
||
const text = await response.text()
|
||
|
||
if (!response.ok) {
|
||
let errorMessage = `HTTP ${response.status}: ${response.statusText}`
|
||
|
||
// 尝试解析错误响应
|
||
if (contentType?.includes("application/json") && text) {
|
||
try {
|
||
const error = JSON.parse(text)
|
||
errorMessage = error.detail || error.message || errorMessage
|
||
} catch (e) {
|
||
console.error("Failed to parse error response as JSON:", e)
|
||
console.error("Response text:", text.substring(0, 200))
|
||
}
|
||
} else {
|
||
console.error("Non-JSON error response:", text.substring(0, 200))
|
||
}
|
||
|
||
throw new Error(errorMessage)
|
||
}
|
||
|
||
// 检查响应是否为JSON
|
||
if (!contentType?.includes("application/json")) {
|
||
console.error("Expected JSON but got:", contentType)
|
||
console.error("Response preview:", text.substring(0, 200))
|
||
throw new Error(`Server returned non-JSON response. Content-Type: ${contentType || 'unknown'}`)
|
||
}
|
||
|
||
// 解析JSON
|
||
try {
|
||
// 极致的预处理:寻找第一个 { 或 [ 并作为开始,最后一个 } 或 ] 并作为结束
|
||
const firstBrace = text.indexOf('{');
|
||
const firstBracket = text.indexOf('[');
|
||
const lastBrace = text.lastIndexOf('}');
|
||
const lastBracket = text.lastIndexOf(']');
|
||
|
||
let startPos = -1;
|
||
let endPos = -1;
|
||
let endChar = '';
|
||
|
||
if (firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket)) {
|
||
startPos = firstBrace;
|
||
endPos = lastBrace;
|
||
endChar = '}';
|
||
} else if (firstBracket !== -1) {
|
||
startPos = firstBracket;
|
||
endPos = lastBracket;
|
||
endChar = ']';
|
||
}
|
||
|
||
let json;
|
||
if (startPos !== -1 && endPos !== -1 && endPos > startPos) {
|
||
// 尝试直接解析提取出的部分
|
||
const potentialJson = text.substring(startPos, endPos + 1);
|
||
try {
|
||
json = JSON.parse(potentialJson);
|
||
} catch (e) {
|
||
// 如果直接解析失败,尝试暴力缩减(从后向前)
|
||
const searchLimit = Math.max(startPos + 1, endPos - 2000);
|
||
for (let i = endPos; i >= searchLimit; i--) {
|
||
if (text[i] === endChar) {
|
||
try {
|
||
json = JSON.parse(text.substring(startPos, i + 1));
|
||
break;
|
||
} catch (e2) {}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!json) {
|
||
// 最后兜底:尝试 trim 后解析
|
||
try {
|
||
json = JSON.parse(text.trim());
|
||
} catch (e) {
|
||
// 彻底失败
|
||
console.error("Failed to parse JSON response after all attempts:", e)
|
||
console.error("Response URL:", response.url)
|
||
console.error("Response text preview:", text.substring(0, 1000))
|
||
throw new Error(`Invalid JSON response from server. URL: ${response.url}`)
|
||
}
|
||
}
|
||
|
||
// console.log(`[API Response] ${response.url}:`, json)
|
||
return json as T
|
||
} catch (e) {
|
||
if (e instanceof Error && e.message.startsWith("Invalid JSON")) throw e;
|
||
throw new Error(`Invalid JSON response from server. Check console for details. URL: ${response.url}`)
|
||
}
|
||
}
|
||
|
||
// Helper function to check if backend is reachable
|
||
async function checkBackendReachable(url: string): Promise<boolean> {
|
||
try {
|
||
const controller = new AbortController()
|
||
const timeoutId = setTimeout(() => controller.abort(), 5000) // 5 second timeout
|
||
const response = await fetch(url, {
|
||
method: "HEAD",
|
||
signal: controller.signal,
|
||
})
|
||
clearTimeout(timeoutId)
|
||
return response.ok || response.status < 500
|
||
} catch {
|
||
return false
|
||
}
|
||
}
|
||
|
||
export class TaijiAPIClient {
|
||
// ==================== 认证模块 API ====================
|
||
// Base URL: http://localhost:8002/api/auth
|
||
|
||
/**
|
||
* 用户自由注册
|
||
* POST /api/auth/register
|
||
*
|
||
* 用户注册新账户,注册成功后自动分配默认资源并返回登录 Token
|
||
*
|
||
* 自动分配的资源包括:
|
||
* - 渠道分配(默认 taiji 渠道)
|
||
* - 自定义 Agent 配额(CPU: 2核, 内存: 2GB)
|
||
* - 平台 Agent 配额(每个模板 1 个 Pod)
|
||
* - 供应商模型(所有活跃供应商模型的 LiteLLM Key)
|
||
* - 账户余额(初始 20 元)
|
||
*
|
||
* @param email - 邮箱地址,需符合邮箱格式
|
||
* @param password - 密码,至少8个字符
|
||
* @param verificationCode - 邮箱验证码,6位数字
|
||
* @param username - 用户名,3-50个字符(可选,默认使用邮箱前缀)
|
||
* @param fullName - 全名/显示名称(可选)
|
||
* @returns 注册结果,包含 token、refreshToken 和用户信息
|
||
* @throws 400 - 验证码错误或已过期、邮箱已被注册、用户名已被使用
|
||
* @throws 500 - 系统配置错误或资源分配失败
|
||
*/
|
||
static async register(
|
||
email: string,
|
||
password: string,
|
||
verificationCode: string,
|
||
username?: string,
|
||
fullName?: string,
|
||
): Promise<APIResponse<{ token: string; refreshToken?: string; user?: any }>> {
|
||
try {
|
||
// 清除所有旧的token
|
||
clearAllTokens()
|
||
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/auth/register`, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify({
|
||
username: username || email.split("@")[0],
|
||
email,
|
||
password,
|
||
verification_code: verificationCode,
|
||
full_name: fullName,
|
||
}),
|
||
signal: AbortSignal.timeout(15000), // 15 second timeout (注册可能需要更长时间进行资源分配)
|
||
})
|
||
const data = await handleResponse<APIResponse<{ token: string; refreshToken?: string; user?: any }>>(response)
|
||
if (data.success && data.data?.token && typeof window !== "undefined") {
|
||
// 存储token
|
||
localStorage.setItem("auth_token", data.data.token)
|
||
document.cookie = `auth_token=${data.data.token}; path=/; max-age=${7 * 24 * 60 * 60}; SameSite=Lax`
|
||
|
||
if (data.data.refreshToken) {
|
||
localStorage.setItem("refresh_token", data.data.refreshToken)
|
||
}
|
||
if (data.data.user) {
|
||
localStorage.setItem("user", JSON.stringify(data.data.user))
|
||
}
|
||
}
|
||
return data
|
||
} catch (error: any) {
|
||
// 处理网络错误
|
||
if (error.name === "AbortError" || error.message?.includes("timeout")) {
|
||
throw new Error("请求超时,请检查网络连接或后端服务状态")
|
||
}
|
||
if (error.message?.includes("Failed to fetch") || error.name === "TypeError") {
|
||
throw new Error(
|
||
`无法连接到后端服务 (${API_BASE_URLS.mcpServer})。请确保 MCP Server 正在运行。`,
|
||
)
|
||
}
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 发送邮箱验证码(自由注册)
|
||
* POST /api/auth/register/send-code?email=xxx
|
||
*
|
||
* 向指定邮箱发送6位数字验证码,验证码有效期为10分钟
|
||
* 同一邮箱60秒内只能发送一次验证码
|
||
*
|
||
* @param email - 邮箱地址
|
||
* @returns 发送结果
|
||
* @throws 429 - 频率限制,需等待后重试
|
||
* @throws 400 - 邮箱已被注册
|
||
* @throws 500 - 邮件服务异常
|
||
*/
|
||
static async sendEmailVerificationCode(
|
||
email: string,
|
||
): Promise<APIResponse<{ message?: string }>> {
|
||
try {
|
||
// 根据接口文档,email 作为 Query 参数传递
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/auth/register/send-code?email=${encodeURIComponent(email)}`,
|
||
{
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
signal: AbortSignal.timeout(10000), // 10 second timeout
|
||
}
|
||
)
|
||
return await handleResponse<APIResponse<{ message?: string }>>(response)
|
||
} catch (error: any) {
|
||
if (error.name === "AbortError" || error.message?.includes("timeout")) {
|
||
throw new Error("请求超时,请检查网络连接或后端服务状态")
|
||
}
|
||
if (error.message?.includes("Failed to fetch") || error.name === "TypeError") {
|
||
throw new Error(
|
||
`无法连接到后端服务 (${API_BASE_URLS.mcpServer})。请确保 MCP Server 正在运行。`,
|
||
)
|
||
}
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 验证邮箱验证码
|
||
*/
|
||
static async verifyEmailCode(
|
||
email: string,
|
||
code: string,
|
||
): Promise<APIResponse<{ verified: boolean }>> {
|
||
try {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/auth/verify-email-code`, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify({ email, code }),
|
||
signal: AbortSignal.timeout(10000), // 10 second timeout
|
||
})
|
||
return await handleResponse<APIResponse<{ verified: boolean }>>(response)
|
||
} catch (error: any) {
|
||
if (error.name === "AbortError" || error.message?.includes("timeout")) {
|
||
throw new Error("请求超时,请检查网络连接或后端服务状态")
|
||
}
|
||
if (error.message?.includes("Failed to fetch") || error.name === "TypeError") {
|
||
throw new Error(
|
||
`无法连接到后端服务 (${API_BASE_URLS.mcpServer})。请确保 MCP Server 正在运行。`,
|
||
)
|
||
}
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 用户登录
|
||
*/
|
||
static async login(
|
||
email: string,
|
||
password: string,
|
||
role: "user" | "channel" | "admin" | "super_admin" | "billing_admin" | "operations_admin" | "provider" = "user",
|
||
): Promise<APIResponse<{ token: string; refreshToken?: string; user?: any }>> {
|
||
try {
|
||
// 清除所有旧的token(防止多用户登录时token重复)
|
||
clearAllTokens()
|
||
|
||
// 直接尝试登录,让实际的登录请求来判断连接状态
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/auth/login`, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify({ email, password, role }),
|
||
signal: AbortSignal.timeout(10000), // 10 second timeout
|
||
})
|
||
const data = await handleResponse<APIResponse<{ token: string; refreshToken?: string; user?: any }>>(response)
|
||
if (data.success && data.data?.token && typeof window !== "undefined") {
|
||
// 根据role存储对应的token
|
||
const tokenKey = role === "channel" ? "channel_token" : role === "admin" ? "admin_token" : "auth_token"
|
||
localStorage.setItem(tokenKey, data.data.token)
|
||
|
||
// 同时保存到 cookie(用于服务器端中间件检查)
|
||
document.cookie = `${tokenKey}=${data.data.token}; path=/; max-age=${7 * 24 * 60 * 60}; SameSite=Lax`
|
||
|
||
if (data.data.refreshToken) {
|
||
localStorage.setItem("refresh_token", data.data.refreshToken)
|
||
}
|
||
if (data.data.user) {
|
||
localStorage.setItem("user", JSON.stringify(data.data.user))
|
||
}
|
||
}
|
||
return data
|
||
} catch (error: any) {
|
||
// 处理网络错误
|
||
if (error.name === "AbortError" || error.message?.includes("timeout")) {
|
||
throw new Error("请求超时,请检查网络连接或后端服务状态")
|
||
}
|
||
if (error.message?.includes("Failed to fetch") || error.name === "TypeError") {
|
||
throw new Error(
|
||
`无法连接到后端服务 (${API_BASE_URLS.mcpServer})。请确保 MCP Server 正在运行。`,
|
||
)
|
||
}
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 用户登出
|
||
*/
|
||
static async logout() {
|
||
try {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/auth/logout`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
})
|
||
await handleResponse(response)
|
||
} catch (error) {
|
||
// 即使API调用失败,也要清除本地存储
|
||
console.error("Logout API call failed:", error)
|
||
} finally {
|
||
// 清除所有本地存储的token和用户信息
|
||
clearAllTokens()
|
||
|
||
// 同时清除 cookie
|
||
if (typeof window !== "undefined") {
|
||
document.cookie = "auth_token=; path=/; max-age=0"
|
||
document.cookie = "channel_token=; path=/; max-age=0"
|
||
document.cookie = "admin_token=; path=/; max-age=0"
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 刷新Token
|
||
*/
|
||
static async refreshToken(): Promise<APIResponse<{ token: string; refreshToken?: string }>> {
|
||
try {
|
||
requireAuth()
|
||
} catch (error) {
|
||
throw new Error("无法刷新token:用户未认证。(Cannot refresh token: user not authenticated.)")
|
||
}
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/auth/refresh`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
})
|
||
const data = await handleResponse<APIResponse<{ token: string; refreshToken?: string }>>(response)
|
||
if (data.success && data.data?.token && typeof window !== "undefined") {
|
||
localStorage.setItem("auth_token", data.data.token)
|
||
if (data.data.refreshToken) {
|
||
localStorage.setItem("refresh_token", data.data.refreshToken)
|
||
}
|
||
}
|
||
return data
|
||
}
|
||
|
||
/**
|
||
* 修改密码
|
||
*/
|
||
static async changePassword(oldPassword: string, newPassword: string) {
|
||
try {
|
||
requireAuth()
|
||
} catch (error) {
|
||
throw new Error("无法修改密码:用户未认证。(Cannot change password: user not authenticated.)")
|
||
}
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/auth/password`, {
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify({ old_password: oldPassword, new_password: newPassword }),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取当前用户信息
|
||
*/
|
||
static async getCurrentUser() {
|
||
try {
|
||
requireAuth()
|
||
} catch (error) {
|
||
throw new Error("无法获取用户信息:用户未认证。(Cannot get user info: user not authenticated.)")
|
||
}
|
||
try {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/profile`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
// 如果是404错误,可能是接口还未部署,直接返回特殊错误
|
||
if (response.status === 404) {
|
||
console.warn("Profile API not available (404), using local user data")
|
||
throw new Error("PROFILE_API_NOT_AVAILABLE")
|
||
}
|
||
return handleResponse(response)
|
||
} catch (error: any) {
|
||
// 如果已经是特殊错误,直接抛出
|
||
if (error.message === "PROFILE_API_NOT_AVAILABLE") {
|
||
throw error
|
||
}
|
||
// 如果是其他错误,检查错误消息中是否包含404
|
||
if (error.message?.includes("404") || error.message?.includes("Not Found") || error.message?.includes("HTTP 404")) {
|
||
console.warn("Profile API not available, using local user data")
|
||
throw new Error("PROFILE_API_NOT_AVAILABLE")
|
||
}
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 更新用户信息
|
||
*/
|
||
static async updateUserProfile(data: {
|
||
username?: string
|
||
company?: string
|
||
}) {
|
||
try {
|
||
requireAuth()
|
||
} catch (error) {
|
||
throw new Error("无法更新用户信息:用户未认证。(Cannot update user profile: user not authenticated.)")
|
||
}
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/profile`, {
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
const result = await handleResponse(response)
|
||
// 如果更新成功,更新本地存储的用户信息
|
||
if (result.success && typeof window !== "undefined") {
|
||
const userStr = localStorage.getItem("user")
|
||
if (userStr) {
|
||
try {
|
||
const user = JSON.parse(userStr)
|
||
if (data.username) user.username = data.username
|
||
if (data.company !== undefined) user.company = data.company
|
||
localStorage.setItem("user", JSON.stringify(user))
|
||
} catch (e) {
|
||
console.error("Failed to update local user info:", e)
|
||
}
|
||
}
|
||
}
|
||
return result
|
||
}
|
||
|
||
/**
|
||
* 获取API密钥信息
|
||
*/
|
||
static async getApiKeyInfo() {
|
||
try {
|
||
requireAuth()
|
||
} catch (error) {
|
||
throw new Error("无法获取API密钥:用户未认证。(Cannot get API key: user not authenticated.)")
|
||
}
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/auth/keys/info`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 重新生成API密钥
|
||
*/
|
||
static async regenerateApiKey(): Promise<APIResponse<{ apiKey: string; message?: string }>> {
|
||
try {
|
||
requireAuth()
|
||
} catch (error) {
|
||
throw new Error("无法重新生成API密钥:用户未认证。(Cannot regenerate API key: user not authenticated.)")
|
||
}
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/auth/keys/regenerate`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
})
|
||
const data = await handleResponse<APIResponse<{ apiKey: string; message?: string }>>(response)
|
||
if (data.success && data.data?.apiKey && typeof window !== "undefined") {
|
||
localStorage.setItem("api_key", data.data.apiKey)
|
||
}
|
||
return data
|
||
}
|
||
|
||
// ==================== 用户侧平台 API ====================
|
||
// Base URL: http://localhost:8002/api/user
|
||
|
||
/**
|
||
* 获取仪表板统计
|
||
*/
|
||
static async getUserDashboardStats() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/dashboard/stats`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取Agent活动数据
|
||
*/
|
||
static async getUserAgentActivity(period: "7d" | "30d" | "90d" = "7d") {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/user/agents/activity?period=${period}`,
|
||
{
|
||
headers: buildHeaders(),
|
||
},
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 选择网关类型
|
||
*/
|
||
static async selectGateway(gatewayType: "MCP" | "A2A" | "API") {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/gateway/select`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify({ gatewayType }),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 创建网关API
|
||
*/
|
||
static async createGatewayAPI(name: string, method: "json" | "url", content: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/gateway/api/create`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify({ name, method, content }),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取网关API列表
|
||
*/
|
||
static async getGatewayAPIs() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/gateway/apis`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取网关监控数据
|
||
*/
|
||
static async getGatewayMonitoring() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/gateway/monitoring`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 生成工具
|
||
*/
|
||
static async generateTool(data: {
|
||
name: string
|
||
description: string
|
||
frameworkTemplate: string
|
||
gateway: string
|
||
agentCount: number
|
||
cpu: number
|
||
memory: number
|
||
maxScale: number
|
||
model: string
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/tools/generate`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 创建数据模板
|
||
*/
|
||
static async createDataTemplate(data: {
|
||
name: string
|
||
type: "json_api" | "cloud_storage" | "database"
|
||
config: any
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/data-templates/create`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取平台Agent列表
|
||
*/
|
||
static async getPlatformAgents() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/agents/platform`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 部署Agent
|
||
*/
|
||
static async deployAgent(data: {
|
||
agentId: string
|
||
instances: number
|
||
model: string
|
||
gateway: "MCP" | "A2A" | "API"
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/agents/deploy`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 创建自定义Agent
|
||
* POST /api/user/custom-agents
|
||
*
|
||
* 根据接口文档 v4 格式:
|
||
* 核心逻辑:创建 Agent 时选择已创建的工具,系统自动从工具获取 template 和 envConfig,
|
||
* 调用 Agent Manager 创建对应类型的 Agent。
|
||
*
|
||
* @param data.name - Agent名称(小写字母、数字、连字符,1-63字符)【必填】
|
||
* @param data.tools - 工具ID列表(第一个工具决定Agent类型和配置)【必填】
|
||
* @param data.template - 模板名称(可选,未指定时从工具获取)
|
||
* @param data.frameworkTemplate - 框架类型("MCP" | "A2A" | "langchain"),默认 "MCP"
|
||
* @param data.description - Agent描述
|
||
* @param data.cpuRequest - CPU请求量(如 "500m"),默认 "100m"
|
||
* @param data.cpuLimit - CPU限制量,默认等于 cpuRequest
|
||
* @param data.memoryRequest - 内存请求量(如 "1Gi"),默认 "128Mi"
|
||
* @param data.memoryLimit - 内存限制量,默认等于 memoryRequest
|
||
* @param data.model - 模型名称(用于注入 LiteLLM 密钥)
|
||
* @param data.envConfig - 额外环境变量(与工具配置合并,请求中的优先)
|
||
* @param data.agentRole - A2A框架专用:Agent角色(如 "data_analyzer")
|
||
* @param data.agentCapabilities - A2A框架专用:Agent能力列表
|
||
*/
|
||
static async createCustomAgent(data: {
|
||
name: string // 必填
|
||
tools: string[] // 必填:工具ID列表
|
||
template?: string // 可选:模板名称(未指定时从工具获取)
|
||
frameworkTemplate?: string // 可选:框架类型
|
||
description?: string
|
||
cpuRequest?: string
|
||
cpuLimit?: string
|
||
memoryRequest?: string
|
||
memoryLimit?: string
|
||
model?: string
|
||
envConfig?: Record<string, string>
|
||
// A2A 框架专用
|
||
agentRole?: string
|
||
agentCapabilities?: string[]
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/custom-agents`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取自定义Agent列表
|
||
* GET /api/user/custom-agents
|
||
*
|
||
* 注意:后端实际路径为 /api/user/custom-agents(非 /api/user/agents/custom)
|
||
*/
|
||
static async getCustomAgents() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/custom-agents`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取用户自定义Agent列表(别名)
|
||
* GET /api/user/custom-agents
|
||
*/
|
||
static async getUserCustomAgents() {
|
||
return this.getCustomAgents()
|
||
}
|
||
|
||
/**
|
||
* 删除自定义Agent
|
||
* DELETE /api/user/custom-agents/{name}
|
||
*
|
||
* @param agentName - Agent名称
|
||
*/
|
||
static async deleteCustomAgent(agentName: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/custom-agents/${agentName}`, {
|
||
method: "DELETE",
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 停止自定义Agent
|
||
* POST /api/user/custom-agents/{name}/stop
|
||
*
|
||
* @param agentName - Agent名称
|
||
*/
|
||
static async stopCustomAgent(agentName: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/custom-agents/${agentName}/stop`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 重启自定义Agent
|
||
* POST /api/user/custom-agents/{name}/restart
|
||
*
|
||
* @param agentName - Agent名称
|
||
*/
|
||
static async restartCustomAgent(agentName: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/custom-agents/${agentName}/restart`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 扩缩容自定义Agent
|
||
* PUT /api/user/custom-agents/{name}/scale
|
||
*
|
||
* @param agentName - Agent名称
|
||
* @param data - 资源配置
|
||
*/
|
||
static async scaleCustomAgent(
|
||
agentName: string,
|
||
data: {
|
||
cpuRequest?: string
|
||
cpuLimit?: string
|
||
memoryRequest?: string
|
||
memoryLimit?: string
|
||
}
|
||
) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/custom-agents/${agentName}/scale`, {
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取Agent框架模板列表
|
||
* GET /api/user/custom-agents/templates
|
||
*/
|
||
static async getCustomAgentTemplates() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/custom-agents/templates`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 创建工具(基于模板)
|
||
* POST /api/user/tools/create
|
||
*
|
||
* 根据接口文档 v4 格式:
|
||
* - name: 工具名称
|
||
* - description: 工具描述(可选)
|
||
* - template: 模板名称(来自 dataTemplates[].template,如 mysql_agent)
|
||
* - envConfig: 环境变量配置(根据模板 env_info 填写)
|
||
*
|
||
* 注意:OPENAI_API_KEY 无需填写,系统会自动注入用户的 LiteLLM 密钥
|
||
*/
|
||
static async createTool(data: {
|
||
name: string
|
||
description?: string
|
||
template: string // 模板名称(如 mysql_agent, postgresql_agent)
|
||
envConfig: Record<string, string> // 环境变量配置
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/tools/create`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 修改工具
|
||
* PUT /api/user/tools/{tool_id}
|
||
*
|
||
* 根据接口文档 v4 格式:
|
||
* - description: 工具描述(可选)
|
||
* - is_active: 是否激活(可选)
|
||
* - envConfig: 更新环境变量配置(可选)
|
||
*
|
||
* 注意:template 字段创建后不可修改
|
||
*/
|
||
static async updateTool(toolId: string, data: {
|
||
description?: string
|
||
is_active?: boolean
|
||
envConfig?: Record<string, string>
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/tools/${toolId}`, {
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 删除工具
|
||
* DELETE /api/user/tools/{tool_id}
|
||
*/
|
||
static async deleteUserTool(toolId: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/tools/${toolId}`, {
|
||
method: "DELETE",
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取用户创建的工具列表
|
||
* GET /api/user/tools
|
||
*/
|
||
static async getUserTools() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/tools`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取工具统计数据
|
||
* GET /api/user/tools/stats
|
||
*/
|
||
static async getToolsStats() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/tools/stats`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取工作流列表
|
||
* GET /api/user/workflows/list
|
||
*
|
||
* 注意:后端实际路径为 /api/user/workflows/list(非 /api/user/workflows)
|
||
*/
|
||
static async getWorkflows() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/workflows/list`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 创建工作流
|
||
*/
|
||
static async createWorkflow(data: {
|
||
name: string
|
||
description?: string
|
||
gateway: "MCP" | "A2A" | "API"
|
||
nodes: Array<{
|
||
agentId: string
|
||
agentType: "platform" | "custom"
|
||
agentName: string
|
||
order: number
|
||
}>
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/workflows/create`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 删除工作流
|
||
* DELETE /api/user/workflows/{workflow_id}
|
||
*
|
||
* @param workflowId - 工作流ID
|
||
*/
|
||
static async deleteWorkflow(workflowId: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/workflows/${workflowId}`, {
|
||
method: "DELETE",
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 运行工作流
|
||
* POST /api/user/workflows/{workflow_id}/run
|
||
*
|
||
* 执行工作流,按顺序调用各节点
|
||
*
|
||
* @param workflowId - 工作流ID
|
||
* @param input - 可选的输入参数
|
||
*/
|
||
static async runWorkflow(workflowId: string, input?: Record<string, any>) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/workflows/${workflowId}/run`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify({ input }),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
// ==================== 工具集 API ====================
|
||
|
||
/**
|
||
* 获取工具集列表
|
||
* GET /api/user/toolsets/list
|
||
*/
|
||
static async getToolsets() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/toolsets/list`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 创建工具集
|
||
* POST /api/user/toolsets/create
|
||
*
|
||
* @param data - 工具集数据
|
||
*/
|
||
static async createToolset(data: {
|
||
name: string
|
||
description?: string
|
||
tools: string[]
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/toolsets/create`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 删除工具集
|
||
* DELETE /api/user/toolsets/{toolset_id}
|
||
*
|
||
* @param toolsetId - 工具集ID
|
||
*/
|
||
static async deleteToolset(toolsetId: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/toolsets/${toolsetId}`, {
|
||
method: "DELETE",
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取计费仪表板综合数据
|
||
* GET /api/user/dashboard/billing-overview
|
||
*/
|
||
static async getBillingOverview() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/dashboard/billing-overview`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取余额信息
|
||
*/
|
||
static async getBillingBalance() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/billing/balance`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 充值余额
|
||
*/
|
||
static async rechargeBalance(amount: number, paymentMethod: "alipay" | "wechat" | "card" = "alipay") {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/billing/recharge`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify({ amount, paymentMethod }),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取计费历史
|
||
*/
|
||
static async getBillingHistory(params: {
|
||
startTime: string
|
||
endTime: string
|
||
customerName?: string
|
||
minCalls?: number
|
||
maxCalls?: number
|
||
export?: "excel" | "csv" | "pdf"
|
||
page?: number
|
||
pageSize?: number
|
||
}) {
|
||
const queryParams = new URLSearchParams()
|
||
Object.entries(params).forEach(([key, value]) => {
|
||
if (value !== undefined) {
|
||
queryParams.append(key, value.toString())
|
||
}
|
||
})
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/user/billing/history?${queryParams}`,
|
||
{
|
||
headers: buildHeaders(),
|
||
},
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
// ==================== 渠道合作伙伴 API ====================
|
||
// Base URL: http://localhost:8002/api/channel
|
||
|
||
/**
|
||
* 获取租户列表
|
||
*/
|
||
static async getChannelTenants() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/channel/tenants`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 创建租户
|
||
* 前端使用systemRole(系统权限),映射到后端的subscriptionTier
|
||
* 角色映射:tenant->free, admin->pro, billing-admin->enterprise, operations-admin->enterprise
|
||
*
|
||
* 注意:超级管理员创建租户时需要提供channelId参数
|
||
*/
|
||
static async createChannelTenant(data: {
|
||
name: string
|
||
email: string
|
||
password: string
|
||
systemRole?: "tenant" | "admin" | "billing-admin" | "operations-admin"
|
||
subscriptionTier?: "free" | "pro" | "enterprise"
|
||
channelId?: string // 超级管理员创建租户时需要提供
|
||
}) {
|
||
// 角色到订阅等级的映射
|
||
const roleToTierMap: Record<string, string> = {
|
||
"tenant": "free",
|
||
"admin": "pro",
|
||
"billing-admin": "enterprise",
|
||
"operations-admin": "enterprise"
|
||
}
|
||
|
||
// 构建发送到后端的数据
|
||
const apiData: Record<string, any> = {
|
||
name: data.name,
|
||
email: data.email,
|
||
password: data.password,
|
||
subscriptionTier: data.subscriptionTier || (data.systemRole ? roleToTierMap[data.systemRole] : "free")
|
||
}
|
||
|
||
// 如果提供了channelId,添加到请求数据中(超级管理员创建租户时需要)
|
||
if (data.channelId) {
|
||
apiData.channelId = data.channelId
|
||
}
|
||
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/channel/tenants/create`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(apiData),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 分配租户资源
|
||
* PUT /api/channel/tenants/{tenant_id}/resources
|
||
*
|
||
* @param tenantId - 租户ID
|
||
* @param data.agents - Agent配额列表,每个元素包含 agentId(模板名称)和 quantity(分配数量)
|
||
* @param data.models - 模型配额列表,每个元素包含 modelName、rpm、tpm
|
||
* @param data.customAgentQuota - 自定义Agent资源配额,包含 cpuQuota 和 memoryQuota
|
||
*/
|
||
static async allocateTenantResources(
|
||
tenantId: string,
|
||
data: {
|
||
agents?: Array<{ agentId: string; quantity: number }>
|
||
models?: Array<{ modelName: string; rpm: number; tpm: number }>
|
||
customAgentQuota?: { cpuQuota: number; memoryQuota: number }
|
||
},
|
||
) {
|
||
console.log("📤 allocateTenantResources 请求:", {
|
||
tenantId,
|
||
data: JSON.stringify(data, null, 2),
|
||
})
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/channel/tenants/${tenantId}/resources`, {
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 更新租户计费设置
|
||
*/
|
||
static async updateTenantBilling(tenantId: string, data: { subscriptionTier?: string; discount?: number }) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/channel/tenants/${tenantId}/billing`, {
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 更新租户状态
|
||
*/
|
||
static async updateTenantStatus(tenantId: string, status: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/channel/tenants/${tenantId}/status`, {
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify({ status }),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 为租户充值
|
||
*/
|
||
static async rechargeTenant(tenantId: string, amount: number) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/channel/tenants/${tenantId}/recharge`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify({ amount }),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 设置租户授信额度
|
||
*/
|
||
static async setTenantCreditLimit(tenantId: string, creditLimit: number) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/channel/tenants/${tenantId}/credit`, {
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify({ creditLimit }),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 更新租户权限
|
||
* PUT /api/channel/tenants/{tenant_id}/permissions
|
||
*
|
||
* @param tenantId - 租户ID
|
||
* @param permissions - 权限列表,可选值:
|
||
* - use:platform_agents: 使用平台Agent
|
||
* - use:custom_agents: 使用自定义Agent
|
||
* - create:agents: 创建Agent
|
||
* - read:billing: 查看计费信息
|
||
* - export:data: 导出数据
|
||
*/
|
||
static async updateTenantPermissions(tenantId: string, permissions: string[]) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/channel/tenants/${tenantId}/permissions`, {
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify({ permissions }),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
// 注意:disableTenant 和 enableTenant 接口已移除
|
||
// 后端使用 updateTenantStatus 接口统一管理租户状态
|
||
// 使用方法:updateTenantStatus(tenantId, "suspended") 暂停租户
|
||
// updateTenantStatus(tenantId, "active") 启用租户
|
||
// updateTenantStatus(tenantId, "inactive") 停用租户
|
||
|
||
/**
|
||
* 获取渠道租户资源分配汇总
|
||
* GET /api/channel/tenants/resources/summary
|
||
*
|
||
* @param channelId - 渠道ID(超级管理员必须提供,渠道管理员可选)
|
||
* @returns 租户资源分配汇总,包括:
|
||
* - channelQuota: 渠道配额
|
||
* - tenants: 租户资源列表,每个租户包含:
|
||
* - customAgentQuota: 自定义Agent配额
|
||
* - platformAgents: 平台Agent配额列表
|
||
* - models: 模型配额列表
|
||
* - summary: 汇总统计
|
||
*/
|
||
static async getTenantsResourcesSummary(channelId?: string) {
|
||
let url = `${API_BASE_URLS.mcpServer}/api/channel/tenants/resources/summary`
|
||
if (channelId) {
|
||
url += `?channel_id=${encodeURIComponent(channelId)}`
|
||
}
|
||
const response = await fetch(url, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 超级管理员查看渠道租户资源分配(旧接口 - 保留兼容)
|
||
* GET /api/admin/channels/{channel_id}/tenants/resources
|
||
*
|
||
* @param channelId - 渠道ID(必须)
|
||
* @returns 渠道租户资源分配详情,包括:
|
||
* - channelId/channelName: 渠道信息
|
||
* - tenants: 租户资源列表
|
||
* - summary: 汇总统计
|
||
*/
|
||
static async getChannelTenantsResources(channelId: string) {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/admin/channels/${channelId}/tenants/resources`,
|
||
{
|
||
headers: buildHeaders(),
|
||
}
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 超级管理员查看渠道资源分配详情(新接口)
|
||
* GET /api/admin/channels/{channel_id}/allocated-resources
|
||
*
|
||
* @param channelId - 渠道ID(必须)
|
||
* @returns 渠道资源分配详情,包括:
|
||
* - channelId/channelName/channelEmail/channelStatus: 渠道基本信息
|
||
* - channelCredit/commissionRate: 渠道财务信息
|
||
* - customAgentQuota: 自定义Agent配额(CPU/内存配额、已分配给租户、可用量)
|
||
* - platformAgents: 平台Agent配额列表(模板名称、Pod配额、使用情况)
|
||
* - modelProviders: 模型供应商列表(供应商信息、支持的模型)
|
||
* - models: 模型配额列表(模型名称、RPM/TPM限制、分配情况)
|
||
* - summary: 资源汇总统计
|
||
*/
|
||
static async getChannelAllocatedResources(channelId: string) {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/admin/channels/${channelId}/allocated-resources`,
|
||
{
|
||
headers: buildHeaders(),
|
||
}
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 删除租户(软删除)
|
||
* DELETE /api/channel/tenants/{tenant_id}
|
||
*
|
||
* @param tenantId - 租户ID
|
||
* @param channelId - 渠道ID(超级管理员必须提供,渠道管理员可选)
|
||
*/
|
||
static async deleteTenant(tenantId: string, channelId?: string) {
|
||
let url = `${API_BASE_URLS.mcpServer}/api/channel/tenants/${tenantId}`
|
||
// 超级管理员需要在查询参数中提供 channel_id
|
||
if (channelId) {
|
||
url += `?channel_id=${encodeURIComponent(channelId)}`
|
||
}
|
||
const response = await fetch(url, {
|
||
method: "DELETE",
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 申请资源(旧接口,已废弃)
|
||
* @deprecated 请使用 applyForPlatformAgent 或 applyForProvider
|
||
*/
|
||
static async applyForResources(data: {
|
||
type: "model" | "agent"
|
||
modelName?: string
|
||
rpm?: number
|
||
tpm?: number
|
||
agentType?: string
|
||
quantity?: number
|
||
reason: string
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/channel/resources/apply`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 渠道申请平台 Agent
|
||
* POST /api/channel/applications/platform-agents
|
||
*
|
||
* @param templateName - Agent模板名称(如 gpt-assistant, jina-search-agent 等)
|
||
* @param requestedPodQuota - 申请的Pod配额数量
|
||
* @param reason - 申请理由
|
||
*/
|
||
static async applyForPlatformAgent(data: {
|
||
templateName: string
|
||
requestedPodQuota: number
|
||
reason: string
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/channel/applications/platform-agents`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取渠道的平台 Agent 申请列表
|
||
* GET /api/channel/applications/platform-agents
|
||
*
|
||
* @param status - 可选,筛选状态:pending | approved | rejected
|
||
*/
|
||
static async getChannelPlatformAgentApplications(status?: "pending" | "approved" | "rejected") {
|
||
const url = status
|
||
? `${API_BASE_URLS.mcpServer}/api/channel/applications/platform-agents?status=${status}`
|
||
: `${API_BASE_URLS.mcpServer}/api/channel/applications/platform-agents`
|
||
const response = await fetch(url, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取渠道计费统计
|
||
*/
|
||
static async getChannelBillingStats(params: {
|
||
startTime: string
|
||
endTime: string
|
||
tenantName?: string
|
||
minCalls?: number
|
||
maxCalls?: number
|
||
export?: "excel" | "csv" | "pdf"
|
||
}) {
|
||
const queryParams = new URLSearchParams()
|
||
Object.entries(params).forEach(([key, value]) => {
|
||
if (value !== undefined) {
|
||
queryParams.append(key, value.toString())
|
||
}
|
||
})
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/channel/billing/stats?${queryParams}`,
|
||
{
|
||
headers: buildHeaders(),
|
||
},
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取渠道可用供应商列表
|
||
* GET /api/channel/providers
|
||
* 获取所有可用的模型供应商列表,并标注渠道是否已获得使用授权
|
||
*/
|
||
static async getChannelProviders() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/channel/providers`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 申请使用供应商
|
||
* POST /api/channel/providers/apply
|
||
*/
|
||
static async applyForProvider(data: {
|
||
providerId: string
|
||
requestedRpm?: number
|
||
requestedTpm?: number
|
||
reason: string
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/channel/providers/apply`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取供应商申请列表
|
||
* GET /api/channel/providers/applications
|
||
*/
|
||
static async getChannelProviderApplications(status?: "pending" | "approved" | "rejected") {
|
||
const url = status
|
||
? `${API_BASE_URLS.mcpServer}/api/channel/providers/applications?status=${status}`
|
||
: `${API_BASE_URLS.mcpServer}/api/channel/providers/applications`
|
||
const response = await fetch(url, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取渠道下的管理员列表
|
||
* GET /api/channel/admins
|
||
*/
|
||
static async getChannelAdmins() {
|
||
const url = `${API_BASE_URLS.mcpServer}/api/channel/admins`
|
||
console.log("🌐 API请求: GET", url)
|
||
const headers = buildHeaders()
|
||
console.log("📋 请求头:", headers)
|
||
const response = await fetch(url, { headers })
|
||
console.log("📨 响应状态:", response.status, response.statusText)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 创建渠道下的管理员
|
||
* POST /api/channel/admins/create
|
||
*/
|
||
static async createChannelAdmin(data: {
|
||
name: string
|
||
email: string
|
||
password: string
|
||
role?: "billing_admin" | "operations_admin"
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/channel/admins/create`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
// ==================== 超级管理员 API ====================
|
||
// Base URL: http://localhost:8002/api/admin
|
||
|
||
/**
|
||
* 获取平台统计
|
||
*/
|
||
static async getAdminDashboardStats() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/dashboard/stats`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取管理员列表(仅超级管理员可用)
|
||
*/
|
||
static async getAdmins() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/admins`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 创建管理员(计费管理员/运营管理员)
|
||
* POST /api/admin/admins/create
|
||
*
|
||
* @param data.name - 管理员名称
|
||
* @param data.email - 管理员邮箱,用于登录
|
||
* @param data.password - 管理员密码
|
||
* @param data.role - 角色类型:billing_admin(计费管理员)或 operations_admin(运维管理员)
|
||
* @param data.channelId - 渠道ID(可选),如果提供则创建渠道管理员
|
||
*/
|
||
static async createAdmin(data: {
|
||
name: string
|
||
email: string
|
||
password: string
|
||
role: "billing_admin" | "operations_admin"
|
||
channelId?: string // 可选参数
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/admins/create`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 删除管理员(软删除)
|
||
*/
|
||
static async deleteAdmin(adminId: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/admins/${adminId}`, {
|
||
method: "DELETE",
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取渠道列表
|
||
*/
|
||
static async getAdminChannels() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/channels`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 创建渠道
|
||
* POST /api/admin/channels/create
|
||
*/
|
||
static async createAdminChannel(data: {
|
||
name: string
|
||
email: string
|
||
password: string
|
||
commissionRate: number
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/channels/create`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 更新渠道信息
|
||
*/
|
||
static async updateAdminChannel(channelId: string, data: {
|
||
name?: string
|
||
commissionRate?: number
|
||
isActive?: boolean
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/channels/${channelId}`, {
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 删除渠道(软删除)
|
||
*/
|
||
static async deleteAdminChannel(channelId: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/channels/${channelId}`, {
|
||
method: "DELETE",
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取渠道供应商授权列表
|
||
* GET /api/admin/providers/access
|
||
*/
|
||
static async getChannelProviderAccess(params?: {
|
||
channelId?: string
|
||
providerId?: string
|
||
status?: "active" | "suspended" | "expired"
|
||
}) {
|
||
const queryParams = new URLSearchParams()
|
||
if (params?.channelId) queryParams.append("channel_id", params.channelId)
|
||
if (params?.providerId) queryParams.append("provider_id", params.providerId)
|
||
if (params?.status) queryParams.append("status", params.status)
|
||
|
||
const url = queryParams.toString()
|
||
? `${API_BASE_URLS.mcpServer}/api/admin/providers/access?${queryParams}`
|
||
: `${API_BASE_URLS.mcpServer}/api/admin/providers/access`
|
||
|
||
const response = await fetch(url, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 更新渠道供应商授权
|
||
* PUT /api/admin/providers/access/{access_id}
|
||
*/
|
||
static async updateChannelProviderAccess(accessId: string, params: {
|
||
status?: "active" | "suspended" | "expired"
|
||
rpmLimit?: number
|
||
tpmLimit?: number
|
||
}) {
|
||
const queryParams = new URLSearchParams()
|
||
if (params.status) queryParams.append("status", params.status)
|
||
if (params.rpmLimit) queryParams.append("rpm_limit", params.rpmLimit.toString())
|
||
if (params.tpmLimit) queryParams.append("tpm_limit", params.tpmLimit.toString())
|
||
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/admin/providers/access/${accessId}?${queryParams}`,
|
||
{
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
}
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 撤销渠道供应商授权
|
||
* DELETE /api/admin/providers/access/{access_id}
|
||
*/
|
||
static async revokeChannelProviderAccess(accessId: string) {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/admin/providers/access/${accessId}`,
|
||
{
|
||
method: "DELETE",
|
||
headers: buildHeaders(),
|
||
}
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取渠道资源分配
|
||
* GET /api/admin/channels/{channel_id}/resources
|
||
*/
|
||
static async getChannelResources(channelId: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/channels/${channelId}/resources`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 统一管理渠道资源
|
||
* PUT /api/admin/channels/{channel_id}/resources
|
||
*/
|
||
static async manageChannelResources(
|
||
channelId: string,
|
||
data: {
|
||
models?: string[]
|
||
agents?: Array<{ agentId: string; quantity: number }>
|
||
customAgentResources?: { cpu: number; memory: number }
|
||
channelCredit?: number
|
||
},
|
||
) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/channels/${channelId}/resources`, {
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 更新渠道佣金比例
|
||
* PUT /api/admin/channels/{channel_id}/commission
|
||
*/
|
||
static async updateChannelCommission(channelId: string, commissionRate: number) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/channels/${channelId}/commission`, {
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify({ commissionRate }),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取所有申请(旧的通用接口)
|
||
* @deprecated 请使用 getProviderApplications 或 getPlatformAgentApplications
|
||
*/
|
||
static async getAdminApplications() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/channels/applications`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取供应商申请列表
|
||
* GET /api/admin/providers/applications
|
||
* 用于"渠道申请审批"功能
|
||
*/
|
||
static async getProviderApplications(status?: "pending" | "approved" | "rejected") {
|
||
const url = status
|
||
? `${API_BASE_URLS.mcpServer}/api/admin/providers/applications?status=${status}`
|
||
: `${API_BASE_URLS.mcpServer}/api/admin/providers/applications`
|
||
const response = await fetch(url, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 审批供应商申请
|
||
* PUT /api/admin/providers/applications/{application_id}/review
|
||
*/
|
||
static async reviewProviderApplication(applicationId: string, approved: boolean, reason?: string) {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/admin/providers/applications/${applicationId}/review`,
|
||
{
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify({ approved, reason }),
|
||
},
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 审批申请(旧的通用接口)
|
||
* @deprecated 请使用 reviewProviderApplication 或 reviewPlatformAgentApplication
|
||
*/
|
||
static async reviewApplication(applicationId: string, approved: boolean, reason?: string) {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/admin/channels/applications/${applicationId}/review`,
|
||
{
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify({ approved, reason }),
|
||
},
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取所有模型供应商
|
||
*/
|
||
static async getAdminModelProviders() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/providers/models`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取所有Agent资源
|
||
* @deprecated v1.3.0 已废弃,请使用 getPlatformAgentStatus() 替代
|
||
*/
|
||
static async getAdminAgentResources() {
|
||
// 调用新接口 getPlatformAgentStatus
|
||
return this.getPlatformAgentStatus()
|
||
}
|
||
|
||
/**
|
||
* 删除Agent资源
|
||
* @deprecated v1.3.0 已废弃,Agent 通过 K8s 管理,无需单独删除接口
|
||
*/
|
||
static async deleteAgentResource(agentId: string) {
|
||
console.warn("deleteAgentResource 已废弃,Agent 通过 K8s 管理")
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/resources/agents/${agentId}`, {
|
||
method: "DELETE",
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 更新Agent资源配置(CPU、内存、最大实例数)
|
||
* @deprecated v1.3.0 已废弃,请使用 configurePlatformAgentTemplate() 替代
|
||
*/
|
||
static async updateAgentResourceConfig(agentId: string, data: {
|
||
cpu?: number
|
||
memory?: number
|
||
maxInstances?: number
|
||
cpu_request?: string
|
||
cpu_limit?: string
|
||
memory_request?: string
|
||
memory_limit?: string
|
||
}) {
|
||
console.warn("updateAgentResourceConfig 已废弃,请使用 configurePlatformAgentTemplate() 替代")
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/resources/agents/${agentId}/config`, {
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 监控Agent健康状态
|
||
* @deprecated v1.3.0 已废弃,请使用 getPlatformAgentStatus() 替代
|
||
*/
|
||
static async getAdminAgentMonitoring() {
|
||
// 调用新接口 getPlatformAgentStatus
|
||
return this.getPlatformAgentStatus()
|
||
}
|
||
|
||
/**
|
||
* 获取三维度计费统计
|
||
*/
|
||
static async getAdminBillingOverview(params: {
|
||
startTime: string
|
||
endTime: string
|
||
channelName?: string
|
||
tenantName?: string
|
||
minCalls?: number
|
||
maxCalls?: number
|
||
export?: "excel" | "csv" | "pdf"
|
||
}) {
|
||
const queryParams = new URLSearchParams()
|
||
Object.entries(params).forEach(([key, value]) => {
|
||
if (value !== undefined) {
|
||
queryParams.append(key, value.toString())
|
||
}
|
||
})
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/admin/billing/overview?${queryParams}`,
|
||
{
|
||
headers: buildHeaders(),
|
||
},
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取供应商统计信息
|
||
*/
|
||
static async getAdminProviderStats() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/providers/stats`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取渠道后台简易统计
|
||
*/
|
||
static async getAdminChannelsBackendStats() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/channels/backend/stats`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取所有租户列表(超级管理员)
|
||
* GET /api/admin/tenants
|
||
*/
|
||
static async getAdminTenants() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/tenants`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 修改租户密码(渠道管理员或超级管理员)
|
||
* PUT /api/channel/tenants/{tenant_id}/password
|
||
*
|
||
* @param tenantId - 租户ID
|
||
* @param newPassword - 新密码
|
||
* @param channelId - 渠道ID(超级管理员必须作为查询参数提供)
|
||
*/
|
||
static async changeTenantPassword(tenantId: string, newPassword: string, channelId?: string) {
|
||
let url = `${API_BASE_URLS.mcpServer}/api/channel/tenants/${tenantId}/password`
|
||
// 超级管理员需要在查询参数中提供 channel_id
|
||
if (channelId) {
|
||
url += `?channel_id=${encodeURIComponent(channelId)}`
|
||
}
|
||
const response = await fetch(url, {
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify({ newPassword }),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取最近登录的租户列表
|
||
* GET /api/admin/dashboard/recent-logins
|
||
*
|
||
* @param limit - 返回的记录数量,默认10,最多50
|
||
* @returns 最近登录的租户列表,包含租户ID、名称、邮箱、渠道信息、最后登录时间、状态
|
||
*/
|
||
static async getRecentLogins(limit: number = 10) {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/admin/dashboard/recent-logins?limit=${limit}`,
|
||
{
|
||
headers: buildHeaders(),
|
||
}
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
// ==================== 资源申请审批模块 API ====================
|
||
// Base URL: http://localhost:8002/api/admin/applications
|
||
|
||
/**
|
||
* 获取平台 Agent 申请列表(管理员)
|
||
* GET /api/admin/applications/platform-agents
|
||
*
|
||
* @param status - 可选,筛选状态:pending | approved | rejected
|
||
*/
|
||
static async getPlatformAgentApplications(status?: "pending" | "approved" | "rejected") {
|
||
const url = status
|
||
? `${API_BASE_URLS.mcpServer}/api/admin/applications/platform-agents?status=${status}`
|
||
: `${API_BASE_URLS.mcpServer}/api/admin/applications/platform-agents`
|
||
const response = await fetch(url, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 审批平台 Agent 申请
|
||
* PUT /api/admin/applications/platform-agents/{application_id}/review
|
||
*
|
||
* @param applicationId - 申请ID
|
||
* @param action - 审批动作:approve 或 reject
|
||
* @param podQuota - 批准的Pod配额数量(approve 时必填)
|
||
* @param reviewReason - 审批意见(可选)
|
||
*/
|
||
static async reviewPlatformAgentApplication(
|
||
applicationId: string,
|
||
action: "approve" | "reject",
|
||
podQuota?: number,
|
||
reviewReason?: string
|
||
) {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/admin/applications/platform-agents/${applicationId}/review`,
|
||
{
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify({ action, podQuota, reviewReason }),
|
||
}
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
// ==================== 平台 Agent 管理模块 API ====================
|
||
// Base URL: http://localhost:8002/api/admin/platform-agents
|
||
|
||
/**
|
||
* 获取平台 Agent 模板列表
|
||
* GET /api/admin/platform-agents/templates
|
||
*/
|
||
static async getPlatformAgentTemplates() {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/admin/platform-agents/templates`,
|
||
{
|
||
headers: buildHeaders(),
|
||
}
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取平台 Agent 分配情况
|
||
* GET /api/admin/platform-agents/allocations
|
||
*/
|
||
static async getPlatformAgentAllocations() {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/admin/platform-agents/allocations`,
|
||
{
|
||
headers: buildHeaders(),
|
||
}
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取平台 Agent 运行状态
|
||
* GET /api/admin/platform-agents/status
|
||
*
|
||
* 这是 v1.3.0 中查看平台 Agent 的主接口,替代了:
|
||
* - GET /api/admin/resources/agents
|
||
* - GET /api/admin/monitoring/agents
|
||
* - GET /api/admin/resources/allocation-stats
|
||
*/
|
||
static async getPlatformAgentStatus() {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/admin/platform-agents/status`,
|
||
{
|
||
headers: buildHeaders(),
|
||
}
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 配置平台 Agent 模板
|
||
* PUT /api/admin/platform-agents/templates/{name}/config
|
||
*
|
||
* 管理员配置平台 Agent 模板的资源参数。这些参数将用于启动 Pod 时的 K8s 资源配置。
|
||
*
|
||
* @param templateName - 模板名称(如 echo_agent, jina_search_agent)
|
||
* @param data.cpuRequest - CPU 请求量,K8s 格式(如 "100m" = 0.1 核)
|
||
* @param data.cpuLimit - CPU 上限,K8s 格式(如 "500m" = 0.5 核)
|
||
* @param data.memoryRequest - 内存请求量,K8s 格式(如 "128Mi" = 128 MiB)
|
||
* @param data.memoryLimit - 内存上限,K8s 格式(如 "512Mi" = 512 MiB)
|
||
* @param data.maxPods - 最大 Pod 数量,默认 0(无限制)
|
||
* @param data.isEnabled - 是否启用,默认 true
|
||
* @param data.displayName - 显示名称
|
||
* @param data.description - 模板描述
|
||
*/
|
||
static async configurePlatformAgentTemplate(
|
||
templateName: string,
|
||
data: {
|
||
cpuRequest?: string
|
||
cpuLimit?: string
|
||
memoryRequest?: string
|
||
memoryLimit?: string
|
||
maxPods?: number
|
||
isEnabled?: boolean
|
||
displayName?: string
|
||
description?: string
|
||
}
|
||
) {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/admin/platform-agents/templates/${templateName}/config`,
|
||
{
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
}
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取平台 Agent 模板配置
|
||
* GET /api/admin/platform-agents/templates/{name}/config
|
||
*
|
||
* 获取指定模板的资源配置详情
|
||
*
|
||
* @param templateName - 模板名称
|
||
*/
|
||
static async getPlatformAgentTemplateConfig(templateName: string) {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/admin/platform-agents/templates/${templateName}/config`,
|
||
{
|
||
headers: buildHeaders(),
|
||
}
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 直接分配平台 Agent 配额给渠道
|
||
* POST /api/admin/platform-agents/allocate
|
||
*
|
||
* @param channelId - 渠道ID
|
||
* @param templateName - 模板名称(如 gpt-assistant)
|
||
* @param podQuota - Pod配额数量(≥1)
|
||
*/
|
||
static async allocatePlatformAgentToChannel(
|
||
channelId: string,
|
||
templateName: string,
|
||
podQuota: number
|
||
) {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/admin/platform-agents/allocate?channel_id=${channelId}&template_name=${templateName}&pod_quota=${podQuota}`,
|
||
{
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
}
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 撤销渠道的平台 Agent 配额
|
||
* DELETE /api/admin/platform-agents/allocate
|
||
*
|
||
* @param channelId - 渠道ID
|
||
* @param templateName - 模板名称
|
||
*/
|
||
static async revokePlatformAgentFromChannel(channelId: string, templateName: string) {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/admin/platform-agents/allocate?channel_id=${channelId}&template_name=${templateName}`,
|
||
{
|
||
method: "DELETE",
|
||
headers: buildHeaders(),
|
||
}
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 渠道查看可用平台 Agent(ACR模板)
|
||
* GET /api/channel/available-platform-agents
|
||
*
|
||
* 查看所有可用的平台 Agent 模板,以及渠道是否已获得使用权限
|
||
* 返回的模板包含 cpuRequest, cpuLimit, memoryRequest, memoryLimit 等K8s资源配置
|
||
*/
|
||
static async getAvailablePlatformAgents() {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/channel/available-platform-agents`,
|
||
{
|
||
headers: buildHeaders(),
|
||
}
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 渠道查看平台 Agent 配额
|
||
* GET /api/channel/platform-agents
|
||
*/
|
||
static async getChannelPlatformAgents() {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/channel/platform-agents`,
|
||
{
|
||
headers: buildHeaders(),
|
||
}
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
// ==================== 供应商管理 API ====================
|
||
// Base URL: http://localhost:8002/api/providers
|
||
|
||
/**
|
||
* 获取模型供应商列表
|
||
*/
|
||
static async getModelProviders() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/providers/models`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 创建模型供应商
|
||
*/
|
||
static async createModelProvider(data: {
|
||
name: string
|
||
provider: "openai" | "anthropic" | "azure" | "google" | "aws"
|
||
apiUrl: string
|
||
apiKey: string
|
||
supportedModels: string[]
|
||
rpm: number
|
||
tpm: number
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/providers/models/create`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取供应商详情
|
||
*/
|
||
static async getProviderDetails(providerId: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/providers/models/${providerId}`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 更新供应商配置
|
||
*/
|
||
static async updateProvider(providerId: string, data: {
|
||
name?: string
|
||
provider?: string
|
||
apiUrl?: string
|
||
apiKey?: string
|
||
supportedModels?: string[]
|
||
rpm?: number
|
||
tpm?: number
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/providers/models/${providerId}`, {
|
||
method: "PUT",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 删除供应商
|
||
*/
|
||
static async deleteProvider(providerId: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/providers/models/${providerId}`, {
|
||
method: "DELETE",
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 测试供应商连接
|
||
*/
|
||
static async testProviderConnection(providerId: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/providers/models/${providerId}/test`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
// ==================== Data Ingestion 服务 API ====================
|
||
// Base URL: http://localhost:8001
|
||
|
||
/**
|
||
* 健康检查
|
||
*/
|
||
static async getHealth() {
|
||
const response = await fetch(`${API_BASE_URLS.dataIngestion}/health`)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 同步 RapidAPI
|
||
*/
|
||
static async syncRapidAPI(category?: string, limit = 100) {
|
||
const params = new URLSearchParams()
|
||
if (category) params.append("category", category)
|
||
params.append("limit", limit.toString())
|
||
|
||
const response = await fetch(`${API_BASE_URLS.dataIngestion}/rapidapi/sync?${params}`, {
|
||
method: "POST",
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 测试 RapidAPI 端点
|
||
*/
|
||
static async testRapidAPI(data: {
|
||
endpoint: string
|
||
method: string
|
||
params?: any
|
||
headers?: any
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.dataIngestion}/rapidapi/test`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 解析 OpenAPI 规范
|
||
*/
|
||
static async parseOpenAPI(url: string) {
|
||
const response = await fetch(`${API_BASE_URLS.dataIngestion}/openapi/parse?url=${encodeURIComponent(url)}`, {
|
||
method: "POST",
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* APILLAMA 处理 API 文档
|
||
*/
|
||
static async processAPILLAMA(
|
||
apiDoc: any,
|
||
context?: any,
|
||
outputFormat: "pydantic" | "json_schema" | "openapi" = "json_schema",
|
||
options?: {
|
||
include_examples?: boolean
|
||
enhance_descriptions?: boolean
|
||
validate_schema?: boolean
|
||
},
|
||
) {
|
||
const response = await fetch(`${API_BASE_URLS.dataIngestion}/apillama/process`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify({
|
||
api_doc: apiDoc,
|
||
context,
|
||
output_format: outputFormat,
|
||
...options,
|
||
}),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 从 API 端点生成工具定义 (Data Ingestion 服务)
|
||
*/
|
||
static async generateToolFromEndpoint(data: {
|
||
url: string
|
||
method: string
|
||
name: string
|
||
description: string
|
||
parameters?: Array<{
|
||
name: string
|
||
type: string
|
||
location?: "query" | "path" | "header" | "body"
|
||
description?: string
|
||
required?: boolean
|
||
}>
|
||
request_body?: any
|
||
responses?: any
|
||
security?: any[]
|
||
tags?: string[]
|
||
deprecated?: boolean
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.dataIngestion}/tools/generate`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取工具列表
|
||
*/
|
||
static async getTools(category?: string, limit = 100, offset = 0) {
|
||
const params = new URLSearchParams({ limit: limit.toString(), offset: offset.toString() })
|
||
if (category) params.append("category", category)
|
||
|
||
const response = await fetch(`${API_BASE_URLS.dataIngestion}/tools?${params}`)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取特定工具定义
|
||
*/
|
||
static async getTool(toolName: string) {
|
||
const response = await fetch(`${API_BASE_URLS.dataIngestion}/tools/${toolName}`)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 删除工具
|
||
*/
|
||
static async deleteTool(toolName: string) {
|
||
const response = await fetch(`${API_BASE_URLS.dataIngestion}/tools/${toolName}`, {
|
||
method: "DELETE",
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取统计信息
|
||
*/
|
||
static async getStats() {
|
||
const response = await fetch(`${API_BASE_URLS.dataIngestion}/stats`)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 清除缓存
|
||
*/
|
||
static async clearCache() {
|
||
const response = await fetch(`${API_BASE_URLS.dataIngestion}/cache/clear`, {
|
||
method: "POST",
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取 Prometheus Metrics
|
||
*/
|
||
static async getMetrics() {
|
||
const response = await fetch(`${API_BASE_URLS.dataIngestion}/metrics`)
|
||
return response.text()
|
||
}
|
||
|
||
// ==================== MCP Server 服务 API ====================
|
||
// Base URL: http://localhost:8000
|
||
|
||
/**
|
||
* MCP Server 健康检查
|
||
*/
|
||
static async getMCPHealth() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/health`)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 注册 Agent
|
||
*/
|
||
static async registerAgent(data: {
|
||
name: string
|
||
description: string
|
||
role?: string
|
||
goal?: string
|
||
tools?: string[]
|
||
config?: any
|
||
capabilities?: string[]
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/agents`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取 Agent 列表
|
||
*/
|
||
static async getAgents(skip = 0, limit = 100) {
|
||
const params = new URLSearchParams({ skip: skip.toString(), limit: limit.toString() })
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/agents?${params}`)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取特定 Agent
|
||
*/
|
||
static async getAgent(agentId: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/agents/${agentId}`)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 执行 Agent 工具
|
||
*/
|
||
static async executeAgentTool(agentId: string, data: {
|
||
jsonrpc?: string
|
||
id?: string
|
||
method: string
|
||
params: {
|
||
tool: { name: string; function_name?: string }
|
||
arguments: any
|
||
context?: any
|
||
}
|
||
}) {
|
||
// 构建请求体,如果data中已有jsonrpc和id则使用,否则使用默认值
|
||
const requestBody = {
|
||
jsonrpc: data.jsonrpc || "2.0",
|
||
id: data.id || `req-${Date.now()}`,
|
||
method: data.method,
|
||
params: data.params,
|
||
}
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/agents/${agentId}/execute`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(requestBody),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取工具列表 (MCP Server)
|
||
*/
|
||
static async getMCPTools() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/tools`)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
// ==================== K8s Agent 管理 API ====================
|
||
// Base URL: http://localhost:8002/agents
|
||
|
||
/**
|
||
* 获取所有可用的 Agent 模板及其所需参数
|
||
* GET /api/admin/platform-agents/templates
|
||
* 此接口已在 v1.3.0 中重构
|
||
*/
|
||
static async getAgentTemplates() {
|
||
return this.getPlatformAgentTemplates()
|
||
}
|
||
|
||
/**
|
||
* 获取指定模板的详细信息
|
||
* GET /api/admin/platform-agents/templates/{name}/config
|
||
*/
|
||
static async getAgentTemplateDetail(templateName: string) {
|
||
return this.getPlatformAgentTemplateConfig(templateName)
|
||
}
|
||
|
||
/**
|
||
* 创建 K8s Agent
|
||
* POST /api/user/platform-agents/use
|
||
* 在 v1.3.0 中,租户使用平台 Agent 统一使用该接口
|
||
*/
|
||
static async createK8sAgent(data: {
|
||
name: string
|
||
description?: string
|
||
template?: string
|
||
resource_config?: {
|
||
cpu_request?: string
|
||
cpu_limit?: string
|
||
memory_request?: string
|
||
memory_limit?: string
|
||
replicas?: number
|
||
env?: Record<string, string>
|
||
}
|
||
}) {
|
||
// 映射旧参数到新接口
|
||
const apiData = {
|
||
templateName: data.template || data.name,
|
||
agentType: "chat", // 默认
|
||
}
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/platform-agents/use`, {
|
||
method: "POST",
|
||
headers: buildHeaders("application/json", true),
|
||
body: JSON.stringify(apiData),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 删除 Agent
|
||
* DELETE /api/user/platform-agents/{instance_name}
|
||
*/
|
||
static async deleteAgent(agentId: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/platform-agents/${agentId}`, {
|
||
method: "DELETE",
|
||
headers: buildHeaders("application/json", true),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取 Agent 的实时状态
|
||
* GET /api/admin/platform-agents/status
|
||
*/
|
||
static async getAgentStatus(agentId: string) {
|
||
// v1.3.0 推荐使用 getPlatformAgentStatus 获取所有,或者这里调用状态接口
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/platform-agents/status`)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取 Agent 的 CPU 和内存资源配置信息
|
||
* GET /agents/{agent_id}/metrics
|
||
*/
|
||
static async getAgentMetrics(agentId: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/agents/${agentId}/metrics`)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取 MCP Prometheus Metrics
|
||
*/
|
||
static async getMCPMetrics() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/metrics`)
|
||
return response.text()
|
||
}
|
||
|
||
/**
|
||
* 获取系统性能指标
|
||
*/
|
||
static async getMonitoringMetrics() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/v1/monitoring/metrics`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取服务统计信息
|
||
*/
|
||
static async getMonitoringStats(service: "all" | "agents" | "executions" | "tools" | "users" = "all") {
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/v1/monitoring/stats?service=${service}`,
|
||
{
|
||
headers: buildHeaders(),
|
||
},
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取性能趋势数据
|
||
*/
|
||
static async getMonitoringTrends(params: {
|
||
metric?: "executions" | "eu_consumption"
|
||
period?: "24h" | "7d" | "30d"
|
||
interval?: "1h" | "6h" | "1d"
|
||
}) {
|
||
const queryParams = new URLSearchParams()
|
||
Object.entries(params).forEach(([key, value]) => {
|
||
if (value) {
|
||
queryParams.append(key, value)
|
||
}
|
||
})
|
||
const response = await fetch(
|
||
`${API_BASE_URLS.mcpServer}/api/v1/monitoring/trends?${queryParams}`,
|
||
{
|
||
headers: buildHeaders(),
|
||
},
|
||
)
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取系统告警
|
||
*/
|
||
static async getMonitoringAlerts(severity?: "info" | "warning" | "critical") {
|
||
const params = severity ? `?severity=${severity}` : ""
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/v1/monitoring/alerts${params}`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取监控仪表盘聚合
|
||
*/
|
||
static async getMonitoringDashboard() {
|
||
try {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/v1/monitoring/dashboard`, {
|
||
headers: buildHeaders(),
|
||
signal: AbortSignal.timeout(10000), // 10 second timeout
|
||
})
|
||
return await handleResponse(response)
|
||
} catch (error: any) {
|
||
// 处理网络错误
|
||
if (error.name === "AbortError" || error.message?.includes("timeout")) {
|
||
throw new Error("请求超时,请检查网络连接或后端服务状态")
|
||
}
|
||
if (error.message?.includes("Failed to fetch") || error.name === "TypeError") {
|
||
throw new Error(
|
||
`无法连接到后端服务 (${API_BASE_URLS.mcpServer})。请确保 MCP Server 正在运行。`,
|
||
)
|
||
}
|
||
throw error
|
||
}
|
||
}
|
||
|
||
// ==================== 用户计费模块 API ====================
|
||
|
||
/**
|
||
* 获取用户 EU 余额
|
||
* GET /api/user/billing/balance
|
||
*/
|
||
static async getUserBalance() {
|
||
try {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/billing/balance`, {
|
||
method: "GET",
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse<APIResponse<{ balance: number; currency?: string; monthlySpent?: number }>>(response)
|
||
} catch (error) {
|
||
console.error("Failed to get user balance:", error)
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取用户资源信息(LiteLLM 密钥和 Agent 信息)
|
||
* GET /api/user/resources/info
|
||
*
|
||
* 返回用户的 LiteLLM 密钥(解密后)和已部署 Agent 的详细信息
|
||
*
|
||
* @returns {
|
||
* litellmKeys: Array<{
|
||
* modelName: string, // 模型名称
|
||
* apiKey: string, // 解密后的完整 API Key
|
||
* apiBase: string, // LiteLLM 网关地址
|
||
* rpmLimit: number, // 每分钟请求数限制
|
||
* tpmLimit: number, // 每分钟 Token 数限制
|
||
* status: string, // 密钥状态
|
||
* createdAt: string // 创建时间
|
||
* }>,
|
||
* litellmApiBase: string, // LiteLLM 网关地址(全局)
|
||
* platformAgents: Array, // 已部署的平台 Agent 列表
|
||
* customAgents: Array, // 已部署的自定义 Agent 列表
|
||
* summary: object // 汇总统计信息
|
||
* }
|
||
*/
|
||
static async getUserResourcesInfo() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/resources/info`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取用户已部署的Agent列表(包含实时状态信息)
|
||
* GET /api/user/resources/agents
|
||
*
|
||
* 返回用户已部署的平台Agent和自定义Agent列表,包含从AKS实时查询的状态信息
|
||
*
|
||
* 【前端必须展示的字段】:
|
||
* - name: Agent名称
|
||
* - status: Agent状态(Running/Stopped/Pending等)
|
||
* - accessUrl: 访问URL(AKS实时,推荐使用)
|
||
* - templateName: 模板名称(用于区分网关类型:MCP/A2A/API)
|
||
*/
|
||
static async getUserResourcesAgents() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/resources/agents`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
// ==================== 租户代理工厂 API ====================
|
||
// 基于文档: 租户用户端-代理工厂对接文档.md
|
||
|
||
/**
|
||
* 获取可用平台Agent列表(租户)
|
||
* GET /api/user/platform-agents/available
|
||
*
|
||
* 返回渠道分配给该租户的所有平台Agent模板,包含每个模板的配额信息
|
||
*/
|
||
static async getUserAvailablePlatformAgents() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/platform-agents/available`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 查看平台Agent配额使用情况(租户)
|
||
* GET /api/user/platform-agents/quota
|
||
*
|
||
* 返回当前租户的平台Agent配额汇总信息,按模板分组显示使用情况
|
||
*/
|
||
static async getUserPlatformAgentQuota() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/platform-agents/quota`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 部署Agent(租户手动部署)
|
||
* POST /api/user/agents/deploy
|
||
*
|
||
* @param data.agentId - Agent模板ID(从可用列表获取)
|
||
* @param data.instances - 实例数量(副本数)
|
||
* @param data.model - 使用的模型名称
|
||
* @param data.gateway - 服务网关类型:MCP / A2A / API
|
||
*/
|
||
static async deployUserAgent(data: {
|
||
agentId: string
|
||
instances: number
|
||
model: string
|
||
gateway: "MCP" | "A2A" | "API"
|
||
}) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/agents/deploy`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify(data),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取已部署的Agent实例列表(租户)
|
||
* GET /api/user/platform-agents/instances
|
||
*
|
||
* 返回当前用户所有正在运行/已停止的平台Agent实例
|
||
*/
|
||
static async getUserPlatformAgentInstances() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/platform-agents/instances`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 启动平台Agent实例(租户)
|
||
* POST /api/user/platform-agents/use
|
||
*
|
||
* @param agentType - Agent模板名称(如"code-assistant")
|
||
*/
|
||
static async startUserPlatformAgent(agentType: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/platform-agents/use`, {
|
||
method: "POST",
|
||
headers: buildHeaders(),
|
||
body: JSON.stringify({ agentType }),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 删除平台 Agent 实例(租户)
|
||
* DELETE /api/user/platform-agents/{agent_name}
|
||
*
|
||
* 删除用户正在运行的平台 Agent 实例,释放 Pod 配额,结算费用
|
||
*
|
||
* @param agentName - 平台 Agent 实例名称(Pod 名称)
|
||
*/
|
||
static async deleteUserPlatformAgent(agentName: string) {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/platform-agents/${agentName}`, {
|
||
method: "DELETE",
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* @deprecated 使用 deleteUserPlatformAgent 替代
|
||
*/
|
||
static async stopUserPlatformAgent(instanceName: string) {
|
||
return this.deleteUserPlatformAgent(instanceName)
|
||
}
|
||
|
||
/**
|
||
* 获取自定义Agent配额(租户)
|
||
* GET /api/user/custom-agent-quota
|
||
*
|
||
* 返回租户的CPU和内存配额信息,用于展示总资源使用情况
|
||
*/
|
||
static async getUserCustomAgentQuota() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/custom-agent-quota`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
// ==================== WebSocket API ====================
|
||
|
||
/**
|
||
* 创建 Agent WebSocket 连接
|
||
*/
|
||
static createAgentWebSocket(agentIdOrName: string) {
|
||
const wsUrl = API_BASE_URLS.mcpServer.replace("http", "ws")
|
||
return new WebSocket(`${wsUrl}/ws/${agentIdOrName}`)
|
||
}
|
||
|
||
// ==================== LiteLLM 模型列表 API ====================
|
||
// 通过后端接口安全获取 LiteLLM 模型列表
|
||
|
||
/**
|
||
* 获取 LiteLLM 可用模型列表
|
||
* GET /api/admin/resources/litellm-models
|
||
*
|
||
* 从后端获取 LiteLLM Gateway 的所有可用模型列表,用于供应商配置时选择可调用的模型
|
||
* 后端会安全地调用 LiteLLM API,避免在前端暴露 API 密钥
|
||
*
|
||
* @returns 模型列表响应,包含 models 数组、total 总数和 providers 供应商分组统计
|
||
*/
|
||
static async getLiteLLMModels(): Promise<APIResponse<{
|
||
models: Array<{
|
||
id: string
|
||
name: string
|
||
provider: string
|
||
object: string
|
||
ownedBy: string
|
||
}>
|
||
total: number
|
||
providers: Array<{
|
||
provider: string
|
||
count: number
|
||
}>
|
||
}>> {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/admin/resources/litellm-models`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
|
||
/**
|
||
* 获取 LiteLLM 模型 ID 列表(简化版)
|
||
*
|
||
* 只返回模型 ID 字符串数组,方便下拉框使用
|
||
*
|
||
* @returns 模型 ID 数组,如 ["gpt-4o", "claude-3-5-sonnet-20241022", ...]
|
||
*/
|
||
static async getLiteLLMModelIds(): Promise<string[]> {
|
||
const result = await this.getLiteLLMModels()
|
||
if (result.success && result.data?.models) {
|
||
return result.data.models.map(model => model.id)
|
||
}
|
||
return []
|
||
}
|
||
|
||
/**
|
||
* 获取用户可用的模型列表
|
||
* GET /api/user/models
|
||
*/
|
||
static async getUserModels() {
|
||
const response = await fetch(`${API_BASE_URLS.mcpServer}/api/user/models`, {
|
||
headers: buildHeaders(),
|
||
})
|
||
return handleResponse(response)
|
||
}
|
||
}
|