Skip to content

分析 API

代码分析任务管理相关的 API 端点。

端点概览

方法端点描述认证
POST/analysis创建分析任务
GET/analysis分析列表
GET/projects/{id}/analysis项目分析列表
GET/analysis/{id}分析详情
POST/analysis/{id}/rerun重新运行分析
DELETE/analysis/{id}取消分析
GET/analysis/{id}/findings分析发现列表
GET/analysis/{id}/requestsLLM 请求列表
GET/analysis/{id}/tool-calls工具调用列表

创建分析

POST /api/v1/analysis

创建新的代码分析任务。

请求

http
POST /api/v1/analysis
Authorization: Bearer <token>
Content-Type: application/json

{
  "repository_id": "550e8400-e29b-41d4-a716-446655440000",
  "task_type": "security_review",
  "trigger_type": "manual",
  "repository_ref": "main",
  "requested_by": "User Name",
  "title": "Security review for main branch"
}

参数说明:

字段类型必填说明
repository_idstring仓库 ID
task_typestring任务类型
trigger_typestring触发类型
repository_refstringGit 引用(分支/标签)
requested_bystring请求人名称
pull_request_numberintegerPR 编号
commit_shastringCommit SHA
base_shastring基准 SHA(PR)
head_shastringHEAD SHA(PR)
titlestring任务标题

任务类型 (task_type):

  • security_review - 安全审查
  • code_review - 代码审查
  • full_analysis - 全面分析

触发类型 (trigger_type):

  • manual - 手动触发
  • push - 代码推送
  • pull_request - PR 触发
  • rerun - 重新运行
  • webhook - Webhook 触发

响应

成功 (201 Created):

json
{
  "analysis_id": "660e8400-e29b-41d4-a716-446655440000",
  "repository_id": "550e8400-e29b-41d4-a716-446655440000",
  "task_type": "security_review",
  "trigger_type": "manual",
  "status": "submitted",
  "repository_provider": "github",
  "repository_url": "https://github.com/owner/repo",
  "repository_ref": "main",
  "requested_by": "User Name",
  "requested_by_user_id": "450e8400-e29b-41d4-a716-446655440000",
  "title": "Security review for main branch",
  "created_at": "2024-01-01T12:00:00Z",
  "updated_at": "2024-01-01T12:00:00Z"
}

错误响应:

  • 400 Bad Request: 参数验证失败
  • 404 Not Found: 仓库不存在

示例

typescript
const createAnalysis = async (
  repositoryId: string,
  taskType: 'security_review' | 'code_review' | 'full_analysis'
) => {
  const response = await fetch('/api/v1/analysis', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      repository_id: repositoryId,
      task_type: taskType,
      trigger_type: 'manual',
      repository_ref: 'main',
      requested_by: 'Current User',
    }),
  });
  
  return response.json();
};

分析列表

GET /api/v1/analysis

获取当前用户的所有分析任务。

请求

http
GET /api/v1/analysis?status=running&limit=20&offset=0
Authorization: Bearer <token>

查询参数:

参数类型默认值说明
limitinteger20每页数量
offsetinteger0偏移量
statusstring-状态过滤

状态值:

  • submitted - 已提交
  • pending - 待处理
  • running - 运行中
  • completed - 已完成
  • failed - 失败
  • cancelled - 已取消

响应

成功 (200 OK):

json
{
  "analyses": [
    {
      "analysis_id": "660e8400-e29b-41d4-a716-446655440000",
      "repository_id": "550e8400-e29b-41d4-a716-446655440000",
      "task_type": "security_review",
      "trigger_type": "manual",
      "status": "running",
      "repository_provider": "github",
      "repository_url": "https://github.com/owner/repo",
      "repository_ref": "main",
      "requested_by": "User Name",
      "title": "Security review",
      "started_at": "2024-01-01T12:01:00Z",
      "created_at": "2024-01-01T12:00:00Z",
      "updated_at": "2024-01-01T12:01:00Z"
    }
  ],
  "total": 1
}

GET /api/v1/projects/{id}/analysis

获取特定项目的分析任务。

请求

http
GET /api/v1/projects/550e8400-e29b-41d4-a716-446655440000/analysis?limit=20
Authorization: Bearer <token>

响应格式与全局分析列表相同。


分析详情

GET /api/v1/analysis/{id}

获取分析任务的详细信息。

请求

http
GET /api/v1/analysis/660e8400-e29b-41d4-a716-446655440000
Authorization: Bearer <token>

响应

成功 (200 OK):

json
{
  "analysis_id": "660e8400-e29b-41d4-a716-446655440000",
  "repository_id": "550e8400-e29b-41d4-a716-446655440000",
  "task_type": "security_review",
  "trigger_type": "manual",
  "status": "completed",
  "repository_provider": "github",
  "repository_url": "https://github.com/owner/repo",
  "repository_ref": "main",
  "requested_by": "User Name",
  "requested_by_user_id": "450e8400-e29b-41d4-a716-446655440000",
  "title": "Security review",
  "started_at": "2024-01-01T12:01:00Z",
  "completed_at": "2024-01-01T12:15:00Z",
  "created_at": "2024-01-01T12:00:00Z",
  "updated_at": "2024-01-01T12:15:00Z"
}

错误响应:

  • 404 Not Found: 分析不存在或无权访问

重新运行分析

POST /api/v1/analysis/{id}/rerun

重新运行已完成或失败的分析。

请求

http
POST /api/v1/analysis/660e8400-e29b-41d4-a716-446655440000/rerun
Authorization: Bearer <token>

响应

成功 (201 Created):

返回新创建的分析任务,字段与创建分析相同。

