全命名空间 6h/24h 聚合数据量过大会拖垮 Loki:前端时间范围旁新增应用范围选择器 (labelValues 候选),>1h 未选应用禁用开始分析并提示;后端同样强制 400(闸门在服务端); 信号采集选择器按 app 收窄后 histogram/stats 从全量变为单应用流,秒级返回。
95 lines
2.5 KiB
TypeScript
95 lines
2.5 KiB
TypeScript
import { http } from '@/api/http'
|
|
|
|
export interface AIConfig {
|
|
enabled: boolean
|
|
provider: string
|
|
baseUrl: string
|
|
/** 后端永远返回掩码(sk-***abcd),保存时留空表示不修改 */
|
|
apiKey: string
|
|
model: string
|
|
temperature: number
|
|
maxTokens: number
|
|
timeoutSec: number
|
|
dailyTokenCap: number
|
|
maxScanBytes: number
|
|
redactExtra: string[]
|
|
}
|
|
|
|
export interface AIConfigResponse {
|
|
config: AIConfig
|
|
tokenUsedToday: number
|
|
}
|
|
|
|
export interface AIFinding {
|
|
title: string
|
|
evidence: string
|
|
severity: 'high' | 'medium' | 'low' | string
|
|
}
|
|
|
|
export interface AIAnalysisResult {
|
|
summary: string
|
|
findings: AIFinding[]
|
|
actions: string[]
|
|
unknowns: string[]
|
|
parseError?: string
|
|
}
|
|
|
|
export interface AISignalBundle {
|
|
sourceId: number
|
|
sourceName: string
|
|
selector: string
|
|
from: string
|
|
to: string
|
|
rangeMinutes: number
|
|
totalBytes: number
|
|
totalEntries: number
|
|
entriesExact: boolean
|
|
apps: Array<{ app: string; namespace: string; entries: number; bytes: number; share: string }>
|
|
alerts: Array<{ ruleName: string; status: string; count: number; createdAt: string }>
|
|
baseline?: { previousBytes: number; currentBytes: number; deltaPercent: number; comparisonNote: string }
|
|
snapshotHours: number
|
|
warnings: string[]
|
|
}
|
|
|
|
export interface AIRun {
|
|
id: number
|
|
userId: number
|
|
username: string
|
|
sourceId: number
|
|
sourceName: string
|
|
rangeMinutes: number
|
|
model: string
|
|
question: string
|
|
status: string
|
|
error: string
|
|
conclusion: string
|
|
promptPayload: string
|
|
promptTokens: number
|
|
completionTokens: number
|
|
scanBytes: number
|
|
durationMs: number
|
|
createdAt: string
|
|
}
|
|
|
|
export interface AIAnalyzeResponse {
|
|
result: AIAnalysisResult
|
|
signals: AISignalBundle
|
|
prompt: string
|
|
run: AIRun
|
|
warnings: string[]
|
|
}
|
|
|
|
export const aiApi = {
|
|
getConfig: () => http.get<AIConfigResponse>('/ai/config'),
|
|
saveConfig: (data: Partial<AIConfig>) => http.put<{ config: AIConfig }>('/ai/config', data),
|
|
testConfig: (data: { baseUrl?: string; model?: string; apiKey?: string }) =>
|
|
http.post<{ reply: string; model: string }>('/ai/config/test', data, { timeout: 45000 }),
|
|
analyze: (data: { sourceId: number; start: number; end: number; question?: string; app?: string }) =>
|
|
http.post<AIAnalyzeResponse>('/ai/analyze', data, { timeout: 180000 }),
|
|
runs: (page: number, pageSize: number) =>
|
|
http.get<{ list: AIRun[]; total: number; page: number; pageSize: number }>(
|
|
`/ai/runs?page=${page}&pageSize=${pageSize}`,
|
|
),
|
|
run: (id: number) => http.get<AIRun>(`/ai/runs/${id}`),
|
|
}
|