91c9ee4b2d
广播逻辑重构: - AI 回复 (stream_start/response/stream_segments/multi_message/stream_end) 改用 broadcastToUser 发送给所有客户端 - 用户消息回显保持 broadcastToUserExcept 排除发送者 消息去重与角色修复: - CacheMessage(user) 移至回复生成后,避免本轮 LLM 调用出现重复用户消息 - action 角色消息在 DB 存储时映射为 assistant,DeepSeek 等模型不支持自定义角色 - stream_end defer 机制确保错误路径也会终止客户端思考指示器 OS 完整环境支持: - host 包重构为 HostBackend 接口 + Direct/WSL/Docker 三种后端 - 新增 os_exec/os_file/os_system 工具供 AI 在完整 Linux 环境中自由操作 其他: - 视觉模型注入 + 图片预处理后清空 Images 避免传给 Chat 模型 - 图片 URL 相对路径→绝对 URL 转换 - DevTools 链路追踪页面 + 重启修复 - 记忆搜索模糊匹配增强 - 后台思考定时调度支持 - 管理后台页面 (模型配置/用户管理等) - docs/api 更新广播机制说明 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
7.9 KiB
7.9 KiB
AI-Core Service API
Base URL: http://<host>:8081 | Auth: 无(/internal 路由除外)
AI-Core 是 LLM 编排引擎,负责对话处理、意图分析、子会话调度、结果合成。所有对话和记忆端点通过 Server-Sent Events (SSE) 或 JSON 返回。
目录
- POST /api/v1/chat — 对话
- GET /api/v1/memory/search — 记忆搜索
- GET /api/v1/memory — 记忆列表
- POST /api/v1/memory — 添加记忆
- DELETE /api/v1/memory — 删除记忆
- POST /api/v1/internal/presence — 在线状态
- GET /api/v1/system/info — OS 环境信息
- GET /api/v1/tools/calls — 工具调用日志
- GET /api/v1/llm-calls — LLM 调用日志
- GET /api/v1/health — 健康检查
- Model Selector 路由说明
1. POST /api/v1/chat
类型: SSE 流式 | Content-Type: application/json → text/event-stream
请求体 (JSON)
| JSON 字段 | Go 类型 | 必填 | 说明 |
|---|---|---|---|
user_id |
string | 是 | 用户 ID |
session_id |
string | 是 | 会话 ID |
message |
string | 是 | 用户消息文本(纯图片时可留空 "") |
images |
[]string | 否 | 图片 URL 数组(data URL 或 https URL) |
mode |
string | 否 | 默认 "text" |
nickname |
string | 否 | 用户昵称 |
图片预处理: 当
images非空时,AI-Core 使用视觉模型 (routing.vision) 自动分析图片:
- 纯图片 (
message="") → 生成场景描述作为用户消息- 文字+图片 → 视觉分析追加到消息末尾
- 原始图片仍传递给下游 LLM(如模型支持多模态)
SSE 事件
delta — 逐 token 发送
{ "delta": "token 文本", "message_id": "msg-1717000000000000000" }
segments — 断句事件(生成完成后)
{
"message_id": "string",
"mode": "string",
"segments": [
{ "index": 0, "text": "第一句话" },
{ "index": 1, "text": "第二句话" }
]
}
review — 审查后结构化消息(action/chat 分离)
{
"message_id": "string",
"review_messages": [
{ "type": "action", "content": "打开灯光", "delay_ms": 0 },
{ "type": "chat", "content": "好的,已为你打开客厅的灯光。", "delay_ms": 200 }
]
}
tool_progress — 工具执行进度
{
"type": "tool_progress",
"tool_name": "host_exec",
"status": "started|running|completed|failed",
"progress": 0.5,
"message": "正在执行 host_exec",
"message_id": "string"
}
done — 流结束
{ "message_id": "string", "mode": "string", "done": true }
error — 错误
{ "delta": "", "error": "错误描述" }
终端标记: data: [DONE]\n\n
HTTP 状态码
| 状态码 | 含义 |
|---|---|
| 200 | 流开始 |
| 400 | JSON 解析失败 |
| 405 | 非 POST 请求 |
| 500 | 服务端不支持流式 |
2. GET /api/v1/memory/search
Query 参数
| 参数 | 必填 | 说明 |
|---|---|---|
user_id |
是 | 用户 ID |
q |
是 | 搜索关键词 |
响应 200
{
"user_id": "string",
"query": "搜索词",
"memories": [ MemoryEntry, ... ],
"total": 5
}
错误 (200 + error 字段)
{
"user_id": "string",
"query": "string",
"memories": [],
"error": "错误描述",
"errorType": "memory_store_unavailable|retrieve_failed",
"hint": "解决方案 (仅 memory_store_unavailable)"
}
3. GET /api/v1/memory — 记忆列表
?user_id=xxx 最大返回 50 条。
{
"user_id": "string",
"memories": [ MemoryEntry, ... ],
"total": 3
}
4. POST /api/v1/memory — 添加记忆
// 请求
{
"user_id": "string (必填)",
"content": "string (必填)",
"category": "string (默认 other)",
"priority": 1
}
// 响应 201
{
"status": "saved",
"memory": MemoryEntry
}
错误
| 状态码 | errorType | 说明 |
|---|---|---|
| 400 | — | 缺少 user_id 或 content |
| 500 | save_failed |
保存失败 |
| 503 | memory_store_unavailable |
存储未初始化 |
5. DELETE /api/v1/memory — 删除记忆
?id=<memory_id>
// 响应 200
{ "status": "deleted", "memory_id": "string" }
错误
| 状态码 | errorType |
|---|---|
| 400 | 缺少 id 参数 |
| 500 | delete_failed |
| 503 | memory_store_unavailable |
6. POST /api/v1/internal/presence
Auth: X-Internal-Token header。Gateway 内部调用的用户上线/下线通知。
// 请求
{
"user_id": "string (必填)",
"status": "online|offline (必填)",
"session_id": "string (必填)"
}
// 响应 200
{ "status": "ok" }
| 状态码 | 含义 |
|---|---|
| 200 | 成功 |
| 400 | JSON 无效 |
| 401 | Token 无效 |
7. GET /api/v1/system/info
返回 OS 环境状态信息(WSL/Docker 后端状态、系统信息、磁盘使用)。
{
"os_enabled": true,
"backend": "wsl",
"system": { "hostname": "...", "os": "linux", "arch": "amd64", "cpu_cores": 12, "total_memory": "16.0 GB" },
"disk": { "path": "/", "total": "250.0 GB", "used": "120.0 GB", "free": "130.0 GB", "used_percent": 48.0 }
}
os_enabled=false 表示未配置 OS 后端。
8. GET /api/v1/tools/calls
工具调用日志(分页)。
| Query 参数 | 说明 |
|---|---|
tool_name |
按工具名过滤 |
limit |
每页条数 (默认 50, 最大 500) |
page |
页码 (从 1 开始) |
{
"calls": [ CallLogRecord ],
"total": 100,
"total_pages": 2,
"page": 1,
"limit": 50
}
GET /api/v1/tools/calls/stats — 工具调用统计
返回各工具的调用次数、成功率等统计信息。
9. GET /api/v1/llm-calls
LLM 调用日志(调试用)。
?limit=50 (默认 50, 最大 500)
{
"calls": [ LLMCallRecord ],
"total": 50
}
10. GET /api/v1/health
{
"status": "ok",
"service": "ai-core",
"model": "gpt-4o"
}
11. Model Selector 路由说明
AI-Core 使用基于用途的模型路由。模型配置从 models.json 加载,回退到 .env 环境变量。
Purpose 常量
| Purpose | 常量 | 用途 |
|---|---|---|
chat |
PurposeChat |
通用对话 |
deep_thinking |
PurposeDeepThinking |
后台深度思考 |
intent_analysis |
PurposeIntentAnalysis |
意图分析 |
tool_calling |
PurposeToolCalling |
工具调用 |
memory_extraction |
PurposeMemoryExtraction |
记忆提取 |
vision |
PurposeVision |
图片理解/视觉分析 (图片预处理、vision_analyze 工具) |
ocr |
PurposeOCR |
专用 OCR 文字提取 |
路由策略
models.json存在 → 按routing.<purpose>.fallback_chain顺序尝试models.json不存在 → 回退到.env的LLM_API_URL/LLM_API_KEY/LLM_MODEL- 全部失败 → 返回
DefaultAdapter()使用 fallback model
MemoryEntry 结构
| JSON 字段 | Go 类型 | 说明 |
|---|---|---|
id |
string | UUID |
user_id |
string | 所属用户 |
content |
string | 完整内容 |
summary |
string | 摘要 |
category |
string | user_preference, personal_info, conversation, knowledge, event, task, relationship |
priority |
int | 0=Temp, 1=Normal, 2=Important, 3=Core |
importance |
int | 1-10 |
keywords |
[]string | 关键词标签 |
session_id |
string | 来源会话 |
source |
string | conversation, thinking, manual |
access_count |
int | 访问次数 |
last_access |
time | 最近访问 |
created_at |
time | 创建时间 |
updated_at |
time | 更新时间 |
expires_at |
*time | 临时记忆过期(可空) |