错误响应:

  • 404 Not Found: 原分析不存在
  • 400 Bad Request: 分析状态不允许重新运行

示例

typescript
const rerunAnalysis = async (analysisId: string) => {
  const response = await fetch(`/api/v1/analysis/${analysisId}/rerun`, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${token}` },
  });
  
  return response.json();
};

取消分析

DELETE /api/v1/analysis/{id}

取消正在运行的分析任务。

请求

http
DELETE /api/v1/analysis/660e8400-e29b-41d4-a716-446655440000
Authorization: Bearer <token>

响应

成功 (204 No Content):

无响应体。

错误响应:

  • 404 Not Found: 分析不存在
  • 400 Bad Request: 分析已完成,无法取消

分析发现

GET /api/v1/analysis/{id}/findings

获取分析任务发现的问题列表。

请求

http
GET /api/v1/analysis/660e8400-e29b-41d4-a716-446655440000/findings?limit=50
Authorization: Bearer <token>

查询参数:

参数类型默认值说明
limitinteger50每页数量
offsetinteger0偏移量

响应

成功 (200 OK):

json
{
  "findings": [
    {
      "session_id": "770e8400-e29b-41d4-a716-446655440000",
      "severity": "high",
      "title": "SQL Injection vulnerability",
      "file_path": "src/database.rs",
      "line_start": 42,
      "line_end": 45,
      "body": "Detailed description of the issue...",
      "suggested_fix": "Use parameterized queries instead...",
      "reported_at": "2024-01-01T12:10:00Z"
    }
  ],
  "total": 1
}

严重程度 (severity):

  • critical - 严重
  • high - 高
  • medium - 中
  • low - 低
  • info - 信息

LLM 请求记录

GET /api/v1/analysis/{id}/requests

获取分析过程中的 LLM API 请求记录。

请求

http
GET /api/v1/analysis/660e8400-e29b-41d4-a716-446655440000/requests?limit=100
Authorization: Bearer <token>

响应

成功 (200 OK):

json
{
  "requests": [
    {
      "request_id": "880e8400-e29b-41d4-a716-446655440000",
      "session_id": "770e8400-e29b-41d4-a716-446655440000",
      "analysis_id": "660e8400-e29b-41d4-a716-446655440000",
      "model": "claude-opus-4",
      "input_tokens": 1500,
      "output_tokens": 800,
      "total_tokens": 2300,
      "cached_input_tokens": 500,
      "created_at": "2024-01-01T12:05:00Z"
    }
  ],
  "total": 1
}

用途:

  • Token 使用统计
  • 成本计算
  • 性能分析

工具调用记录

GET /api/v1/analysis/{id}/tool-calls

获取 Agent 执行的工具调用记录。

请求

http
GET /api/v1/analysis/660e8400-e29b-41d4-a716-446655440000/tool-calls?limit=100
Authorization: Bearer <token>

响应

成功 (200 OK):

json
{
  "tool_calls": [
    {
      "tool_call_id": "990e8400-e29b-41d4-a716-446655440000",
      "request_id": "880e8400-e29b-41d4-a716-446655440000",
      "session_id": "770e8400-e29b-41d4-a716-446655440000",
      "analysis_id": "660e8400-e29b-41d4-a716-446655440000",
      "tool_name": "read_file",
      "tool_input": { "path": "src/main.rs" },
      "tool_output": { "content": "..." },
      "status": "completed",
      "created_at": "2024-01-01T12:05:00Z",
      "completed_at": "2024-01-01T12:05:01Z"
    }
  ],
  "total": 1
}

工具状态:

  • pending - 待执行
  • running - 执行中
  • completed - 已完成
  • failed - 失败

状态流转

submitted → pending → running → completed
                            ↘ failed
                            ↘ cancelled

状态说明:

  • submitted: 任务已提交,等待入队
  • pending: 已入队,等待 Agent 执行
  • running: Agent 正在执行
  • completed: 执行完成
  • failed: 执行失败
  • cancelled: 用户取消

实时更新

使用 SSE 获取分析状态实时更新:

typescript
const connectSSE = (analysisId: string) => {
  const token = localStorage.getItem('token');
  const url = `/api/v1/sse/analysis/${analysisId}?token=${token}`;
  
  const eventSource = new EventSource(url);
  
  eventSource.onmessage = (event) => {
    const data = JSON.parse(event.data);
    console.log('Analysis update:', data);
    
    // 根据事件类型处理
    if (data.type === 'status_changed') {
      updateStatus(data.status);
    }
  };
  
  return eventSource;
};

详见 SSE API


最佳实践

1. 轮询状态

typescript
const waitForCompletion = async (analysisId: string) => {
  const interval = 5000; // 5秒
  
  while (true) {
    const analysis = await getAnalysis(analysisId);
    
    if (['completed', 'failed', 'cancelled'].includes(analysis.status)) {
      return analysis;
    }
    
    await new Promise(resolve => setTimeout(resolve, interval));
  }
};

2. 错误重试

typescript
const createAnalysisWithRetry = async (data, maxRetries = 3) => {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await createAnalysis(data);
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
    }
  }
};

3. Token 统计

typescript
const calculateCost = (requests: Request[]) => {
  const totalInputTokens = requests.reduce((sum, r) => sum + r.input_tokens, 0);
  const totalOutputTokens = requests.reduce((sum, r) => sum + r.output_tokens, 0);
  const cachedTokens = requests.reduce((sum, r) => sum + (r.cached_input_tokens || 0), 0);
  
  return {
    inputTokens: totalInputTokens,
    outputTokens: totalOutputTokens,
    cachedTokens,
    effectiveInputTokens: totalInputTokens - cachedTokens,
  };
};

相关文档

Released under the MIT License.