# REST API 参考

## 文档维护规范

0. **先改文档，再动代码**
1. **文档分层，链接代码** — 格式：`module/file.py:function_name`
2. **简洁快照，日志分离** — 决策依据记录在 `knowhub/docs/decisions.md`

---

实现：`knowhub/server.py`

## Knowledge API

### `GET /api/knowledge/search` — 向量搜索知识

参数：`q`（必填）, `top_k`（默认5, 1-20）, `min_score`（默认3, 1-5）, `types`（逗号分隔, AND）, `owner`（逗号分隔, OR）

只返回 status=approved/checked 的知识。向量召回 3×top_k 候选，按余弦距离排序取 top_k。当前跳过 LLM 精排。

响应：`{"results": [...], "count": int, "reranked": false}`

### `POST /api/knowledge` — 创建知识

请求体：task（必填）, content（必填）, types, tags, scopes, owner, message_id, source, eval, capability_ids, tool_ids

自动生成 task_embedding + content_embedding。初始 status=pending，异步触发去重处理（详见 [processing-pipeline.md](processing-pipeline.md)）。

### `GET /api/knowledge` — 列表（分页+过滤）

参数：page, page_size（默认20）, types, scopes, owner, tags, status（默认 approved,checked）

### `GET /api/knowledge/{knowledge_id}` — 获取单条

### `PUT /api/knowledge/{knowledge_id}` — 更新（含知识进化）

请求体：add_helpful_case, add_harmful_case, update_score, evolve_feedback

`evolve_feedback` 非空时触发 LLM 重写知识内容并更新 task_embedding。

### `PATCH /api/knowledge/{knowledge_id}` — 直接编辑字段

请求体：task, content, types, tags, scopes, owner, capability_ids, tool_ids（均可选）

修改 task/content 时自动更新对应 embedding。

### `DELETE /api/knowledge/{knowledge_id}` — 删除

### `POST /api/knowledge/batch_delete` — 批量删除

请求体：`List[str]`（knowledge_ids）

### `POST /api/knowledge/{knowledge_id}/verify` — 验证

请求体：action（"approve"/"reject"）, verified_by

approve 在 approved ↔ checked 之间切换。reject 设为 rejected。

### `POST /api/knowledge/batch_verify` — 批量验证

请求体：knowledge_ids, action（必须 "approve"）, verified_by

### `POST /api/knowledge/batch_update` — 批量反馈

请求体：feedback_list `[{knowledge_id, is_effective, feedback?}]`

is_effective=true + feedback 时触发并发 LLM 知识进化。

### `POST /api/knowledge/slim` — 知识库瘦身

参数：model（默认 gemini-2.5-flash-lite）

LLM 识别可合并项 → 合并 → 重建 embedding。

### `POST /api/extract` — 从对话提取知识

请求体：messages（`[{role, content}]`）, agent_id, submitted_by（必填）, session_key

LLM 提取结构化知识 → 批量生成 embedding → 入库（pending） → 触发去重。

### `GET /api/knowledge/pending` — 处理队列

返回 status 为 pending/processing/dedup_passed/analyzing 的知识。

### `POST /api/knowledge/process` — 手动触发处理

参数：force（重置卡住的 processing/analyzing 状态）

### `GET /api/knowledge/status/{knowledge_id}` — 查看处理状态

### `GET /api/knowledge/meta/tags` — 获取所有标签

---

## Resource API

### `POST /api/resource` — 创建/更新资源

请求体：id（必填, 路径格式）, title, body, secure_body, content_type, metadata, sort_order, submitted_by

secure_body 在有组织密钥时自动加密（AES-256-GCM）。

### `GET /api/resource/{resource_id}` — 获取资源（含导航）

响应包含：toc（根节点）, children（子节点）, prev/next（同级前后节点）。

### `PATCH /api/resource/{resource_id}` — 更新字段

### `GET /api/resource` — 列表

参数：content_type, limit（默认100）

### `DELETE /api/resource/{resource_id}` — 删除

---

## Tool API

