# 通风数据解读 API 接口文档

> **服务器地址**: http://39.97.59.228:8070
>
> **文档版本**: v2.0
> 
> **最后更新**: 2026-08-05

---

## 目录

- [接口概览](#接口概览)
- [认证机制](#认证机制)
- [SSE 流式响应格式](#sse-流式响应格式)
- [点选巷道解读接口](#点选巷道解读接口)
- [点选设备解读接口](#点选设备解读接口)
- [对话式解读接口](#对话式解读接口)
- [对话恢复接口（人工审批）](#对话恢复接口人工审批)
- [配风计划审查接口（PDF 上传）](#配风计划审查接口pdf-上传)
- [聊天历史查询接口](#聊天历史查询接口)
- [会话列表接口](#会话列表接口)
- [删除会话接口](#删除会话接口)
- [会话权限模式管理](#会话权限模式管理)
- [会话置顶](#会话置顶)
- [会话标题编辑](#会话标题编辑)
- [上下文用量查询](#上下文用量查询)
- [模型管理接口](#模型管理接口)
- [技能管理接口](#技能管理接口)
- [工具清单](#工具清单)
- [前端接入示例](#前端接入示例)
- [错误处理](#错误处理)

---

## 接口概览

| 方法 | 路径 | 描述 | 类型 | 认证 |
|------|------|------|------|------|
| POST | `/api/interpret/click/tun` | 点选/悬浮巷道数据解读 | SSE 流式 | — |
| POST | `/api/interpret/click/device` | 点选/悬浮设备数据解读 | SSE 流式 | — |
| POST | `/api/chat` | 对话式数据解读 / 需风量计算 / PDF 审查 | SSE 流式 | ✓ |
| POST | `/api/chat/resume` | 恢复中断的对话（人工审批） | SSE 流式 | ✓ |
| POST | `/api/vent/review/pdf` | 配风计划审查（PDF 上传） | SSE 流式 | — |
| GET | `/api/chat/history/{session_id}` | 查询聊天历史 | 常规 | ✓ |
| GET | `/api/sessions` | 查询会话列表 | 常规 | ✓ |
| DELETE | `/api/sessions/{session_id}` | 删除会话 | 常规 | ✓ |
| GET | `/api/sessions/{session_id}/mode` | 获取会话权限模式 | 常规 | ✓ |
| PUT | `/api/sessions/{session_id}/mode` | 设置会话权限模式 | 常规 | ✓ |
| PUT | `/api/sessions/{session_id}/pin` | 切换会话置顶状态 | 常规 | ✓ |
| PUT | `/api/sessions/{session_id}/title` | 编辑会话标题 | 常规 | ✓ |
| GET | `/api/sessions/{session_id}/context` | 查询会话上下文用量 | 常规 | ✓ |
| GET | `/api/model` | 获取当前模型信息 | 常规 | — |
| POST | `/api/model/switch` | 切换运行时模型 | 常规 | — |
| POST | `/api/model/thinking` | 切换思考级别 | 常规 | — |
| GET | `/api/skills` | 获取技能列表 | 常规 | — |
| GET | `/api/skills/{name}` | 查看技能详情 | 常规 | — |
| POST | `/api/skills/{name}/toggle` | 启用/禁用技能 | 常规 | — |
| POST | `/api/skills/upload` | 上传新技能包 | 常规 | — |

---

## 认证机制

> **新增于 v2.0**

所有标注 "✓ 认证" 的接口需要在请求头中携带登录令牌。

### 请求头

```
x-access-token: <your_token>
```

### 认证流程

1. 客户端在请求头中传递 `x-access-token`
2. 服务端将令牌转发到通风系统 `GET /sys/user/getUserInfo` 进行验证
3. 验证通过后，请求继续处理；验证失败返回 401

### 认证错误码

| HTTP 状态码 | 含义 |
|-------------|------|
| 401 | 缺少令牌、令牌无效或已过期 |
| 502 | 认证服务连接失败 |
| 504 | 认证服务响应超时 |
| 500 | 认证服务地址未配置 |

> **注意**：点选解读接口（`/api/interpret/click/*`）和配风计划审查接口（`/api/vent/review/pdf`）暂不要求认证。模型管理和技能管理接口也不要求认证。

---

## SSE 流式响应格式

所有流式接口均采用 Server-Sent Events (SSE) 协议，返回 `text/event-stream` 类型。

### 通用响应头

```
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
X-Session-Id: {session_id}
```

### 事件类型 (type 字段)

流式返回数据以 `data:` 开头，JSON 格式，核心字段定义如下：

| type | 描述 | 核心字段 |
|------|------|----------|
| `agent_start` | 智能体开始处理（对话 Agent 启动时发送） | `agent`, `cn_agent`, `message` |
| `thinking` | AI 正在思考/推理 | `source`, `node`, `message` |
| `executing` | AI 正在执行工具调用 | `source`, `tools`, `message` |
| `tool_call` | 检测到工具调用 | `source`, `tool`, `message` |
| `tool_result` | 工具执行结果返回 | `source`, `tool`, `message` |
| `updated_todo_list` | Todo 列表更新 | `source`, `todos`, `message` |
| `token` | AI 生成的文本内容 | `source`, `content` |
| `reasoning` | 推理模型思考过程（如 DeepSeek-R1 的 reasoning_content） | `source`, `content` |
| `agent_done` | 智能体处理完成 | `agent`, `cn_agent`, `duration_ms`, `message` |
| `interrupt` | 智能体暂停等待人工审批（计划模式） | `node`, `message`, `interrupts`, `plan`（可选） |
| `done` | 流式响应结束 | `thread_id`, `session_id`, `message` |
| `generating` | Fast 模式：LLM 开始生成报告 | `source` |
| `progress` | Fast 模式 / PDF 审查：进度更新 | `message` |
| `error` | 发生错误 | `message` |

> **`message` 字段**（v1.3+）：所有事件均包含中文 `message` 字段，描述当前正在执行的操作，如 "正在分析您的问题..."、"查询巷道监测数据 完成"。前端可据此展示进度提示。

### 配风计划审查专属事件

配风计划 PDF 审查接口还会产生以下额外事件类型：

| type | 描述 | 核心字段 |
|------|------|----------|
| `progress` | 审查进度更新 | `message`, `agent`, `hash_id`, `download_url` |
| `agent_start` | 子智能体开始审查 | `agent`, `message` |
| `agent_thinking` | 子智能体正在分析 | `agent`, `message` |
| `agent_executing` | 子智能体执行工具 | `agent`, `message`, `tools` |
| `agent_todos` | 子智能体任务进度更新 | `agent`, `message`, `todos` |
| `agent_tool_result` | 子智能体工具执行完成 | `agent`, `message`, `tool` |
| `agent_done` | 子智能体审查完成 | `agent`, `message`, `preview`, `progress` |
| `agent_error` | 子智能体审查出错 | `agent`, `message`, `error` |
| `generating` | LLM 正在生成报告 | `source` |

### source 字段说明

| 值 | 含义 |
|----|------|
| `main` | 主代理（当前对话） |
| `subagent` | 子代理（被调用的工具代理） |
| `fast` | Fast 模式直连（跳过 Agent） |

---

## 点选巷道解读接口

**POST** `/api/interpret/click/tun`

> **认证**：不需要

### 解读模式

接口支持两种模式，通过 `mode` 参数控制：

| 模式 | 值 | 行为 | 适用场景 |
|------|------|------|----------|
| **Plan**（默认） | `"plan"` | 走完整智能体流程：加载技能 → 调用工具 → 逐项比对规程 → 生成结构化报告 | 需要深度分析、规程溯源 |
| **Fast** | `"fast"` | 跳过智能体和技能，直接查询数据后发给 LLM 按模板生成报告 | 快速预览、延迟敏感场景 |

> **区别**：Plan 模式会调用多个工具逐项核查（知识库检索、规程比对等），输出更严谨完整；Fast 模式仅一次数据查询 + 一次 LLM 调用，响应更快但分析深度较浅。
>
> **数据库**：点选解读接口**不写数据库**，不创建会话、不保存消息记录。

### 请求示例

**Plan 模式（默认）：**
```json
{
  "tun_id": "15216",
  "tun_name": "15216 辅运起坡段"
}
```

**Fast 模式：**
```json
{
  "tun_id": "15216",
  "tun_name": "15216 辅运起坡段",
  "mode": "fast"
}
```

### 请求参数

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `tun_id` | string | 是 | 巷道 ID |
| `tun_name` | string | 是 | 巷道名称 |
| `mode` | string | 否 | 解读模式：`"plan"`（智能体全流程，默认）或 `"fast"`（直接生成报告） |

### 响应示例

**Plan 模式（智能体全流程）**：
```
data: {"type": "thinking", "source": "main", "node": "model"}

data: {"type": "executing", "source": "main", "tools": ["query_knowledge_base"]}

data: {"type": "tool_call", "source": "main", "tool": "query_knowledge_base"}

data: {"type": "tool_result", "source": "main", "tool": "query_knowledge_base"}

data: {"type": "token", "source": "main", "content": "根据监测数据，该巷道当前风速为"}

data: {"type": "done", "thread_id": "xxx", "session_id": "xxx"}
```

**Fast 模式（直连 LLM）**：
```
data: {"type": "thinking", "source": "fast", "node": "fetching_data"}

data: {"type": "executing", "source": "fast", "tools": ["query_tun_data_by_id"]}

data: {"type": "generating", "source": "fast"}

data: {"type": "token", "source": "fast", "content": "**15216 辅运起坡段**\n- 当前风速："}

data: {"type": "done", "thread_id": "xxx", "session_id": "xxx"}
```

> Fast 模式下 `source` 为 `"fast"`，不会出现 `tool_call`/`tool_result`/`updated_todo_list` 等 Agent 独有事件；LLM 生成阶段可能出现 `progress`（心跳）和 `reasoning`（推理过程）事件。

---

## 点选设备解读接口

**POST** `/api/interpret/click/device`

> **认证**：不需要

### 解读模式

与巷道解读接口相同，支持 `mode` 参数：

| 模式 | 值 | 行为 |
|------|------|------|
| **Plan**（默认） | `"plan"` | 走完整智能体流程：加载技能 → 调用工具 → 逐项比对 → 生成报告 |
| **Fast** | `"fast"` | 跳过智能体，直接查数据 + LLM 生成报告 |

> 点选设备解读同样**不写数据库**。

### 请求示例

**Plan 模式（默认）：**
```json
{
  "device_id": "FAN-001",
  "device_name": "主通风机",
  "device_type": "fan"
}
```

**Fast 模式：**
```json
{
  "device_id": "FAN-001",
  "device_name": "主通风机",
  "device_type": "fan",
  "mode": "fast"
}
```

### 请求参数

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `device_id` | string | 是 | 设备 ID |
| `device_name` | string | 是 | 设备名称 |
| `device_type` | string | 是 | 设备类型 |
| `mode` | string | 否 | 解读模式：`"plan"`（默认）或 `"fast"` |

### 响应格式

与巷道解读接口相同，返回该设备的数据解读报告。

---

## 对话式解读接口

**POST** `/api/chat`

> **认证**：需要 `x-access-token` 请求头
>
> **Content-Type**：`multipart/form-data`

### 功能说明

统一对话入口，根据用户意图自动路由到不同智能体：
- **配风计划审查**（上传 PDF）→ 审查管线（form-reviewer + data-checker + calc-verifier）
- **数据解读 / 需风量计算 / 其他** → 通风对话助手

支持两种权限模式：
- **plan**（计划模式）：Agent 先制定执行计划，提交人工审批后再执行
- **full**（完全访问）：Agent 自动执行，无需审批

> **注意**：接口已从 `application/json` 改为 `multipart/form-data`，以支持文件上传。

### 请求参数（multipart/form-data）

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `message` | string | 是 | 用户消息（自然语言） |
| `session_id` | string | 否 | 会话 ID，新会话可不传 |
| `thread_id` | string | 否 | LangGraph 线程 ID，用于恢复多轮对话状态 |
| `mode` | string | 否 | 权限模式：`"plan"`（计划审批）或 `"full"`（完全访问）。仅新建会话时生效 |
| `file` | file | 否 | 附件（PDF / 文档等），用于配风计划审查等场景 |

### 请求示例（curl）

```bash
curl -X POST http://39.97.59.228:8070/api/chat \
  -H "x-access-token: YOUR_TOKEN" \
  -F "message=15216 辅运起坡段当前风速风量情况如何？" \
  -F "session_id=optional-session-id" \
  -F "mode=full"
```

带文件上传：
```bash
curl -X POST http://39.97.59.228:8070/api/chat \
  -H "x-access-token: YOUR_TOKEN" \
  -F "message=帮我审查这份配风计划" \
  -F "file=@/path/to/plan.pdf" \
  -F "mode=plan"
```

### 智能体开场事件（新增）

对话 Agent 启动时会先发送 `agent_start` 事件：

```json
{
  "type": "agent_start",
  "agent": "通风对话助手",
  "cn_agent": "通风对话助手",
  "message": "「通风对话助手」开始处理..."
}
```

对应完成时有 `agent_done` 事件：

```json
{
  "type": "agent_done",
  "agent": "通风对话助手",
  "cn_agent": "通风对话助手",
  "duration_ms": 4523,
  "message": "「通风对话助手」完成（4523ms）"
}
```

### 中断事件（计划模式）

当权限模式为 `plan` 时，Agent 调用 `request_plan_approval` 工具后会暂停，发送 `interrupt` 事件：

```json
{
  "type": "interrupt",
  "node": "tools",
  "message": "智能体已制定执行计划，等待您的审批...",
  "interrupts": ["..."]
}
```

此时流式响应**不会**发送 `done` 事件，前端应展示审批 UI。用户批准/拒绝后，调用 `/api/chat/resume` 接口继续。

### reasoning 事件（推理模型）

当使用 DeepSeek-R1 等推理模型时，模型的思考过程通过 `reasoning` 事件输出：

```json
{
  "type": "reasoning",
  "source": "main",
  "content": "用户询问15216巷道风速，我需要先查询监测数据..."
}
```

### 流式响应详解

#### thinking 事件

```json
{
  "type": "thinking",
  "source": "main",
  "node": "model"
}
```

| 字段 | 描述 |
|------|------|
| `type` | 固定为 `thinking` |
| `source` | 事件来源：`main` 或 `subagent` |
| `node` | 当前执行节点名称 |

#### executing 事件

```json
{
  "type": "executing",
  "source": "main",
  "tools": ["write_todos", "query_knowledge_base"]
}
```

| 字段 | 描述 |
|------|------|
| `type` | 固定为 `executing` |
| `source` | 事件来源 |
| `tools` | 即将执行的工具名称列表 |

#### tool_call 事件

```json
{
  "type": "tool_call",
  "source": "main",
  "tool": "query_knowledge_base"
}
```

| 字段 | 描述 |
|------|------|
| `type` | 固定为 `tool_call` |
| `source` | 事件来源 |
| `tool` | 被调用的工具名称 |

#### tool_result 事件

```json
{
  "type": "tool_result",
  "source": "main",
  "tool": "query_knowledge_base"
}
```

| 字段 | 描述 |
|------|------|
| `type` | 固定为 `tool_result` |
| `source` | 事件来源 |
| `tool` | 执行完成的工具名称 |

#### updated_todo_list 事件

```json
{
  "type": "updated_todo_list",
  "source": "main",
  "todos": [
    {"content": "查询巷道监测数据", "status": "in_progress"},
    {"content": "分析风速风量异常", "status": "pending"}
  ]
}
```

| 字段 | 描述 |
|------|------|
| `type` | 固定为 `updated_todo_list` |
| `source` | 事件来源 |
| `todos` | Todo 列表数组 |

#### token 事件

```json
{
  "type": "token",
  "source": "main",
  "content": "根据监测数据，"
}
```

| 字段 | 描述 |
|------|------|
| `type` | 固定为 `token` |
| `source` | 事件来源 |
| `content` | AI 生成的文本片段（逐步累积） |

#### done 事件

```json
{
  "type": "done",
  "thread_id": "a1b2c3d4-...",
  "session_id": "e5f6g7h8-..."
}
```

| 字段 | 描述 |
|------|------|
| `type` | 固定为 `done` |
| `thread_id` | LangGraph 线程 ID |
| `session_id` | 会话 ID |

#### error 事件

```json
{
  "type": "error",
  "message": "查询超时，请重试"
}
```

| 字段 | 描述 |
|------|------|
| `type` | 固定为 `error` |
| `message` | 错误信息描述 |

---

## 对话恢复接口（人工审批）

**POST** `/api/chat/resume`

> **认证**：需要 `x-access-token` 请求头

### 功能说明

恢复被中断的 LangGraph 对话。当计划模式（plan）下 Agent 调用 `request_plan_approval` 工具后暂停，用户批准或拒绝后通过此接口继续执行。

### 请求参数（JSON）

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `session_id` | string | 是 | 会话 ID |
| `thread_id` | string | 否 | LangGraph 线程 ID（不传则使用 session_id） |
| `action` | string | 是 | `"approve"`（批准继续执行）或 `"reject"`（拒绝） |

### 请求示例

```json
{
  "session_id": "e5f6g7h8-...",
  "thread_id": "a1b2c3d4-...",
  "action": "approve"
}
```

### 响应

与 `/api/chat` 相同的 SSE 流式格式。拒绝时立即返回 error + done：

```
data: {"type": "error", "message": "用户拒绝了工具执行"}

data: {"type": "done", "thread_id": "...", "session_id": "...", "message": "已取消执行"}
```

---

## 配风计划审查接口（PDF 上传）

**POST** `/api/vent/review/pdf`

> **认证**：不需要

### 功能说明

上传配风计划 PDF 文件，系统自动进行三方面审查：
1. **基本形式审查** — 版本、签字、编制时间、计算过程完整性、语病逻辑
2. **数据一致性审查** — 用风地点完整性、瓦斯/CO₂数据、工作面参数、风速温度匹配
3. **计算核验** — 逐地点调用计算工具核验需风量

三个子智能体并行审查，汇总后流式返回结果，同时生成可下载的 Word 审查报告。

### 请求参数（multipart/form-data）

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `file` | file | 是 | 配风计划 PDF 文件 |
| `session_id` | string | 否 | 会话 ID，新会话可不传 |
| `message` | string | 否 | 附加消息/审查指令 |
| `force_refresh` | bool | 否 | 是否强制重新 OCR 提取（忽略缓存），默认 false |

### 流式响应示例

```
data: {"type":"progress","message":"正在保存上传的 PDF 文件...","agent":"system"}

data: {"type":"progress","message":"PDF 文件已保存，HashID: a1b2c3d4...，正在提取文本内容...","agent":"system","hash_id":"a1b2c3d4..."}

data: {"type":"progress","message":"PaddleOCR 正在扫描第 1/12 页...","agent":"system","ocr_progress":{"page":1,"total":12}}

data: {"type":"progress","message":"PDF 文本提取完成，共 45230 字符。正在初始化审查智能体...","agent":"system"}

data: {"type":"progress","message":"3个审查智能体已就绪，正在并行执行审查...","agent":"system"}

data: {"type":"agent_start","agent":"form-reviewer","message":"「基本形式审查」开始审查..."}
data: {"type":"agent_start","agent":"data-checker","message":"「数据一致性审查」开始审查..."}
data: {"type":"agent_start","agent":"calc-verifier","message":"「计算核验审查」开始审查..."}

data: {"type":"agent_thinking","agent":"form-reviewer","message":"「基本形式审查」正在分析..."}
data: {"type":"agent_executing","agent":"calc-verifier","message":"「计算核验审查」正在采煤面综合需风量计算...","tools":["calc_face_air_volume_max"]}
data: {"type":"agent_tool_result","agent":"calc-verifier","message":"「计算核验审查」采煤面综合需风量计算 完成","tool":"calc_face_air_volume_max"}

data: {"type":"agent_todos","agent":"data-checker","message":"「数据一致性审查」已更新任务进度","todos":[{"content":"查询采掘计划","status":"completed"},{"content":"对比用风地点","status":"in_progress"}]}

data: {"type":"agent_done","agent":"form-reviewer","message":"「基本形式审查」审查完成","preview":"## 基本形式审查结果...","progress":"1/3"}
data: {"type":"agent_done","agent":"data-checker","message":"「数据一致性审查」审查完成","preview":"## 数据一致性审查结果...","progress":"2/3"}
data: {"type":"agent_done","agent":"calc-verifier","message":"「计算核验审查」审查完成","preview":"## 计算核验结果...","progress":"3/3"}

data: {"type":"progress","message":"3个子智能体均已审查完成，正在汇总审查结果...","agent":"system"}

data: {"type":"progress","message":"正在生成最终审查报告...","agent":"system"}

data: {"type":"token","content":"# 最终审查报告\n\n## 审查概况..."}

data: {"type":"progress","message":"正在生成 Word 审查报告...","agent":"system"}

data: {"type":"progress","message":"Word 报告已生成，点击下载","agent":"system","download_url":"http://localhost:8000/static/reports/vent_review_abc123_20260713.docx"}

data: {"type":"done","session_id":"xxx","download_url":"http://localhost:8000/static/reports/vent_review_abc123_20260713.docx"}
```

### subagent 字段说明

| 值 | 含义 |
|----|------|
| `form-reviewer` | 基本形式审查子智能体 |
| `data-checker` | 数据一致性审查子智能体 |
| `calc-verifier` | 计算核验审查子智能体 |

### 审查进度事件详解

#### progress 事件
```json
{
  "type": "progress",
  "message": "正在提取 PDF 文本...",
  "agent": "system",
  "hash_id": "a1b2c3d4...",
  "ocr_progress": {"page": 3, "total": 12},
  "download_url": "http://..."
}
```
| 字段 | 描述 |
|------|------|
| `message` | 进度描述 |
| `agent` | `"system"` 表示系统级进度 |
| `hash_id` | PDF 文件哈希，用于缓存标识 |
| `ocr_progress` | OCR 扫描进度（仅 OCR 阶段出现） |
| `download_url` | Word 报告下载链接（报告生成完成时出现） |

#### agent_start / agent_done / agent_error 事件
```json
{
  "type": "agent_done",
  "agent": "form-reviewer",
  "message": "「基本形式审查」审查完成",
  "preview": "## 基本形式审查结果\n### 1. 版本审查...",
  "progress": "1/3"
}
```
| 字段 | 描述 |
|------|------|
| `agent` | 子智能体标识 |
| `message` | 状态描述 |
| `preview` | 审查结果预览（前 300 字，仅 agent_done） |
| `progress` | 完成进度，格式 `已完成/总数` |
| `error` | 错误详情（仅 agent_error） |

#### agent_thinking / agent_executing / agent_tool_result 事件
```json
{
  "type": "agent_executing",
  "agent": "calc-verifier",
  "message": "「计算核验审查」正在采煤面综合需风量计算...",
  "tools": ["calc_face_air_volume_max"]
}
```
| 字段 | 描述 |
|------|------|
| `agent` | 子智能体标识 |
| `message` | 操作描述 |
| `tools` | 正在执行的工具名称列表（仅 agent_executing） |
| `tool` | 完成的工具名称（仅 agent_tool_result） |

#### agent_todos 事件
```json
{
  "type": "agent_todos",
  "agent": "data-checker",
  "message": "「数据一致性审查」已更新任务进度",
  "todos": [
    {"content": "查询采掘计划", "status": "completed"},
    {"content": "对比用风地点完整性", "status": "in_progress"},
    {"content": "校验瓦斯数据", "status": "pending"}
  ]
}
```

---

## 聊天历史查询接口

**GET** `/api/chat/history/{session_id}`

> **认证**：需要 `x-access-token` 请求头

### 请求参数（Query）

| 参数 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| `limit` | int | 100 | 返回条数上限 |
| `offset` | int | 0 | 偏移量 |

### 响应示例

```json
{
  "session_id": "abc123",
  "messages": [
    {
      "role": "user",
      "content": "15216 辅运起坡段当前风速风量情况如何？"
    },
    {
      "role": "assistant",
      "content": "根据监测数据，该巷道当前..."
    }
  ],
  "total": 10
}
```

### 响应字段

| 字段 | 描述 |
|------|------|
| `session_id` | 会话 ID |
| `messages` | 消息列表，每条包含 `role` 和 `content` |
| `total` | 消息总条数 |

---

## 会话列表接口

**GET** `/api/sessions`

> **认证**：需要 `x-access-token` 请求头

> **v2.0 变更**：会话按当前登录用户过滤，仅返回该用户的会话。

### 请求参数（Query）

| 参数 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| `limit` | int | 20 | 返回条数上限 |
| `offset` | int | 0 | 偏移量 |

### 响应示例

```json
{
  "sessions": [
    {
      "session_id": "xxx",
      "title": "15216 辅运起坡段...",
      "message_count": 5,
      "user_name": "zhangsan",
      "sort_order": 1,
      "created_at": "2024-01-15T10:30:00"
    }
  ],
  "total": 15
}
```

### 新增字段（v2.0）

| 字段 | 描述 |
|------|------|
| `user_name` | 会话所属用户名 |
| `sort_order` | 置顶状态：`1` = 已置顶，`0` = 未置顶 |

---

## 删除会话接口

**DELETE** `/api/sessions/{session_id}`

> **认证**：需要 `x-access-token` 请求头

### 路径参数

| 参数 | 类型 | 描述 |
|------|------|------|
| `session_id` | string | 要删除的会话 ID |

### 响应示例

```json
{
  "status": "ok",
  "message": "会话 xxx 已删除"
}
```

---

## 会话权限模式管理

> **v2.0 新增**

### 获取权限模式

**GET** `/api/sessions/{session_id}/mode`

> **认证**：需要 `x-access-token` 请求头

#### 响应示例

```json
{
  "session_id": "xxx",
  "mode": "full"
}
```

### 设置权限模式

**PUT** `/api/sessions/{session_id}/mode`

> **认证**：需要 `x-access-token` 请求头

#### 请求参数（JSON）

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `mode` | string | 是 | `"plan"`（计划审批模式）或 `"full"`（完全访问模式） |

#### 请求示例

```json
{
  "mode": "plan"
}
```

#### 响应示例

```json
{
  "session_id": "xxx",
  "mode": "plan",
  "message": "已切换为「plan」模式"
}
```

### 权限模式说明

| 模式 | 行为 |
|------|------|
| `plan` | Agent 先制定执行计划 → 调用 `request_plan_approval` 暂停 → 等待人工审批 → 审批后执行 |
| `full` | Agent 自动执行所有操作，无需人工审批 |

---

## 会话置顶

> **v2.0 新增**

**PUT** `/api/sessions/{session_id}/pin`

> **认证**：需要 `x-access-token` 请求头

切换会话置顶状态（置顶 ⇄ 取消置顶），每次调用反转当前状态。

#### 响应示例

```json
{
  "session_id": "xxx",
  "pinned": true,
  "message": "已置顶"
}
```

---

## 会话标题编辑

> **v2.0 新增**

**PUT** `/api/sessions/{session_id}/title`

> **认证**：需要 `x-access-token` 请求头

#### 请求参数（JSON）

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `title` | string | 是 | 新标题，最长 100 字 |

#### 请求示例

```json
{
  "title": "15216 工作面需风量计算"
}
```

#### 响应示例

```json
{
  "session_id": "xxx",
  "title": "15216 工作面需风量计算",
  "message": "标题已更新"
}
```

---

## 上下文用量查询

> **v2.0 新增**

**GET** `/api/sessions/{session_id}/context`

> **认证**：需要 `x-access-token` 请求头

查询会话最近一次请求的上下文 token 用量详情，用于监控 LLM 上下文窗口使用情况。

#### 响应示例

```json
{
  "session_id": "xxx",
  "total_limit": 131072,
  "current_usage": 12345,
  "usage_pct": 9.4,
  "breakdown": {
    "messages": 5000,
    "mcp": 4000,
    "skills": 800,
    "system_prompt": 600,
    "other": 2745
  },
  "updated_at": "2026-08-05 14:30:00"
}
```

#### 响应字段

| 字段 | 描述 |
|------|------|
| `total_limit` | 模型上下文窗口上限（tokens） |
| `current_usage` | 当前已用 tokens |
| `usage_pct` | 使用百分比 |
| `breakdown.messages` | 历史消息占用的 tokens |
| `breakdown.mcp` | MCP 工具描述占用的 tokens |
| `breakdown.skills` | 技能描述占用的 tokens |
| `breakdown.system_prompt` | 系统提示词占用的 tokens |
| `breakdown.other` | 其他（工具结果等）占用的 tokens |
| `updated_at` | 最近一次更新时间 |

> 若无记录，各个数值字段返回 `null`。

---

## 模型管理接口

> **v2.0 新增**

### 获取当前模型信息

**GET** `/api/model`

返回当前运行时模型的名称、思考级别和可用选项。

#### 响应示例

```json
{
  "current": "deepseek-v4-pro",
  "available": ["deepseek-v4-pro", "deepseek-v4-flash"],
  "thinking_level": "off",
  "thinking_levels": ["off", "high", "highest"]
}
```

### 切换运行时模型

**POST** `/api/model/switch`

切换对话 Agent 使用的 LLM 模型。切换后立即生效（下次请求使用新模型）。

#### 请求参数（JSON）

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `model` | string | 是 | 模型名称，可选值见 `GET /api/model` 的 `available` 字段 |

#### 请求示例

```json
{
  "model": "deepseek-v4-flash"
}
```

#### 响应示例

```json
{
  "current": "deepseek-v4-flash",
  "message": "已切换到 deepseek-v4-flash，下次请求生效"
}
```

> **注意**：仅影响对话解读和配风计划审查的智能体，点选解读（click_routes）不受影响。

### 切换思考级别

**POST** `/api/model/thinking`

切换模型思考深度。切换后立即生效。

#### 请求参数（JSON）

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `level` | string | 是 | `"off"`（关闭）、`"high"`（开启）、`"highest"`（最强） |

#### 请求示例

```json
{
  "level": "high"
}
```

#### 响应示例

```json
{
  "thinking_level": "high",
  "message": "思考级别已切换为「high」，下次请求生效"
}
```

---

## 技能管理接口

> **v2.0 新增**

### 获取技能列表

**GET** `/api/skills`

返回所有已安装技能的列表（含启用状态和所属智能体）。

#### 响应示例

```json
{
  "skills": [
    {
      "name": "click-interpret-tun",
      "display_name": "巷道点选解读",
      "path": "skills/click-interpret-tun",
      "description": "对巷道监测数据进行深度解读...",
      "enabled": true,
      "agents": ["点选解读 Agent"],
      "has_skill_md": true
    }
  ]
}
```

#### 响应字段

| 字段 | 描述 |
|------|------|
| `name` | 技能内部名称（目录名） |
| `display_name` | 技能显示名称（取自 SKILL.md frontmatter） |
| `path` | 技能相对路径 |
| `description` | 技能描述（取自 SKILL.md frontmatter，截取前120字） |
| `enabled` | 是否启用 |
| `agents` | 使用该技能的智能体列表 |
| `has_skill_md` | 是否包含 SKILL.md 文件 |

### 查看技能详情

**GET** `/api/skills/{name}`

返回指定技能的 SKILL.md 完整内容。

#### 路径参数

| 参数 | 类型 | 描述 |
|------|------|------|
| `name` | string | 技能名称（目录名） |

#### 响应示例

```json
{
  "name": "click-interpret-tun",
  "content": "---\nname: 巷道点选解读\ndescription: |\n  对巷道监测数据..."
}
```

### 启用/禁用技能

**POST** `/api/skills/{name}/toggle`

切换技能的启用状态。禁用后，对应智能体在下次请求时将跳过该技能。

#### 路径参数

| 参数 | 类型 | 描述 |
|------|------|------|
| `name` | string | 技能名称（目录名） |

#### 响应示例

```json
{
  "name": "click-interpret-tun",
  "enabled": false,
  "message": "技能「click-interpret-tun」已禁用"
}
```

### 上传新技能

**POST** `/api/skills/upload`

上传一个 `.zip` 格式的技能包。

#### 请求参数（multipart/form-data）

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `file` | file | 是 | `.zip` 格式的技能包，解压后必须包含 SKILL.md |

#### 约束

- 仅支持 `.zip` 格式
- 技能包内必须包含 `SKILL.md` 文件
- 技能名不能与已有技能重复
- 自动过滤路径穿越攻击

#### 响应示例（成功）

```json
{
  "name": "my-new-skill",
  "message": "技能「my-new-skill」上传成功"
}
```

---

## 工具清单

系统工具分为数据查询、知识库检索、需风量计算、MCP 远程查询、用户偏好、系统工具六类。

### 数据查询工具（对话解读 / 点选解读）

| 工具名称 | 描述 |
|----------|------|
| `query_tun_data_by_id` | 根据巷道 ID 查询巷道监测数据（风速、风量、瓦斯、温度等） |
| `query_device_data_by_id` | 根据设备 ID 查询设备实时数据和报警信息 |
| `query_devices_by_tunnel` | 根据巷道名称查询关联设备列表 |
| `query_devices_by_tunnel_id` | 根据巷道 ID 查询已绑定设备 |
| `get_tun_list_by_modelid` | 根据模型 ID 获取巷道列表 |
| `query_tunnels_by_model` | 查询模型巷道列表 |
| `query_tunnel_list` | 按名称搜索巷道 |
| `get_device_kind_dict` | 查询设备类型字典 |
| `get_device_list_by_kind` | 按类型查询设备列表 |
| `query_device_realtime_data` | 查询设备实时快照数据 |
| `list_ventanaly_monitor_data_days` | 查询监测历史时序数据 |
| `query_knowledge_base` | 检索煤矿安全知识库（《煤矿安全规程》条款） |
| `write_todos` | 任务清单管理工具 |

### 需风量计算工具（需风量计算 / 配风计划审查）

| 工具名称 | 描述 |
|----------|------|
| `calc_face_by_gas` | 按瓦斯涌出量计算采煤面需风量 |
| `calc_face_by_workers` | 按人数计算采煤面需风量 |
| `calc_face_by_wind_speed` | 按风速验算采煤面需风量 |
| `calc_face_air_volume_max` | 采煤面需风量综合计算（取各方法最大值） |
| `calc_tunnel_by_gas` | 按瓦斯涌出量计算掘进面需风量 |
| `calc_tunnel_by_explosives` | 按炸药量计算掘进面需风量 |
| `calc_tunnel_by_workers` | 按人数计算掘进面需风量 |
| `calc_tunnel_by_wind_speed` | 按风速验算掘进面需风量 |
| `calc_tunnel_by_vehicle` | 按胶轮车计算掘进面需风量 |
| `calc_tunnel_air_volume_max` | 掘进面需风量综合计算（取各方法最大值） |
| `calc_chamber_by_equipment` | 按设备发热量计算机电硐室需风量 |
| `calc_chamber_by_wind_speed` | 按风速验算硐室需风量 |
| `calc_other_by_wind_speed` | 按风速计算其他巷道需风量 |
| `calc_effective_area` | 计算工作面有效断面积 |
| `calc_total_air_volume` | 汇总矿井总需风量 |
| `get_needq_all_data` | 获取通防管控平台全部需风量数据（MCP） |

### 反算 / 系统工具

| 工具名称 | 描述 |
|----------|------|
| `calc_gas_emission_from_wind` | 测风报表瓦斯涌出量反算 |
| `get_current_time` | 获取当前系统时间 |

### MCP 配风计划审查工具（仅 PDF 审查）

| 工具名称 | MCP 服务端工具名 | 描述 |
|----------|-----------------|------|
| `query_mining_plan` | `query_monthly_mining_plan` | 查询煤矿月度采掘计划 |
| `query_face_procedure` | `query_working_face_procedure` | 查询工作面作业规程参数 |
| `query_gas_report` | `query_gas_identification_report` | 查询瓦斯等级鉴定报告 |
| `query_wind_report` | `query_ventilation_report` | 查询测风报表数据 |

### 用户偏好记忆工具

| 工具名称 | 描述 |
|----------|------|
| `save_user_preference` | 保存用户偏好/习惯（Agent 可据此个性化回复） |
| `list_user_preferences` | 查看当前用户已保存的所有偏好 |
| `delete_user_preference` | 删除指定用户偏好 |

### 计划审批工具（Human-in-the-Loop）

| 工具名称 | 描述 |
|----------|------|
| `request_plan_approval` | 提交执行计划等待人工审批（用于 plan 模式） |

### write_todos 工具响应

当调用 `write_todos` 时，会触发 `updated_todo_list` 事件：

```json
{
  "type": "updated_todo_list",
  "source": "main",
  "message": "任务进度已更新",
  "todos": [
    {"content": "查询巷道监测数据", "status": "pending"},
    {"content": "分析风速风量异常", "status": "in_progress"},
    {"content": "生成解读报告", "status": "pending"}
  ]
}
```

Todo 状态枚举：
- `pending`: 待执行
- `in_progress`: 执行中
- `completed`: 已完成

---

## 前端接入示例

### SSE 连接示例 (JavaScript)

> **v2.0 更新**：需要携带认证令牌，使用 FormData 发送请求。

```javascript
async function connectChat(message, sessionId = null, mode = 'full', token = '') {
  const formData = new FormData();
  formData.append('message', message);
  if (sessionId) formData.append('session_id', sessionId);
  formData.append('mode', mode);

  const response = await fetch('http://39.97.59.228:8070/api/chat', {
    method: 'POST',
    headers: {
      'x-access-token': token,
    },
    body: formData,
  });

  const reader = response.body.getReader();
  const decoder = new TextDecoder();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    const chunk = decoder.decode(value);
    const lines = chunk.split('\n\n');

    for (const line of lines) {
      if (line.startsWith('data: ')) {
        const data = JSON.parse(line.slice(6));
        handleSSEMessage(data);
      }
    }
  }
}

function handleSSEMessage(data) {
  switch (data.type) {
    case 'agent_start':
      console.log('Agent 启动:', data.cn_agent);
      break;
    case 'thinking':
      console.log('AI思考中...', data.node);
      break;
    case 'executing':
      console.log('执行工具:', data.tools);
      break;
    case 'token':
      appendContent(data.content);
      break;
    case 'reasoning':
      console.log('推理过程:', data.content);
      break;
    case 'interrupt':
      // 展示审批 UI，等待用户批准/拒绝
      showApprovalUI(data);
      break;
    case 'agent_done':
      console.log('Agent 完成:', data.cn_agent, data.duration_ms + 'ms');
      break;
    case 'done':
      console.log('完成', data.session_id);
      break;
  }
}

// 批准后恢复对话
async function resumeChat(sessionId, threadId, action = 'approve', token = '') {
  const response = await fetch('http://39.97.59.228:8070/api/chat/resume', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-access-token': token,
    },
    body: JSON.stringify({
      session_id: sessionId,
      thread_id: threadId,
      action: action,
    }),
  });

  // 同样使用 SSE 解析...
}
```

### 带文件上传示例

```javascript
async function uploadAndChat(message, file, token = '') {
  const formData = new FormData();
  formData.append('message', message);
  formData.append('file', file);

  const response = await fetch('http://39.97.59.228:8070/api/chat', {
    method: 'POST',
    headers: { 'x-access-token': token },
    body: formData,
  });

  // 解析 SSE 流...
}
```

---

## 错误处理

### 常见错误码

| HTTP 状态码 | 含义 |
|-------------|------|
| 400 | 请求参数错误 |
| 401 | 未登录或令牌无效（详见[认证机制](#认证机制)） |
| 404 | 会话不存在 |
| 409 | 资源冲突（如技能名重复） |
| 500 | 服务器内部错误 |
| 502 | 认证服务不可用 |
| 504 | 认证服务超时 |

### 错误响应格式

```json
{
  "type": "error",
  "message": "详细错误信息"
}
```

或（非流式接口）：

```json
{
  "error": "详细错误信息"
}
```

---

*文档生成时间: 2024年 | 最后更新: 2026-08-05 (v2.0)*
