mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
feat: 手动代理节点支持、系统默认代理与跨格式流式 usage 提取
代理节点: - 支持手动添加代理节点(HTTP/HTTPS/SOCKS5),含地址、认证信息和区域标签 - 新增手动节点的 CRUD API 和前端管理界面 - 提供商代理配置从 URL 字符串迁移至代理节点选择器(proxy_node_id) - 新增系统默认代理节点设置,未单独配置代理的提供商自动回退使用 - 删除节点时自动清除系统默认代理引用并失效缓存 - 健康检查跳过手动节点(无心跳,始终在线) 流式处理: - CLI handler 跨格式转换时委托基类解析 Provider 原始事件的 usage - StreamProcessor 新增 _extract_usage_from_converted_event 从转换后事件补充提取 usage - 支持 Claude/OpenAI/OpenAI Responses/Gemini 多种 usage 格式
This commit is contained in:
@@ -81,12 +81,16 @@ export function sortApiFormats(formats: string[]): string[] {
|
||||
|
||||
/**
|
||||
* 代理配置类型
|
||||
* 支持两种模式:
|
||||
* - 手动配置:设置 url/username/password
|
||||
* - 代理节点:设置 node_id(与 url 互斥)
|
||||
*/
|
||||
export interface ProxyConfig {
|
||||
url: string
|
||||
url?: string
|
||||
username?: string
|
||||
password?: string
|
||||
enabled?: boolean // 是否启用代理(false 时保留配置但不使用)
|
||||
node_id?: string // 代理节点 ID(aether-proxy 注册的节点,与 url 互斥)
|
||||
enabled?: boolean // 是否启用代理(false 时保留配置但不使用)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,11 @@ export interface ProxyNode {
|
||||
port: number
|
||||
region: string | null
|
||||
status: 'online' | 'unhealthy' | 'offline'
|
||||
is_manual: boolean
|
||||
// 手动节点专用字段
|
||||
proxy_url?: string
|
||||
proxy_username?: string
|
||||
proxy_password?: string // 脱敏后的密码
|
||||
registered_by: string | null
|
||||
last_heartbeat_at: string | null
|
||||
heartbeat_interval: number
|
||||
@@ -24,13 +29,40 @@ export interface ProxyNodeListResponse {
|
||||
limit: number
|
||||
}
|
||||
|
||||
export interface ManualProxyNodeCreateRequest {
|
||||
name: string
|
||||
proxy_url: string
|
||||
username?: string
|
||||
password?: string
|
||||
region?: string
|
||||
}
|
||||
|
||||
export interface ManualProxyNodeUpdateRequest {
|
||||
name?: string
|
||||
proxy_url?: string
|
||||
username?: string
|
||||
password?: string
|
||||
region?: string
|
||||
}
|
||||
|
||||
export const proxyNodesApi = {
|
||||
async listProxyNodes(params?: { status?: string; skip?: number; limit?: number }): Promise<ProxyNodeListResponse> {
|
||||
const response = await apiClient.get<ProxyNodeListResponse>('/api/admin/proxy-nodes', { params })
|
||||
return response.data
|
||||
},
|
||||
|
||||
async deleteProxyNode(nodeId: string): Promise<void> {
|
||||
await apiClient.delete(`/api/admin/proxy-nodes/${nodeId}`)
|
||||
async createManualNode(data: ManualProxyNodeCreateRequest): Promise<{ node_id: string; node: ProxyNode }> {
|
||||
const response = await apiClient.post<{ node_id: string; node: ProxyNode }>('/api/admin/proxy-nodes/manual', data)
|
||||
return response.data
|
||||
},
|
||||
|
||||
async updateManualNode(nodeId: string, data: ManualProxyNodeUpdateRequest): Promise<{ node_id: string; node: ProxyNode }> {
|
||||
const response = await apiClient.patch<{ node_id: string; node: ProxyNode }>(`/api/admin/proxy-nodes/${nodeId}`, data)
|
||||
return response.data
|
||||
},
|
||||
|
||||
async deleteProxyNode(nodeId: string): Promise<{ message: string; node_id: string; cleared_system_proxy: boolean }> {
|
||||
const response = await apiClient.delete<{ message: string; node_id: string; cleared_system_proxy: boolean }>(`/api/admin/proxy-nodes/${nodeId}`)
|
||||
return response.data
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user