### `POST /api/tool` — 创建/更新工具

请求体：id（必填）, name, version, introduction, tutorial, input, output, status, capability_ids, knowledge_ids

自动生成 embedding（name + introduction）。

### `GET /api/tool` — 列表

参数：status, limit（默认100）, offset

### `GET /api/tool/search` — 向量搜索工具

参数：q（必填）, top_k（默认5）, status

### `GET /api/tool/{tool_id}` — 获取单个

### `PATCH /api/tool/{tool_id}` — 更新字段

### `DELETE /api/tool/{tool_id}` — 删除

---

## Capability API

### `POST /api/capability` — 创建/更新原子能力

请求体：id（必填）, name, criterion, description, requirement_ids, implements, tool_ids, knowledge_ids

自动生成 embedding（name + description）。

### `GET /api/capability` — 列表

参数：limit（默认100）, offset

### `GET /api/capability/search` — 向量搜索能力

参数：q（必填）, top_k（默认5）

### `GET /api/capability/{cap_id}` — 获取单个

### `PATCH /api/capability/{cap_id}` — 更新字段

### `DELETE /api/capability/{cap_id}` — 删除

---

## Requirement API

### `POST /api/requirement` — 创建/更新需求

请求体：id（必填）, description, capability_ids, source_nodes, status（默认 "未满足"）, match_result

自动生成 embedding（description）。

### `GET /api/requirement` — 列表

参数：status, limit（默认100）, offset

### `GET /api/requirement/search` — 向量搜索需求

参数：q（必填）, top_k（默认5）

### `GET /api/requirement/{req_id}` — 获取单个

### `PATCH /api/requirement/{req_id}` — 更新字段

### `DELETE /api/requirement/{req_id}` — 删除

---

### `POST /api/agent` — 统一远端 Agent 入口

同步阻塞。运行由 `agent_type` 指定的远端 Agent（如 `remote_librarian`、`remote_research`），返回标准的 Agent 结果。

**请求体**：
| 字段 | 类型 | 说明 |
|------|------|------|
| `agent_type` | str | 必填。必须是 `remote_` 前缀，如 `remote_librarian`、`remote_research` |
| `task` | str | 必填。单任务描述（远端模式不支持 `List[str]` 多任务） |
| `messages` | List | 可选。预置 OpenAI 格式消息，作为 Agent 初始上下文 |
| `continue_from` | str | 可选。已有 `sub_trace_id`，传入则续跑该 trace |
| `skills` | List[str] | 可选。调用方指定的 skill 列表；服务器按每个 agent_type 的 `ALLOWED_SKILLS` 过滤 |

**约束**：客户端传的 `tool_groups` / `model` / prompt 由服务器 preset 完全决定，客户端无法干预。`skills` 是例外——可被指定但受白名单约束。

**响应**：
```json
{
  "sub_trace_id": "...",
  "status": "completed",
  "summary": "...",
  "stats": {"total_messages": N, "total_tokens": N, "total_cost": 0.xxx}
}
```

`summary` 是 Agent 最终产出的 message 文本——Agent 之间通过 message 通信，不定义 per-agent 的结构化字段。如果 Agent 需要返回结构化数据（引用来源、ID 列表等），由其 prompt 约定写进 message 文本（例如 JSON 代码块），调用方自行 parse。

**续跑语义**：服务器不维护 `caller_trace_id → sub_trace_id` 映射。首次调用不传 `continue_from` 创建新 trace；caller 自行记住返回的 `sub_trace_id`，下次作为 `continue_from` 传回。

详见 [remote-agents.md](remote-agents.md)。

### `GET /api/knowledge/upload/pending` / `POST /api/knowledge/upload/retry` — 运维

查询与重跑历史 upload buffer 中的 pending / failed 记录。仅用于人工排查，不在主 agent 调用流中。

> 知识上传本身已并入 `POST /api/agent`，使用 `agent_type="remote_librarian_ingest"`；`task` 为 JSON 字符串（`{knowledge, tools, resources}`）。详见 [remote-agents.md](remote-agents.md)。
