909 行的单文件 api.ts 按域拆为 10 个模块 + 共享 client;barrel 保持 import from '../api' 不变,调用点零改动。 - api/client.ts:axios 实例 + 拦截器 + authToken + setOnUnauthorized (唯一住处)。 - 10 个域模块:auth / targets / scenarios / modelConfigs / runs / reports / stats / campaigns / intelligentEvals / files,每个 自包含类型声明与 API 方法。 - api/index.ts:barrel 再导出,调用点 import 路径全部不变。 - 原 api.ts 中的 Blob 导出仪式已在 Commit 4 下沉至 utils/download.ts,本 commit 仅做拆分与搬运。
292 lines
7.4 KiB
TypeScript
292 lines
7.4 KiB
TypeScript
import api from './client'
|
|
import { downloadBlob } from '../utils/download'
|
|
|
|
export interface CampaignPlanEntry {
|
|
scenario_id: string
|
|
offset_seconds: number
|
|
count: number
|
|
}
|
|
|
|
export interface ExplorationSeeds {
|
|
personas: string[]
|
|
goals: string[]
|
|
}
|
|
|
|
export interface ExplorationBudgetConfig {
|
|
max_sessions?: number | null
|
|
max_turns?: number | null
|
|
min_interval_seconds?: number | null
|
|
}
|
|
|
|
export interface ExplorationIssueCount {
|
|
issue: string
|
|
count: number
|
|
}
|
|
|
|
export interface ExplorationJudgeReview {
|
|
reviewed_sessions: number
|
|
findings: { dimension: string; rating: string; comment: string }[]
|
|
summaries: string[]
|
|
}
|
|
|
|
export interface ExplorationSummary {
|
|
session_count: number
|
|
sessions_with_experience: number
|
|
goal_achieved_count: number
|
|
goal_achievement_rate: number | null
|
|
issues: ExplorationIssueCount[]
|
|
misled: ExplorationIssueCount[]
|
|
judge_review: ExplorationJudgeReview | null
|
|
}
|
|
|
|
export interface ExplorationExperience {
|
|
goal_achieved: boolean
|
|
blockers: string[]
|
|
misled: string[]
|
|
emotion: string
|
|
notes: string
|
|
}
|
|
|
|
export interface ExplorationSession {
|
|
id: string
|
|
campaign_id: string
|
|
target_id: string
|
|
persona: Record<string, unknown>
|
|
goal: string
|
|
seed_ref: Record<string, unknown> | null
|
|
status: string
|
|
triggered_by: string
|
|
experience: ExplorationExperience | null
|
|
judge_review: Record<string, unknown> | null
|
|
turn_count: number
|
|
error: string | null
|
|
created_at: string | null
|
|
closed_at: string | null
|
|
}
|
|
|
|
export interface ExplorationMessage {
|
|
id: string
|
|
session_id: string
|
|
round_index: number
|
|
role: string
|
|
content: string
|
|
latency_ms: number | null
|
|
created_at: string | null
|
|
}
|
|
|
|
export const explorationApi = {
|
|
listSessions: (campaignId: string) =>
|
|
api.get<{ sessions: ExplorationSession[] }>(`/exploration/campaigns/${campaignId}/sessions`),
|
|
listMessages: (sessionId: string) =>
|
|
api.get<{ messages: ExplorationMessage[] }>(`/exploration/sessions/${sessionId}/messages`),
|
|
}
|
|
|
|
export interface CampaignProgress {
|
|
current_offset_seconds: number
|
|
spawned_runs: number
|
|
completed_runs: number
|
|
}
|
|
|
|
export interface CampaignListProgress {
|
|
completed_runs: number
|
|
planned_total: number
|
|
overall_pass_rate: number | null
|
|
}
|
|
|
|
export interface Campaign {
|
|
id: string
|
|
name: string
|
|
target_id: string
|
|
window_seconds: number
|
|
time_scale: number
|
|
plan: CampaignPlanEntry[]
|
|
status: string
|
|
started_at: string | null
|
|
completed_at: string | null
|
|
summary: Record<string, unknown> | null
|
|
analysis_model_config_id: string | null
|
|
exploration_seeds: ExplorationSeeds | null
|
|
exploration_budget: ExplorationBudgetConfig | null
|
|
progress?: CampaignProgress
|
|
}
|
|
|
|
export interface CampaignListItem extends Omit<Campaign, 'progress'> {
|
|
progress: CampaignListProgress
|
|
}
|
|
|
|
export interface CampaignTrendBucket {
|
|
bucket_index: number
|
|
start_seconds: number
|
|
end_seconds: number
|
|
run_count: number
|
|
pass_rate: number | null
|
|
availability: number | null
|
|
avg_latency_ms: number | null
|
|
}
|
|
|
|
export interface CampaignCapability {
|
|
scenario_id: string
|
|
scenario_name: string
|
|
run_count: number
|
|
pass_rate: number | null
|
|
availability: number | null
|
|
avg_latency_ms: number | null
|
|
}
|
|
|
|
export interface CampaignReport {
|
|
campaign_id: string
|
|
name: string
|
|
target_id: string
|
|
status: string
|
|
window_seconds: number
|
|
time_scale: number
|
|
started_at: string | null
|
|
completed_at: string | null
|
|
summary: {
|
|
total_runs: number
|
|
completed_runs: number
|
|
overall_pass_rate: number | null
|
|
overall_availability: number | null
|
|
avg_latency_ms: number | null
|
|
}
|
|
time_trend: CampaignTrendBucket[]
|
|
capability_summary: CampaignCapability[]
|
|
exploration?: ExplorationSummary | null
|
|
}
|
|
|
|
export interface CampaignTimelineEntry {
|
|
run_id: string
|
|
scenario_id: string
|
|
scenario_name: string
|
|
offset_seconds: number
|
|
status: string
|
|
pass_rate: number | null
|
|
avg_latency_ms: number | null
|
|
started_at: string | null
|
|
}
|
|
|
|
export type CampaignAnalysisStatus = 'none' | 'queued' | 'generating' | 'completed' | 'failed'
|
|
|
|
export interface CampaignAnalysisProblem {
|
|
severity: string
|
|
title: string
|
|
description: string
|
|
scenario_ids: string[]
|
|
evidence_run_ids: string[]
|
|
}
|
|
|
|
export interface CampaignAnalysisResult {
|
|
overall: string
|
|
problems: CampaignAnalysisProblem[]
|
|
scenario_narratives: { scenario_id: string; narrative: string }[]
|
|
suggestions: { priority: number; text: string }[]
|
|
}
|
|
|
|
export interface CampaignAnalysis {
|
|
status: CampaignAnalysisStatus
|
|
result?: CampaignAnalysisResult | null
|
|
error?: string | null
|
|
model_config_id?: string | null
|
|
triggered_by?: string
|
|
updated_at?: string | null
|
|
}
|
|
|
|
export interface CreateCampaignPayload {
|
|
name: string
|
|
target_id: string
|
|
window_seconds: number
|
|
time_scale: number
|
|
plan: CampaignPlanEntry[]
|
|
analysis_model_config_id?: string | null
|
|
exploration_seeds?: ExplorationSeeds | null
|
|
exploration_budget?: ExplorationBudgetConfig | null
|
|
}
|
|
|
|
export type ComparisonTrend = 'improving' | 'stable' | 'regressing'
|
|
|
|
export interface MetricDeltaPair {
|
|
baseline: number | null
|
|
current: number | null
|
|
delta: number | null
|
|
}
|
|
|
|
export interface MetricDiffScenario {
|
|
scenario_id: string
|
|
scenario_name: string
|
|
pass_rate: MetricDeltaPair
|
|
availability: MetricDeltaPair
|
|
avg_latency_ms: MetricDeltaPair
|
|
}
|
|
|
|
export interface MetricDiff {
|
|
overall: {
|
|
pass_rate: MetricDeltaPair
|
|
availability: MetricDeltaPair
|
|
avg_latency_ms: MetricDeltaPair
|
|
}
|
|
scenarios: MetricDiffScenario[]
|
|
}
|
|
|
|
export interface ComparisonBaselineInfo {
|
|
id: string
|
|
name: string
|
|
completed_at: string | null
|
|
}
|
|
|
|
export interface ComparisonProblemEvolution {
|
|
status: string
|
|
title: string
|
|
detail: string
|
|
scenario_ids: string[]
|
|
}
|
|
|
|
export interface ComparisonSuggestionTracking {
|
|
text: string
|
|
status: string
|
|
note: string
|
|
}
|
|
|
|
export interface ComparisonResult {
|
|
trend: ComparisonTrend
|
|
summary: string
|
|
problem_evolution: ComparisonProblemEvolution[]
|
|
suggestion_tracking: ComparisonSuggestionTracking[]
|
|
}
|
|
|
|
export interface CampaignComparison {
|
|
status: CampaignAnalysisStatus
|
|
auto_baseline: ComparisonBaselineInfo | null
|
|
metric_diff: MetricDiff | null
|
|
comparison: {
|
|
baseline_campaign_id: string
|
|
baseline: ComparisonBaselineInfo | null
|
|
result: ComparisonResult | null
|
|
error: string | null
|
|
model_config_id: string | null
|
|
triggered_by: string
|
|
updated_at: string | null
|
|
} | null
|
|
}
|
|
|
|
export const campaignsApi = {
|
|
list: () => api.get<CampaignListItem[]>('/campaigns'),
|
|
get: (id: string) => api.get<Campaign>(`/campaigns/${id}`),
|
|
create: (data: CreateCampaignPayload) => api.post<Campaign>('/campaigns', data),
|
|
cancel: (id: string) => api.post<Campaign>(`/campaigns/${id}/cancel`),
|
|
report: (id: string) => api.get<CampaignReport>(`/campaigns/${id}/report`),
|
|
timeline: (id: string) =>
|
|
api.get<{ entries: CampaignTimelineEntry[] }>(`/campaigns/${id}/timeline`),
|
|
getAnalysis: (id: string) => api.get<CampaignAnalysis>(`/campaigns/${id}/analysis`),
|
|
generateAnalysis: (id: string) => api.post<{ status: string }>(`/campaigns/${id}/analysis`),
|
|
getComparison: (id: string) => api.get<CampaignComparison>(`/campaigns/${id}/comparison`),
|
|
generateComparison: (id: string, baselineCampaignId?: string) =>
|
|
api.post<{ status: string }>(
|
|
`/campaigns/${id}/comparison`,
|
|
baselineCampaignId ? { baseline_campaign_id: baselineCampaignId } : {},
|
|
),
|
|
downloadReport: async (id: string) => {
|
|
const res = await api.get(`/campaigns/${id}/report/markdown`, { responseType: 'blob' })
|
|
downloadBlob(res.data as Blob, `campaign-report-${id.slice(0, 8)}.md`)
|
|
},
|
|
}
|